包教包會-彈性動畫的原理與實現(xiàn)

bounce

彈性動畫一直以來都深深地吸引我,隨著知識儲備增多拂封,漸漸探索出一套彈性動畫的實現(xiàn)原理茬射。

簡介

本文將從零開始,一步步解析彈性動畫原理冒签,包教包會在抛。本文Demo簡單地封裝了一個動畫庫來測試,支持UIView的三種動畫類型:Size萧恕、Position刚梭、Scale,動畫運動曲線有:bounce票唆、easeInOut朴读。CALayer動畫暫不支持。

運動曲線

從初中開始走趋,我們就開始接觸正弦曲線衅金、余弦曲線,現(xiàn)在真的排上用場了(后悔當初數(shù)學沒學好)吆视。我們可以通過對正弦余弦做一些處理典挑,來得到動畫的運動曲線。彈性動畫稍微復雜一些啦吧,主要分為兩部分,一是 波動(波形) 拙寡、二是 衰減 授滓,將二者結合就能得到我們想要的動畫運動曲線。

1. 淡入淡出運動曲線

** 正弦曲線 **,Y坐標隨著X坐標的變化而變化般堆,新手乍一看在孝,這跟動畫根本沒有半毛錢關系,我們還需要進行精加工處理淮摔,才能使用私沮。

正弦曲線

不管是彈性動畫還是線性動畫,我們都有一個起點和終點和橙,彈性動畫不同的是它的值在某些時候會超越最終值仔燕,然后又回到最終值∧д校總之晰搀,我們需要一個絕對起點值為0,絕對終點值為1办斑,progress值范圍在01外恕。舉個栗子,我們要從``(100,100)``移動到``(200乡翅,200)``鳞疲,x和y初始值和最終值相差100,減去初始值蠕蚜,這0100就是progress的從0~1的過程尚洽。

不管是正弦還是余弦,經(jīng)過我們的翻轉(zhuǎn)位移之后都能得到一個從0到1的曲線:

正弦函數(shù) 0~1
余弦函數(shù) 0~1

這就是easeInOut動畫的運動曲線圖波势,在開始和結尾比較平緩翎朱,而中間波動較大,即淡入淡出的效果尺铣。

easeInOut

2. 彈性運動曲線

**a. 衰減曲線 **彈性動畫中從0~1的過程主要由指數(shù)衰減函數(shù)來控制拴曲,指數(shù)倍數(shù)越小,衰減速度越快凛忿,在動畫參數(shù)中相當于 彈性阻尼澈灼。

指數(shù)衰減函數(shù)
指數(shù)衰減曲線

b. 余弦曲線 在這里的我們使用余弦來作為彈性動畫波動曲線,x倍數(shù)值越大店溢,振動頻率 越快叁熔。

余弦振幅函數(shù)

余弦曲線

**c. 衰減的余弦曲線 **衰減函數(shù)和余弦函數(shù)相乘,得到初步的彈性運動曲線床牧。

衰減的余弦函數(shù)
衰減的余弦曲線(淺色線為衰減曲線)

**d. 0~1的衰減的余弦曲線 荣回,將曲線函數(shù)翻轉(zhuǎn)(加負號)后上移1(+1)即可得到最終彈性曲線,曲線從0開始戈咳,y值隨著x值變化波動后漸漸平穩(wěn)歸于1心软。x值遞增越快壕吹, 動畫速度 **越快,整個動畫所需時間越短删铃。

0~1的衰減的余弦函數(shù)
0~1的衰減的余弦曲線

通過運動曲線生成動畫

1. CADisplayLink

CADisplayLink是一個能讓我們以和屏幕刷新率相同的頻率將動畫顯示到屏幕上的定時器耳贬。通過定時器我們利用當前動畫progress得出運動曲線當前Y的值,即代碼中的timeLineY猎唁。

舉個例子咒劲,移動position的動畫,是用動畫的startPoint+(endPoint-startPoint)*timeLineY=動畫當前progress的的position诫隅,當按順序?qū)⑦@些position顯示出來就形成了我們需要的動畫腐魂。

// 新建一個displayLink
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisplayLink)];

- (void)updateDisplayLink {
    // 獲取彈性動畫曲線當前進度的曲線的Y坐標
    float timeLineY = [self getSpringAnimation:animation springOffset:animation.progress];
    // +進度
    animation.progress+=animation.speed;
    // 使用Y坐標值 算出View當前位置
    CGRect tempFrame = animationView.frame;
    NSValue *fromValue = animation.fromValue;
    CGPoint startPoint = fromValue.CGPointValue;
    NSValue *toValue = animation.toValue;
    CGPoint endPoint = toValue.CGPointValue;
      
    tempFrame.origin.x = startPoint.x+(endPoint.x - startPoint.x)*timeLineY;
    tempFrame.origin.y = startPoint.y+(endPoint.y - startPoint.y)*timeLineY;
    animationView.frame = tempFrame;
}

