iOS 抖音点赞动画 收藏动画

JWGiveLikeAnimation

描述:iOS 抖音点赞动画 收藏动画
git传送门

点赞动画

前言

最近项目中需要模仿抖音的点赞动画来应用到项目中,所以自己撸了一个动画,给同行们分享下,不喜勿喷。欢迎随时批评指正 QQ:38251725

实现思路

  • 点赞动画

    将点赞动画分解为4个部分

    1. 6个倒三角形从中心向外扩散,先缩放在放大
    2. 6个三角全部展开之后由内向外消失
    3. 心形点赞图片 从小扩大在收缩动画
    4. 波纹慢慢扩大至心型图片圆周,再慢慢消失

    实现原理:

    动画1、2:使用CAShapeLayer图层,UIBezierPath曲线绘制三角形。然后使用CAAnimationGroup来实现缩放和消失组合动画。

    - (void)createTrigonsAnimtion {
        //三角形大小
        for (int i = 0; i < 6; i++) {
            //绘制三角形的图层
            CAShapeLayer * shapeLayer = [[CAShapeLayer alloc]init];
            shapeLayer.position = _giveLikeView.center;
            shapeLayer.fillColor = self.shapeFillColor.CGColor;
            //三角形
            UIBezierPath * startPath = [UIBezierPath bezierPath];
            [startPath moveToPoint:CGPointMake(-2, _length)];
            [startPath addLineToPoint:CGPointMake(2, _length)];
            [startPath addLineToPoint:CGPointMake(0, 0)];
            shapeLayer.path = startPath.CGPath;
            //旋转图层,形成圆形
            //因为一共是6个,均等应该是反转60度 所以是M_PI/3 ,围绕Z轴旋转
            shapeLayer.transform = CATransform3DMakeRotation(M_PI / 3 * i, 0, 0, 1);
            [self.layer addSublayer:shapeLayer];
            
            //使用动画组来解决三角形 出现跟消失】
            CAAnimationGroup * groupAnimation = [CAAnimationGroup animation];
            groupAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
            groupAnimation.duration = self.animationDurtion;
            groupAnimation.fillMode = kCAFillModeForwards;
            groupAnimation.removedOnCompletion = NO;
            
            CABasicAnimation * scaleAnimtion = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
            //缩放时间占20%
            scaleAnimtion.duration = self.animationDurtion * 0.2;
            scaleAnimtion.fromValue = @(0);
            scaleAnimtion.toValue = @(1);
            
            //绘制三角形结束  一条直线
            UIBezierPath * endPath = [UIBezierPath bezierPath];
            [endPath moveToPoint:CGPointMake(-2, _length)];
            [endPath addLineToPoint:CGPointMake(2, _length)];
            [endPath addLineToPoint:CGPointMake(0, _length)];
            
            CABasicAnimation * pathAnimtion = [CABasicAnimation animationWithKeyPath:@"path"];
            pathAnimtion.beginTime = self.animationDurtion * 0.2;
            pathAnimtion.duration = self.animationDurtion * 0.8;
            pathAnimtion.fromValue = (__bridge id)startPath.CGPath;
            pathAnimtion.toValue = (__bridge id)endPath.CGPath;
            
            groupAnimation.animations = @[scaleAnimtion,pathAnimtion];
            [shapeLayer addAnimation:groupAnimation forKey:nil];
        }
    }
    

    动画3: 心形图片放大缩小,使用UIView的帧动画,来设置每帧的动画。分2部分,一部分是放大一部分是恢复

    [UIView animateKeyframesWithDuration:self.animationDurtion delay:0.0 options:UIViewKeyframeAnimationOptionLayoutSubviews animations:^{
                 /*参数1:关键帧开始时间
                  参数2:关键帧占用时间比例
                  参数3:到达该关键帧时的属性值 */
                [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 * self.animationDurtion animations:^{
                    self.giveLikeView.transform =  CGAffineTransformMakeScale(1.5, 1.5);;
                }];
                [UIView addKeyframeWithRelativeStartTime:0.5 * self.animationDurtion relativeDuration:0.5 * self.animationDurtion animations:^{
                    self.giveLikeView.transform = CGAffineTransformIdentity;
                }];
            } completion:^(BOOL finished) {
                self.userInteractionEnabled = YES;
            }];
    

    动画4:波纹动画使用CAShapeLayer绘制一个圆圈,CAAnimationGroup组合使用 缩小、宽度变宽,再消失。

    - (void)createCircleAnimation {
        //创建背景圆环
        CAShapeLayer *circleLayer = [[CAShapeLayer alloc]init];
        circleLayer.frame = self.bounds;
        //清空填充色
        circleLayer.fillColor = [UIColor clearColor].CGColor;
        //设置画笔颜色 即圆环背景色
        circleLayer.strokeColor =  self.shapeFillColor.CGColor;
        circleLayer.lineWidth = 1;
        //设置画笔路径
        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2.0, self.frame.size.height/2.0) radius:_length startAngle:- M_PI_2 endAngle:-M_PI_2 + M_PI * 2 clockwise:YES];
        //path 决定layer将被渲染成何种形状
        circleLayer.path = path.CGPath;
        [self.layer addSublayer:circleLayer];
        
        //使用动画组来解决圆圈从小到大 -->消失
        CAAnimationGroup * groupAnimation = [CAAnimationGroup animation];
        groupAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        NSTimeInterval groupDurtion = self.animationDurtion * 0.8;
        groupAnimation.duration = groupDurtion;
        groupAnimation.fillMode = kCAFillModeForwards;
        groupAnimation.removedOnCompletion = NO;
    
        CABasicAnimation * scaleAnimtion = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        //放大时间占80%
        scaleAnimtion.duration = groupDurtion * 0.8;
        scaleAnimtion.fromValue = @(0);
        scaleAnimtion.toValue = @(1);
    
    
        CABasicAnimation * widthStartAnimtion = [CABasicAnimation animationWithKeyPath:@"lineWidth"];
        widthStartAnimtion.beginTime = 0;
        widthStartAnimtion.duration = groupDurtion * 0.8;
        widthStartAnimtion.fromValue = @(1);
        widthStartAnimtion.toValue = @(3);
    
        CABasicAnimation * widthEndAnimtion = [CABasicAnimation animationWithKeyPath:@"lineWidth"];
        widthEndAnimtion.beginTime =  groupDurtion * 0.8;
        widthEndAnimtion.duration = groupDurtion * 0.2;
        widthEndAnimtion.fromValue = @(3);
        widthEndAnimtion.toValue = @(0);
    
        groupAnimation.animations = @[scaleAnimtion,widthStartAnimtion,widthEndAnimtion];
        [circleLayer addAnimation:groupAnimation forKey:@"circleLayerAnimtion"];
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(groupDurtion * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [circleLayer removeAnimationForKey:@"circleLayerAnimtion"];
            [circleLayer removeFromSuperlayer];
        });
        
    }
    
  • 取消点赞动画

    取消点赞动画分解,点赞图片由外向内慢慢消失。

    [self bringSubviewToFront:_giveLikeView];
            _giveLikeView.transform = CGAffineTransformMakeScale(1.1, 1.1);
            [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
                self.giveLikeView.transform = CGAffineTransformMakeScale(0.1, 0.1);
            } completion:^(BOOL finished) {
                self.giveLikeView.hidden = YES;
                self.giveLikeView.transform = CGAffineTransformMakeScale(1, 1);
                self.userInteractionEnabled = YES;
            }];
    

总结

以上就是整个动画的分解原理。主要是使用的Shaperlayer图层 贝塞尔绘制图形,使用动画组还合成动画的实现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342