基于CAKeyframeAnimation环绕闪烁效果(过山车效果)

先看看效果

环绕效果图

需求

这个需求是在为了吸引用户注意到某一个按钮, 或一个View里面的内容提出的. 例如: 滑动解锁按钮, 抽奖按钮等, 恩, 是的, 当你打开一个新的界面的时候, 里面的内容展示比较多的时候, 这样的效果确实能突出重点. 然后我接到需求的时候找了一下相关的知识, 发现没什么思路, 本来知乎上有个人提出的问题跟我的需求很像, 可是没有比较清晰的思路答案, 知乎的问题 iOS 一条线条绕贝塞尔曲线做动画?
直到我看到了这一篇iOS动画进阶 - CAKeyframeAnimation实现过山车动画然后找到了思路

实现

画出两个闪烁点得运动轨迹, 并给两个点设定运动轨迹

-(void)pathWithClockwise:(BOOL)clockwise {
    CGFloat width = self.frame.size.width;
    CGFloat height = self.frame.size.height;
    CGPoint startPointOne = CGPointMake(height * 0.5, 0);//第一个闪烁开始的点
    CGPoint startPointTwo = CGPointMake(width - height * 0.5, height);//第二个闪烁开始的点
    
    //第一个闪烁的运动轨迹
      UIBezierPath *pathOne = [UIBezierPath bezierPath];
    //第二个闪烁的运动轨迹
    UIBezierPath *pathTwo = [UIBezierPath bezierPath];
    if (clockwise) {//顺时针
      
        [pathOne moveToPoint:startPointOne];
        [pathOne addLineToPoint:CGPointMake(width - height * 0.5, 0)];
        [pathOne addArcWithCenter:CGPointMake(self.frame.size.width - height * 0.5, height * 0.5) radius:height * 0.5 startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:clockwise];
        [pathOne addLineToPoint:CGPointMake(height * 0.5, height)];
        [pathOne addArcWithCenter:CGPointMake(height * 0.5, height * 0.5) radius:height * 0.5 startAngle:M_PI_2 endAngle: -M_PI_2 clockwise:clockwise];
        
       
        [pathTwo moveToPoint:startPointTwo];
        [pathTwo addLineToPoint:CGPointMake(height * 0.5, height)];
        [pathTwo addArcWithCenter:CGPointMake(height * 0.5, height * 0.5) radius:height * 0.5 startAngle:M_PI_2 endAngle: -M_PI_2 clockwise:clockwise];
        [pathTwo addLineToPoint:CGPointMake(width - height * 0.5, 0)];
        [pathTwo addArcWithCenter:CGPointMake(self.frame.size.width - height * 0.5, height * 0.5) radius:height * 0.5 startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:clockwise];
    }else {//逆时针
        [pathOne moveToPoint:startPointOne];
        [pathOne addArcWithCenter:CGPointMake(height * 0.5, height * 0.5) radius:height * 0.5 startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:clockwise];
        [pathOne addLineToPoint:startPointTwo];
        [pathOne addArcWithCenter:CGPointMake(self.frame.size.width - height * 0.5, height * 0.5) radius:height * 0.5 startAngle:M_PI_2 endAngle: -M_PI_2 clockwise:clockwise];
        [pathOne addLineToPoint:startPointOne];
        
        
        [pathTwo moveToPoint:startPointTwo];
        [pathTwo addArcWithCenter:CGPointMake(self.frame.size.width - height * 0.5, height * 0.5) radius:height * 0.5 startAngle:M_PI_2 endAngle: -M_PI_2 clockwise:clockwise];
        [pathTwo addLineToPoint:startPointOne];
        [pathTwo addArcWithCenter:CGPointMake(height * 0.5, height * 0.5) radius:height * 0.5 startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:clockwise];
        [pathTwo addLineToPoint:startPointTwo];
    
    }
   
    
    
    //显示的轨迹
    CAShapeLayer *pathLayer = [CAShapeLayer layer];
    pathLayer.path = pathOne.CGPath;
    pathLayer.lineCap = kCALineCapRound;
    pathLayer.strokeColor = [UIColor orangeColor].CGColor;
    pathLayer.lineWidth = 2;
    pathLayer.fillColor = [UIColor clearColor].CGColor;
    [self.layer addSublayer:pathLayer];

    //开始两个闪烁动画
    [self startAnimationWith:pathOne startPostion:startPointOne];
    [self startAnimationWith:pathTwo startPostion:startPointTwo];

}

创建闪烁的点, 根据透明度拼成一条渐变的线段

-(void)startAnimationWith:(UIBezierPath *)path startPostion:(CGPoint)point {
    for (int i = 0; i < 20; i++) {
        //创建粒子
        CALayer *dotLayer = [CALayer layer];
        dotLayer.frame = CGRectMake(point.x, point.y, 4, 4);
        dotLayer.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:(1-0.05*i)].CGColor;
        [self.layer addSublayer:dotLayer];
        CAKeyframeAnimation *anim = [self animationWithPath:path withIndex:i];
        [dotLayer addAnimation:anim forKey:nil];
    }

}

然后给线段的每个点执行动画

-(CAKeyframeAnimation *)animationWithPath:(UIBezierPath *)path  withIndex:(int)index{
    //添加帧动画
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    anim.keyPath = @"position";
    anim.path = path.CGPath;
    anim.repeatCount = MAXFLOAT;
    anim.calculationMode = kCAAnimationPaced;
    //动画速度为匀速
    anim.calculationMode = kCAAnimationCubicPaced;
    //动画角度是否调整
    anim.rotationMode = kCAAnimationRotateAuto;
    anim.fillMode = kCAFillModeForwards;
    anim.removedOnCompletion = NO;
    anim.duration = 1.5;
    anim.beginTime = CACurrentMediaTime() + 0.01 * index;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    return anim;
}

另外一种思路

本来是想用CAShapeLayer作为运动的线段的, 而不是一个个点拼成的线段. CAShapeLayer上做 " strokeStart" 和 "strokeEnd"结合的. 但是细节看起来很丑, 可能是我处理的不够, 如果你有更好的思路欢迎告诉我.

最后附上 DEMO

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,156评论 4 61
  • ”你到底要告诉自己怎样的故事,才会让快乐与幸福就此消失了呢?我们根本就是自己最恶劣的敌人!我们对自己身体外表的不良...
    蓝莓姑娘阅读 538评论 0 0
  • 关于坚持二字,的确是考验人的耐性和毅力的。 但凡有点儿事情就能分心,然后就很难在短时间内收回去。 Not that...
    柒弟阅读 1,629评论 1 1