iOS特效之仿Mac窗口最小化的神奇效果
關鍵時刻,第一時間送達!
GIF/23K
本文示例代碼(http://www.gltech.win/ios%E5%BC%80%E5%8F%91/2017/08/30/iOS%E7%89%B9%E6%95%88%E4%B9%8B%E4%BB%BFMac%E7%AA%97%E5%8F%A3%E6%9C%80%E5%B0%8F%E5%8C%96%E7%9A%84%E7%A5%9E%E5%A5%87%E6%95%88%E6%9E%9C.html)
我希望我可以成為占點陣圖
前言
這次仿照Mac窗口最小化時的神奇效果(官方的中文版本是這麼叫的,聽起來很尷尬),做了一個iOS版本的。基礎代碼都沿用自iOS特效之破碎的ViewController(http://www.jianshu.com/p/1f4984c4e653)。先來看一下效果圖。
GIF/1205K
原理
首先要分析一下官方的動畫是如何進行的,下面是效果的截圖。動畫分為兩步,先是將圖片扭曲成下面的樣子,然後再吸入到左側。想要做圖片扭曲,用一個nxm的3D網格就可以了。n和m越大,扭曲後得到的邊緣越平滑。
在上圖的基礎上加入一個坐標軸,這樣便於觀察規律。
在動畫執行過程中,網格上的點會沿著一個方向縮放,我們稱縮放的軸為縮放軸,圖中的縮放軸是y軸。同時還需要在縮放軸上指定一個縮放中心點。在動畫的第二個階段,所有點會沿著一個方向移動,我們稱這個軸為移動軸,圖中的移動軸是x軸。
動畫第一階段
在動畫的第一個階段中,網格上的點只在縮放軸上移動。我們假設一個點在移動軸上的位置為movLoc,那麼我們可以使用公式0.5 * 0.98 * cos(3.14 * movLoc + 3.14) + 0.5 + 0.01;計算出第一階段結束時,該點需要向縮放中心點縮放的量。為什麼是這個公式呢,我給大家貼一張圖就清楚了。是不是和上面的邊緣曲線有點像。圖我是用Mac自帶的Grapher繪製的。在調試曲線的過程中Grapher的確非常好用。公式里的0.98和0.01是相關的兩個量,控制左邊窄口的大小。0.01 = (1 - 0.98) / 2。動畫第一階段主要的工作就是根據當前動畫的進度百分比,控制點到達最終縮放量的進度即可。
動畫第二階段
第二階段主要就是移動軸上的移動,我們可以根據最遠移動距離和當前的動畫進度計算出當前點在移動軸上的位置。然後根據當前的位置計算出縮放軸上需要的縮放量。最遠距離可以通過吸入點和另一側的邊界計算出來。
Shader
了解完原理我們來看Shader代碼吧。Swift代碼比較簡單,只是生成了一個撐滿屏幕的nxm網格,稍候再說。
傳入Shader的數據
VertexIn和VertexOut很普通,包含頂點位置和紋理坐標。Uniforms里包含了動畫相關的信息,當前動畫經過的時間animationElapsedTime,動畫總時間animationTotalTime,吸入點gatherPoint。
動畫實現
動畫的實現都在Vertex Shader里。步驟如下。
計算並規範動畫進度,得到動畫進度animationPercent。
求解移動軸scaleAxis和縮放軸moveAxis,以及最遠移動距離。我們可以通過移動軸scaleAxis和縮放軸moveAxis獲取點或者向量對應軸的分量。
定義第一階段動畫在總動畫中的佔比。
根據點在移動軸上規範化後的坐標計算縮放量的最終值。在第一階段時,根據最終縮放量和當前動畫進度計算當前的縮放量scaleAxisCurrentValue。第二階段時,直接使用最終縮放量,因為此時縮放量只和移動軸上坐標有關。
根據移動軸上動畫的進度moveAxisAnimationPercent和縮放軸的縮放量scaleAxisCurrentValue計算最終頂點的位置。
Vertex Shader到此就結束了,Fragment Shader很簡單,採樣,返回顏色。
Swift代碼
Swift代碼里基本重用破碎效果的代碼,在MagicalEffectView.swift中,最核心的代碼也就是構建網格這一段了。
根據網格單元格的大小,構建頂點位置和UV數組。還有就是對Uniforms進行了修改。包含動畫相關的信息。
其他自定義Transition動畫的代碼和之前一樣,基本沒動過。
總結
這種看似複雜的動畫,可以把它拆解成幾個簡單的階段,分開處理。對於每個階段里複雜的運動,可以把運動拆分到不同的軸上,然後為每個軸上的運動規律推導公式。和上學時解題的思路還是很像的。使用網格製作動畫相對於之前的點精靈,更加靈活,但是需要的頂點量也偏多。可以根據要做的效果斟酌使用。
作者:handyTOOL
鏈接:http://www.jianshu.com/p/31f6f10ce09a
來源:簡書
程序員大咖整理髮布,轉載請聯繫作者獲得授權


TAG:程序員大咖 |