下面將會提到各種動畫是如何獲取當前timeLineY,提供了相應的曲線函數(shù)阎肝、代碼和動畫效果圖挤渔。

2. 非曲線動畫

非曲線意思就是0~1運動軌跡是直線遞增,整個動畫會顯得比較生硬风题。

函數(shù):y=x

動畫效果:


line_position.gif
line_scale.gif

3. 淡入淡出動畫

EaseInOut曲線在動畫在起點和終點的位置遞增比較慢判导,動畫開啟和結束的地方比較平滑。

曲線函數(shù):


余弦函數(shù) 0~1

轉(zhuǎn)換成OC代碼:

- (CGFloat)getEaseInOutAnimation:(FDSpringAnimation *)animation springOffset:(CGFloat)x {
    result = MIN(-cos(M_PI*animation.progress)/2.0+0.5, 1.000);
    return result;
}

動畫效果:

easeInOut_position.gif
easeInOut_scale.gif

4. 彈性動畫

彈性動畫增加了2個參數(shù)沛硅,分別是阻尼:damping和波動頻率:frequency眼刃。

曲線函數(shù):


0~1的衰減的余弦函數(shù)

轉(zhuǎn)換成OC代碼:

- (CGFloat)getSpringAnimation:(FDSpringAnimation *)animation springOffset:(CGFloat)x {
    result = -pow(2, -animation.damping * x) * cos(animation.frequency*x)+1;
}

動畫效果:


bounce_position.gif
bounce_scale.gif

拓展

上面的內(nèi)容基本可以實現(xiàn)一個簡單的彈性動畫,本文Demo在此基礎上增加了同時多個動畫運行摇肌、completionBlock等功能擂红,正在運行的動畫暫停移除正在運行的動畫围小、替換正在運行的動畫等功能待加入昵骤。

本文所有曲線通過Grapher繪畫。

Grapher

總結

以前一直都是直接用POP或者UIView動畫實現(xiàn)彈性動畫的效果肯适,對于原理實現(xiàn)不甚了解变秦,但是一直保持著好奇心,終于是自己實現(xiàn)了一套方案(路子比較野)框舔。

個人水平有限蹦玫,歡迎提出建議。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刘绣,一起剝皮案震驚了整個濱河市樱溉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纬凤,老刑警劉巖福贞,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異停士,居然都是意外死亡肚医,警方通過查閱死者的電腦和手機绢馍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門向瓷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肠套,“玉大人,你說我怎么就攤上這事猖任∧阒桑” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵朱躺,是天一觀的道長刁赖。 經(jīng)常有香客問我,道長长搀,這世上最難降的妖魔是什么宇弛? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮源请,結果婚禮上枪芒,老公的妹妹穿的比我還像新娘。我一直安慰自己谁尸,他們只是感情好舅踪,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著良蛮,像睡著了一般抽碌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上决瞳,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天货徙,我揣著相機與錄音,去河邊找鬼皮胡。 笑死痴颊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的胸囱。 我是一名探鬼主播祷舀,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烹笔!你這毒婦竟也來了裳扯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤谤职,失蹤者是張志新(化名)和其女友劉穎饰豺,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體允蜈,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡冤吨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年蒿柳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漩蟆。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡垒探,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怠李,到底是詐尸還是另有隱情圾叼,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布捺癞,位于F島的核電站夷蚊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏髓介。R本人自食惡果不足惜惕鼓,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望唐础。 院中可真熱鬧箱歧,春花似錦、人聲如沸彻犁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汞幢。三九已至驼鹅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間森篷,已是汗流浹背输钩。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留仲智,地道東北人买乃。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像钓辆,于是被迫代替她去往敵國和親剪验。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 【Android 動畫】 動畫分類補間動畫(Tween動畫)幀動畫(Frame 動畫)屬性動畫(Property ...
    Rtia閱讀 6,144評論 1 38
  • 動畫基礎概念 動畫分類 Android 中動畫分為兩種前联,一種是 Tween 動畫功戚、還有一種是 Frame 動畫。 ...
    Rtia閱讀 1,226評論 0 6
  • 一似嗤、傅立葉變換的由來 關于傅立葉變換啸臀,無論是書本還是在網(wǎng)上可以很容易找到關于傅立葉變換的描述,但是大都是些故弄玄虛...
    constant007閱讀 4,424評論 1 10
  • 一烁落、CoreAnimation(核心動畫) 1.什么是核心動畫 Core Animation可以用在 Mac OS...
    就叫yang閱讀 9,141評論 1 34
  • 動畫和繪圖是iOS開發(fā)中非常重要的部分乘粒。我們要實現(xiàn)一個動效豌注,首先就是動畫解析,分析動畫的路徑灯萍,然后再考慮具體的代碼...
    daixunry閱讀 12,214評論 14 120