你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS 復雜動畫的簡單原理(一)

iOS 復雜動畫的簡單原理(一)

編輯:IOS開發基礎

作者:鄭欽洪_ 

自己想好好學習動畫,在這個方向上發展,於是想總結一下自己學習這方面遇到的問題和收獲與大家分享,我會一直不斷的分享我學到的東西,會跟大家分享自己在學習動畫過程中搞懂的一些動畫原理,在下一篇會跟大家分享一下注水動畫的實現,希望得到大家的支持,也希望能夠一直把這個專題寫下去。

1. 圓弧動畫

經常我們會看到一個圓形加載動畫,圓弧大小總是在變化著的,例如芒果TV的加載動畫,眾乘巴士的加載動畫。這種動畫原理類似的還出現在一些一些儀表盤的動畫中,例如騰訊管家的測試WIFI速度功能,常常是一開始從0的位置或者是一個中間一個位置開始,做一段圓弧大小增縮的動畫。

QQ截圖20160205104345.png

通常這種動畫有以下幾個共同點:

  1. 一開始出現的時候圓弧都只是圓的一部分

  2. 圓弧不斷的向圓擴充,起始點和結束點也在不斷的變化接下來,我們就以以下這個加載動畫為例子,來說一下這類動畫的原理,分享一下我的拙見。GitHub傳送門

677383-b573d4bba3f5430d.gif

2. 拆分動畫

我們通過這張GIF高清無碼圖,看到一個圓弧從一開始慢慢從0變到0.5,在從0.5變到1的過程(這他媽不是廢話嗎?!),我們來看一下這兩個階段的動畫分別做了什麼事情:

  1. 0 -> 0.5 :起始點位置在0處,結束點從0慢慢變到0.5。

  2. 0.5 -> 1: 結束點從0.5處出發,用原來的速度走到1.0的位置,但是在這個階段開始的時候,起始點也動了,而且速度還比結束點運動的速度快,在結束點走到1.0的時候起始點已經追上了結束點的位置。

於是我們得出結論,一開始起始點不動,結束點動,當結束點走到一半的時候起始點發現不對勁了,也開始動,而且動的速度還比結束點快,在終點1.0處起始點追上了結束點 。

3. 實現

(1) CAShapeLayer

要實現這個動畫,首先我們得借助CAShapeLayer來做一個圓。在官方文檔的第一句話中,CAShapeLayer是這樣呗描述的:

/*  
*The shape layer draws a cubic Bezier spline in its coordinate space.
 * The spline is described using a CGPath object and may have both fill 
* and stroke components (in which case the stroke is composited over 
* the fill). The shape as a whole is composited between the layer's 
* contents and its first sublayer.
*/

CAShapeLayer 是在坐標系內繪制貝塞爾曲線的,通過繪制貝塞爾曲線,設置為shape的path,來繪制各種各樣的形狀,關於CAShapeLayer的介紹需要的可以自行簡書,上面有很詳細的介紹,我就不在這裡贅述。在這個Gif中,底部有一個灰色的圓,上面蓋著一個帶有動畫的紅色的圓,我們分別用CAShapeLayer來創建這兩個形狀。

 /// 底部的灰色layer 
CAShapeLayer *bottomShapeLayer = [CAShapeLayer layer]; 
bottomShapeLayer.strokeColor = [UIColor colorWithRed:229/255.0 green:229/255.0 blue:229/255.0 alpha:1].CGColor; 
bottomShapeLayer.fillColor = [UIColor clearColor].CGColor;        
bottomShapeLayer.lineWidth = KShapelayerLineWidth;   
bottomShapeLayer.path = [UIBezierPath 
bezierPathWithRoundedRect:CGRectMake(KShapeLayerMargin, 0, KShapeLayerWidth, KShapeLayerWidth) cornerRadius:KShapeLayerRadius].CGPath; [self.layer addSublayer:bottomShapeLayer]; 
/// 橘黃色的layer 
CAShapeLayer *ovalShapeLayer = [CAShapeLayer layer]; 
ovalShapeLayer.strokeColor = [UIColor colorWithRed:0.984 green:0.153 blue:0.039 alpha:1.000].CGColor; 
ovalShapeLayer.fillColor = [UIColor clearColor].CGColor; 
ovalShapeLayer.lineWidth = KShapelayerLineWidth; 
ovalShapeLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(KShapeLayerMargin, 0,KShapeLayerWidth, KShapeLayerWidth) cornerRadius:KShapeLayerRadius].CGPath;

677383-4c24bb91e6436511.png

得到了上面圖片的圖形,接下來我們要在上面的圖片中增加動畫,達到我們想要的效果。

(2) 加入動畫

從一開始的分析中,我們可以知道,一開始起點位置不變,當結束點運行到0.5的時候以結束點2倍的速度運動,在結束點走一半的路徑時間內走完了整個圓。而結束點始終如一的在做勻速運動。

  1. 起始點:要麼一開始不動,一動就是人家的2倍速度,追上人家。

  2. 結束點:始終以相同的速度勻速運動。

這裡實現這個動畫有好幾種方法,其中一種是讓結束點先運動1半,然後這時候起始點開始運動,速度是結束點的2倍,結束點也在0.5的位置繼續以原來的速度運動,這種也是從gif圖上最直觀看到的動畫效果。但是在這裡我選擇了投機取巧,我讓起始點一開始也運動,並且是以結束點的速度的兩倍,在結束點一開始運動的時候也跟著運動。那麼這裡就奇怪了,一開始起始點就運動的話,並且速度比結束點大,是不可能走出一段圓形一半的圓弧的。這裡,我們就需要讓起始點辛苦點了,在相同的時間內要跑結束點運動路徑的兩倍,結束點在圓形上跑一圈,結束點要在相同的時間裡跑兩圈,並且一開始第一圈還必須在看不到的地方跑,也就是在起跑線之前跑一圈,這可苦了起始點了,但誰讓您老人家跑得太快了呢。

我們這裡設置strokeStart的初始值和結束值為 -1.0 和 1.0 ,而 strokeEnd 的初值和最終值為0.0和1.0 ,由於動畫時間相等,在strokeEnd的值為0.5的時候,strokeStart剛好從 -1.0到0.0,也就是我們一開始看到的效果,之後由於strokeStart的運動速度是strokeEnd的兩倍,所以能在接下來的路程中追趕上。

/// 起點動畫
CABasicAnimation * strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
strokeStartAnimation.fromValue = @(-1);
strokeStartAnimation.toValue = @(1.0);

/// 終點動畫
CABasicAnimation * strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
strokeEndAnimation.fromValue = @(0.0);
strokeEndAnimation.toValue = @(1.0);

/// 組合動畫
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation];
animationGroup.duration = KAnimationDurationTime;
animationGroup.repeatCount = CGFLOAT_MAX;
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.removedOnCompletion = NO;
[ovalShapeLayer addAnimation:animationGroup forKey:nil];

01.gif

(3) 分割點效果

利用CAShapeLayer的lineDashPattern屬性,我們可以輕松的設置出分割點的效果,加上原來的動畫,就能做到我們想要的效果

ovalShapeLayer.lineDashPattern = @[@6,@3];

4. 後記

由於這一兩個月自己接了兩個外包項目,所以好久沒有寫簡書了,最近項目漸漸要結束了,作為學生黨最開心的就是看到下學期功課表只用上一天的課。接下來因為考完試時間比較充裕,會投入更多的時間在動畫的學習上,希望能將自己所學的、自己的一些拙見分享給大家,也希望得到大家的指點。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved