動畫特效二十:仿支付寶轉賬動畫

本人錄製技術視頻地址:https://edu.csdn.net/lecturer/1899 歡迎觀看。

最近比較忙碌,有一段時間沒有更新自己的博客了。這一節爲大家介紹的動畫特效是: 仿支付寶轉賬動畫。 先看看最終效果圖。



處理這種多變的動畫,我們的分析思路就是各個擊破。在這裏,我將這個動畫分解爲三組進行處理:

1.  一小段弧線的運動,在效果圖中轉了3圈。

2. 繪製一個完整的圓,在效果圖中轉了1圈。

3. 白色的打鉤動畫。

關於第2點,我在之前的博客中已經進行了詳細的說明工作,我就不做解釋了,如果大家感興趣的話,請參照:CALayer的needsDisplayForKey方法使用說明 這篇博客。

現在我們來分析第一點:

我們知道,繪製圓弧的方法如下:

CGContextAddArc(CGContextRef __nullable c, CGFloat x, CGFloat y,
    CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)

第一個參數是繪製的上下文。

第二,三個參數是圓心。

第四個參數是圓的半徑。

第五、六個參數是繪製圓的起始角度和終止角度。

第六個參數是決定繪製方向(逆時針還是順時針)。

我們這裏所關注的是 startAngle和endAngle, 繪製的起始點是正上方,所以剛開始的時候,startAngle和endAngle均爲 -90°。

注意觀察可以看出,startAngle在前半圓的運動過程中比 endAngle塊,所以在這個過程中,弧線的長度越來越大。startAngle在後半圓的運動過程中比 endAngle慢,所以endAngle會慢慢趕上startAngle, 當繪製完整個圓的時候,兩者又在正上方那點重合了。分析圖如下:



有了這一層分析,就可以緊接着分析兩個小球的運動函數了。假設紅色小球在運動過程中是一直保持勻速狀態。那麼黃色小球在前半段的運動過程中速度相對而言慢一點,而在後半段的運動過程中速度相對而言快一點。體現在數學函數上面就是,前半段,黃色小球的直線斜率小於紅色小球,而後半段,黃色小球的直線斜率大於紅色小球。

函數分析示意圖:


有了上面的分析步奏,我們就可以書寫代碼,進行繪製了。

- (void)drawInContext:(CGContextRef)ctx {
    
    CGContextSetLineWidth(ctx, 5.0f);
    CGContextSetLineCap(ctx, kCGLineCapRound);
    CGContextSetStrokeColorWithColor(ctx, [UIColor blueColor].CGColor);
   
    if (self.roundTwo) {
        CGContextAddArc(ctx, CGRectGetWidth(self.bounds) * 0.5, CGRectGetHeight(self.bounds) * 0.5, CGRectGetWidth(self.bounds) * 0.5 - 5, -M_PI_2, 3 * M_PI / 2 * self.progress, 0);
    } else {
        // 注意這裏其實角度和終止角度的計算
        
        CGFloat startAngle, endAngle;
        if (self.progress <= 0.5) {
            startAngle = 5 * M_PI / 3 * self.progress - M_PI_2;
            endAngle = 2 * M_PI * self.progress - M_PI_2;
        } else {
            startAngle = 7 * M_PI / 3 * self.progress - 5 * M_PI / 6;
            endAngle = 2 * M_PI * self.progress - M_PI_2;
        }
        
        CGContextAddArc(ctx, CGRectGetWidth(self.bounds) * 0.5, CGRectGetHeight(self.bounds) * 0.5, CGRectGetWidth(self.bounds) * 0.5 - 5, startAngle, endAngle, 0);
    }
    
    CGContextStrokePath(ctx);
}

接下來,我們分析怎麼繪製打鉤動畫。

從圖中的效果圖,我們可以看出,打鉤動畫就是一段路徑。只要我們實現準備好相關的路徑信息,就可以方便的繪製出來了。分析圖如下:


繪製打鉤的代碼如下:

- (void)startCheck {
    
    CGFloat viewHeight = self.frame.size.height;
    CGFloat viewWidth = self.frame.size.width;
    UIBezierPath *strokePath = [UIBezierPath bezierPath];
    [strokePath moveToPoint:CGPointMake(viewWidth * 0.25, viewHeight * 0.65)];
    [strokePath addLineToPoint:CGPointMake(viewWidth * 0.4, viewHeight * 0.75)];
    [strokePath addLineToPoint:CGPointMake(viewWidth * 0.75, viewHeight * 0.25)];
    
    CAShapeLayer *checkLayer = [CAShapeLayer layer];
    checkLayer.frame = self.bounds; // 這樣就可以相對於父layer計算path了。
    checkLayer.strokeColor = [UIColor whiteColor].CGColor;
    checkLayer.fillColor = [UIColor clearColor].CGColor;
    checkLayer.lineWidth = 10;
    checkLayer.lineCap = kCALineCapRound;
    checkLayer.lineJoin = kCALineJoinRound;
    checkLayer.path = strokePath.CGPath;
    [self addSublayer:checkLayer];
    
    CABasicAnimation *checkAnim = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    checkAnim.fromValue = @(0.0);
    checkAnim.toValue = @(1.0);
    checkAnim.duration = 1.0f;
    checkAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    checkAnim.delegate = self;
    [checkAnim setValue:@"check_animation" forKey:@"check_name"];
    
    [checkLayer addAnimation:checkAnim forKey:nil];
}

至此,這個動畫效果就算完成了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章