iOS開發(fā)之——從零開始完成頁面切換形變動畫

前言的前言

有很多人說用遮罩,移動下就能完成需求,這里我統(tǒng)一回復下:

  • 1.是可以,但是火山口那個形狀絕對很生硬,不自然
  • 2.我只是想用動手寫寫畫畫算算,挑戰(zhàn)下自己,所以不用再評論『用遮罩就能做balabala』了,我知道的

前言

<br />
某天我接到了UI發(fā)給我的兩張圖:

需求圖.png

看到圖的時候我一臉懵逼,顯然我需要做一個頁面切換的指示動畫。老實說,從大三暑假開始做iOS開發(fā)也一年有余了,但是遇到復雜動畫總是唯恐避之不及,只做過一些簡單的位移動畫。大腦中的舒適區(qū)總是讓我下意識避開麻煩的問題選擇簡單的解決方式。UI很善解人意得告訴我,你可以先用圖片替代動畫,以后有空慢慢完善。我突然不知哪里來的底氣拍了拍胸脯:“沒問題,包在我身上”。裝出去的b潑出去的水,沒辦法,我只好下定決心趁此機會好好鉆研一下形變動畫。(就在寫這篇文章的時候,UI看到了我最終的成果并點贊,頓時成就感爆棚)。

最終成果如圖:

<br />


demo.gif
具體代碼詳見:https://github.com/lfny2580832/NYTubeAnimation

<br />

需求分析

打定主意要搞定這個動畫,我首先在腦海中一遍遍模擬了整體效果。想象這是一個封閉光滑的管道,管道兩端是兩個可伸縮變形的白塊,當點擊下一步滑動到第二個頁面時,管道左邊的白塊被一股向右的力推動,逐步壓縮進管道中,最后從右邊釋放出來。這種感覺很抽象,只能隱隱約約想象出大概的效果。我在紙上一遍遍得模擬每一個細節(jié),開始進行簡化和分解。

簡化

如果只看設(shè)計圖,顯然中間管道過窄,白塊無法通過。于是我嘗試著將中間管道變寬,并用keynote利用圓弧與矩形畫出了簡化圖:

需求簡化圖.png

思路是不是立即清晰很多!實際上簡化的過程我花了很長時間。一開始我并沒有用圓形,而是用貝塞爾曲線來擬合圖形,但是在擬合過程后中遇到了重重困難。比如要根據(jù)角度來確定某段弧線中貝塞爾點的控制點的長度(一小段曲線中至少需要計算五個點的坐標,計算非常復雜,且擬合效果不是很好),以及多個貝塞爾曲線UIBeizerPath閉合時各種錯位等等問題。多次嘗試無果后,我退而求其次,使用了UIBeizerPath 自帶圓弧方法來構(gòu)造整體圖形以及動畫。這段時間我花了整整兩天。

簡化圖畫出來之后,心中有了思路,即用UIBeizerPath擬合圖形構(gòu)造CAShapeLayer,然后使用CADisplayLink完成幀動畫。對CAShapeLayer和CADisplayLink做動畫不太熟悉的同學可以參考我之前的一個水波動畫,github地址:https://github.com/lfny2580832/NYWaterWave

waterwave.gif

分解

<br />
看著上面的簡化圖,我又懵逼了。這丫該怎么動起來?而且要想讓效果看起來自然流暢,在形狀開始壓縮和在管道中移動速度肯定是不一樣的,由管道的狹窄程度決定,要計算的話難度太大,于是我便手動指定這兩塊區(qū)域的速度(所有參數(shù)都可以在代碼中指定)。經(jīng)過簡單的分解后我畫出了如下的參考圖,并標注了參數(shù):

整體分解圖.png

看著上圖腦海里有了些思路。我不可能只用一個CAShapelayer就做完這一系列的動畫,當然只能將其分解成各個部分,分別進行動畫。想象每個部分在整個動畫中的位置及大小,當每個部分都做好之后,再完美拼接起來,整個動畫不就完成了嗎?

實現(xiàn)

屬性與實例變量

下圖屬性與實例變量位置及命名只是個人習慣,方便開發(fā)時自己查看,其中所有點都是根據(jù)上面的參考圖來命名的,大家可以對照查看:

變量.png

看起來一臉懵逼?沒關(guān)系,我會將每個分解出來的模塊完整動畫向大家展示出來。由于代碼有點多有點復雜,就直接以圖片形式像大家展示。這其中大部分都只是很多簡單的動畫,但將他們組合起來就不一樣啦!

速度控制點—dynamic_Q_d和dynamic_Q2_d

</br>
這兩個點來控制在不同階段的速度,只需改變自增量即可,邏輯稍稍復雜。


dynamic_Q_d.png

dynamic_Q2_d.png

左邊的圓弧— leftSemiShape

</br>


leftSemiShape.gif

leftSemiShape.png

主體矩形區(qū)域—maintubeShape

</br>


mainTubeShape.gif

mainTubeShape.png

火山形狀—volcanoShape

</br>


volcanoShape.gif

火山形狀也是整個動畫中最復雜的一部分,需要一些簡單的計算,下面附上計算使用的參考圖:


火山形狀參考圖.png

我們可以根據(jù)Q點移動的距離(dynamic_Q2_d)計算出b夾角,再通過UIBeizerPath畫出相應的形狀:
volcanoShape.png

白塊右方圓形—rightCircleShape

</br>


rightCircleShape.gif

rightCircleShape.png

尾部圓形形狀—tailCircleShape

</br>


tailCircleShape.gif

tailCircleShape.png

管道形狀—tubeShape

</br>


tubeShape.gif

tubeShape.png

背景形狀—wholeShape

</br>


wholeShape.png

背景形狀只需要將上方所有圖形拼合起來并擴大一圈即可,在此就不附代碼了。

拼合

</br>


整體效果.gif

總結(jié)

當動畫效果做出來后,再將其封裝起來,開始事件、完成委托都變得那么簡單。寫這篇文章記錄我的思考過程是想讓更多人敢于挑戰(zhàn)自己,其實很多東西并沒有那么難,認真下去就能完成。如果總是待在自己的舒適區(qū),很難提高自己的水平。主動挑戰(zhàn)自己,將一個復雜的問題分解成一個個小目標,然后一一達成,問題就迎刃而解啦!

順便安利一波我和幾個同樣年輕的小伙伴一起創(chuàng)建的公眾號“萌新碼路”,記錄一些有趣的問題和解決方案以及萌新碼農(nóng)的日常,歡迎關(guān)注!
萌新碼路.png

喜歡就在github支持下咯:https://github.com/lfny2580832/NYTubeAnimation

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容