美文网首页
CAShaperLayer的BezierPath动画

CAShaperLayer的BezierPath动画

作者: boy丿log | 来源:发表于2020-09-08 18:16 被阅读0次

    在做业务需求的通常会有一些异形图片,我们通常会使用CAShaperLayer来绘制这些图形,因为他比较简单且易维护,但是有时候会遇到一些bezierPath的动画,这个时候往往就会出现各种奇怪的动画效果,比如美团外卖的tab,如果为了快速完成需求,可以直接用lottie实现,可是身为iOSer,总是希望可以用原生实现这样的功能。

    接下来我们就用代码实现这个功能,首先画个路径:

       CGFloat height = 100;
        NSInteger itemCount = 5;
        CGFloat itemWidth = [UIScreen width]/itemCount;
        CGFloat topSpace = 25;
        CGFloat s = 82.945 / 180.0 * M_PI;
        __block CAShapeLayer *layer1;
        UIBezierPath *bezierPath = [UIBezierPath bezierPath];
        [bezierPath moveToPoint:CGPointMake(0, topSpace)];
        [bezierPath addLineToPoint:CGPointMake(itemWidth * 2 - 3.5, topSpace)];
        [bezierPath addArcWithCenter:CGPointMake([UIScreen width]/2, topSpace + 3.5) radius:28.5  startAngle:(3 * M_PI_2 - s) endAngle: (M_PI_2 * 3 + s) clockwise:YES];
        [bezierPath addLineToPoint:CGPointMake([UIScreen width], topSpace)];
        [bezierPath addLineToPoint:CGPointMake([UIScreen width], height)];
        [bezierPath addLineToPoint:CGPointMake(0, height)];
        [bezierPath addLineToPoint:CGPointMake(0, topSpace)];
        CAShapeLayerCreate().makeChain.frame(CGRectMake((0) /2, ([UIScreen height] - 200) /2, [UIScreen width], 200))
        .shadowColor([UIColor blackColor].CGColor)
        .shadowRadius(4)
        .path(bezierPath.CGPath)
        .lineWidth(1)
        .fillColor([UIColor yellowColor].CGColor)
        .borderColor(UIColor.redColor.CGColor)
        .borderWidth(1)
        .strokeColor(UIColor.blackColor.CGColor)
        .backgroundColor([UIColor clearColor].CGColor)
        .addToSuperLayer(self.view.layer)
        .assignTo(^(__kindof CALayer * _Nonnull layer) {
            layer1 = layer;
        });
    
    image.png

    然后画个动画后的路径:

             UIBezierPath *bezierPath = [UIBezierPath bezierPath];
            [bezierPath moveToPoint:CGPointMake(0, topSpace)];
            [bezierPath addLineToPoint:CGPointMake(itemWidth * 2 - 3.5, topSpace)];
            [bezierPath addLineToPoint:bezierPath.currentPoint];
            [bezierPath addLineToPoint:CGPointMake([UIScreen width]/2, topSpace)];
            [bezierPath addLineToPoint:CGPointMake(itemWidth * 3 + 3.5, topSpace)];
            [bezierPath addLineToPoint:CGPointMake([UIScreen width], topSpace)];
            [bezierPath addLineToPoint:CGPointMake([UIScreen width], height)];
            [bezierPath addLineToPoint:CGPointMake(0, height)];
            [bezierPath addLineToPoint:CGPointMake(0, topSpace)];
    
    image.png

    接下来添加一个动画:

            CASpringAnimation *animated = [CASpringAnimation animationWithKeyPath:@"path"];
            animated.fromValue = (id)(layer1.path);
            animated.toValue = (id)(bezierPath.CGPath);
            animated.removedOnCompletion = NO;
            animated.fillMode = kCAFillModeForwards;
            animated.duration = 1;
            animated.mass = 1;
            [layer1 addAnimation:animated forKey:@"path"];
    

    接下来我们就可以看到这个动画的效果了:

    好吧,我承认跟lottie的还是有点差距,不过我想说的是当一个不规则path向规则path做动画的时候其实更多地是保持path段的一致性,不一致就会发生错乱动画,比如之前的突起形状有7段,而方形有9段,这是因为如果我们打断点看这个path,会发现:


    在实际的path中,addArcWithCenter:会向path添加两段,当他们的段数一样的话,用动画来过度就会表现的非常平滑。😃

    相关文章

      网友评论

          本文标题:CAShaperLayer的BezierPath动画

          本文链接:https://www.haomeiwen.com/subject/hqqjjktx.html