美文网首页
iOS开发 花瓣动画效果

iOS开发 花瓣动画效果

作者: 我是卖报的小行家 | 来源:发表于2022-05-11 15:42 被阅读0次

    先上图


    花瓣效果

    整个动画动效图


    flower.gif

    核心思想
    创建8个同心圆,然后将圆心偏移到一定位置
    上代码

    1.开始并开始动画

    //注:containerView为容器,承载着最开始的圆
    
     if (self.containerView.subviews.count !=8) {
            for ( SMBreathCircleView * container in self.containerView.subviews) {
                [container removeFromSuperview];
            }
            for (int i = 0; i<self.animationArray.count; i++) {
                SMBreathCircleView * container = [[SMBreathCircleView alloc]init];
                container.backgroundColor = UIColor.clearColor;
                [self.containerView addSubview:container];
                [container makeConstraints:^(MASConstraintMaker *make) {
                    make.center.equalTo(self);
                    make.width.height.equalTo(self.containerView);
                }];
                [self addAnimationWithLayer:container.layer andAnimationArray:self.animationArray[i]];
            }
            
        }else{
            int i=0;
            for (SMBreathCircleView * container in self.containerView.subviews) {
                [self addAnimationWithLayer:container.layer andAnimationArray:self.animationArray[i]];
                i++;
            }
            
        }
    

    2.设置CABasicAnimation的toValue

    我的做法是创建了一个数组,装着8个圆形视图最终的圆心
    - (NSArray *)animationArray
    {
        if (!_animationArray) {
            //不能直接cos(45)  180度为π 那45度为π/4 则为cos(π/4)
            CGFloat degree = [self getRadianFromDegree:360 / 8];
            CGFloat radius = self.viewFrameWidth / 2.0;
            _animationArray = @[
                [NSValue valueWithCGPoint:CGPointMake(radius, radius *2.0f-1)],//正下
                [NSValue valueWithCGPoint:CGPointMake(radius, 1)],//正上
                [NSValue valueWithCGPoint:CGPointMake(radius *2.0f-1,radius)],//正右
                [NSValue valueWithCGPoint:CGPointMake(1,radius)],//正左
                [NSValue valueWithCGPoint:CGPointMake(radius-1 + radius * cos(degree), radius+1 -radius * sin(degree))],//右上
                [NSValue valueWithCGPoint:CGPointMake(radius+1 - radius * cos(degree), radius-1 +radius * sin(degree))],//左下
                [NSValue valueWithCGPoint:CGPointMake(radius+1 - radius * cos(degree), radius+1-radius * sin(degree))], //左上
                [NSValue valueWithCGPoint:CGPointMake(radius-1 + radius * cos(degree),radius-1+ radius * sin(degree))],//右下
            ];
        }
        return _animationArray;
    }
    
    

    注:这里涉及到一个知识点,当我们计算三角函数时候必须要将度数转化为弧度比如 cos45 不能直接写cos(45),应该是cos(π/4)下面是度数转弧度公式

    -(float)getRadianFromDegree:(float)degree
    {
        return M_PI/(180/du);
    }
    

    3.给layer添加animation,并设置animation的tovalue

    -(void)addAnimationWithLayer:(CALayer *)layer andAnimationArray:(id)animationValue{
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
        animation.duration = 4;
        animation.removedOnCompletion = NO;
        animation.delegate = self;
        animation.fillMode = kCAFillModeForwards;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        animation.autoreverses = YES;
        animation.repeatCount = INFINITY;
    //经测试这里必须要设置fromvalue
        animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(self.viewFrameWidth/2.0,self.viewFrameWidth/2.0)];
        animation.toValue = animationValue;
        [layer addAnimation:animation forKey:nil];
    }
    

    4.移除动画方式

    - (void)removeAnimation
    {
        for (SMBreathCircleView * container in self.containerView.subviews) {
            //这里选择全部移除
            [container.layer removeAllAnimations];
        }
    }
    

    5.暂停动画

    - (void)pauseOnAnimation
    {
        for (SMBreathCircleView * container in self.containerView.subviews) {
            //注意这里一定不要写成CACurrentMediaTime() ToLayer
            CFTimeInterval pausedTime = [container.layer convertTime:CACurrentMediaTime() fromLayer:nil];
            container.layer.speed = 0.0;
            container.layer.timeOffset = pausedTime;
        }
    }
    

    6.继续动画

    -(void)continueAnimation{
        for (SMBreathCircleView * container in self.containerView.subviews) {
            CFTimeInterval pausedTime = [container.layer timeOffset];
            container.layer.speed = 1.0;
            container.layer.timeOffset = 0.0;
            container.layer.beginTime = 0.0;
            CFTimeInterval timeSincePause = [container.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
            container.layer.beginTime = timeSincePause;
        }
    }
    

    7.反转动画

    Tips:当我们想反转动画也就是说获取动画的reverse,其实方法也就是将动画的tovalue和fromvalue对换一下位置即可

    -(void)showReverseAnimationWithDuration:(NSInteger)duration{
        for (int i = 0; i<self.animationArray.count; i++) {
            SMBreathCircleView * container =self.containerView.subviews [i];
            CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
            animation.duration = duration;
            animation.fromValue = self.animationArray[i];
            animation.toValue = [NSValue valueWithCGPoint:CGPointMake(self.viewFrameWidth/2.0,self.viewFrameWidth/2.0)];
            animation.removedOnCompletion = NO;
            animation.delegate = self;
            animation.fillMode = kCAFillModeForwards;
            animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
            animation.autoreverses = YES;
            animation.repeatCount = INFINITY;
            [container.layer addAnimation:animation forKey:nil];
        }
        
    }
    

    至此完成这个动作
    有更好的方式的同学可以互相探讨

    相关文章

      网友评论

          本文标题:iOS开发 花瓣动画效果

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