动画特效二十:仿支付宝转账动画

本人录制技术视频地址: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];
}

至此,这个动画效果就算完成了。

猜你喜欢

转载自blog.csdn.net/sinat_27706697/article/details/50357232