美文网首页
分析一波 浪的停不下来的 QQ电话波浪线 via@JosQiao

分析一波 浪的停不下来的 QQ电话波浪线 via@JosQiao

作者: 邋了个遢 | 来源:发表于2016-10-13 22:34 被阅读172次

    @下午下班的时候老杨突然发了一张截图

    4D84AB66AA27CBE88F0F3DDC73913B62.jpg

    这种波浪动画, 谁做过, 遇到动画就好忧伤.

    我就顺手帮他找了一下

    结果找到一位大神的demo

    效果如下

    qqPhone waveLine.gif

    在勒索老杨为群内成员续费其一个月爱奇艺会员后,把demo发给了他.自己也想看看是怎么实现的,写完前面那篇文章之后,就顺手把这个demo分析一波吧.

    qqPhone waveLine1.gif

    主要分析界面,现在看来其实没什么难得,但是没做过可得怎么想出来啊.

    好, 开始分析。(我要改下设置,搜狗的中文模式下使用英文标点。上一篇文章不好看,肯定是因为这个。)

    这个界面分成了三部分 ,上面的view 放了一个imageView 和一个label 下面的view放了俩按钮

    中间的波浪线是重点

    直接上这位大神的代码 (@ JosQiao ,多谢大神)

    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 设置第一次电话图标的位置
        self.lastDismissPoint = CGPointMake([UIScreen mainScreen].bounds.size.width - 50, [UIScreen mainScreen].bounds.size.height - 90);
        
        self.view.backgroundColor = [UIColor grayColor];
        // 添加头像 和 底部 按钮
        [self.view addSubview:self.viewTop];
        [self.view addSubview:self.viewBottom];
        
        // 根据屏幕尺寸比例伸缩
        CGFloat topHeight = 280.0 / SCALE;
        CGFloat bottomHeight = 160.0 / SCALE;
        
        self.viewTop.frame = CGRectMake(0, 0, self.view.bounds.size.width, topHeight);
        self.viewBottom.frame = CGRectMake(0, self.view.bounds.size.height - bottomHeight, self.view.bounds.size.width, bottomHeight);
        
        //self.view.layer.contents = (__bridge id)[UIImage imageNamed:@"11.png"].CGImage;
        
        // layer
        self.layer = [CAShapeLayer layer];
        // 填充颜色
        self.layer.fillColor = [UIColor clearColor].CGColor;
        // 描边颜色
        self.layer.strokeColor = [UIColor colorWithRed:190/255.0 green:218/255.0 blue:226/255.0 alpha:0.3].CGColor;
        // 边缘线的类型
        self.layer.lineCap = kCALineCapRound;
        
        // layer1
        self.layer1 = [CAShapeLayer layer];
        self.layer1.fillColor = [UIColor clearColor].CGColor;
        self.layer1.strokeColor = [UIColor colorWithRed:190/255.0 green:218/255.0 blue:226/255.0 alpha:0.6].CGColor;
        self.layer1.lineCap = kCALineCapRound;
        
        // layer2
        self.layer2 = [CAShapeLayer layer];
        self.layer2.fillColor = [UIColor clearColor].CGColor;
        self.layer2.strokeColor = [UIColor colorWithRed:190/255.0 green:218/255.0 blue:226/255.0 alpha:0.9].CGColor;
        self.layer2.lineCap = kCALineCapRound;
        
        
        CGFloat width = WIDTH;
        
        CGFloat width1 = 40;
        CGFloat width2 = 70;
        
        CGFloat centerY = 360.0 / SCALE;
        // 初试线段的起点
        UIBezierPath *shapePath = [[UIBezierPath alloc] init];
        [shapePath moveToPoint:CGPointMake(-width, centerY)];// -40 ,
        
        UIBezierPath *shapePath1 = [[UIBezierPath alloc] init];
        [shapePath1 moveToPoint:CGPointMake(-width - width1, centerY)];
        
        UIBezierPath *shapePath2 = [[UIBezierPath alloc] init];
        [shapePath2 moveToPoint:CGPointMake(-width - width2, centerY)];
        
        
        CGFloat  x = 0;
        for (int i =0 ; i < 6; i++) {
            //画二元曲线,一般和moveToPoint配合使用
            [shapePath addQuadCurveToPoint:CGPointMake(x - WIDTH / 2.0, centerY) controlPoint:CGPointMake(x - WIDTH + WIDTH/4.0, centerY - 8)];
            
            [shapePath addQuadCurveToPoint:CGPointMake(x, centerY) controlPoint:CGPointMake(x - WIDTH/4.0, centerY + 8)];
            
            [shapePath1 addQuadCurveToPoint:CGPointMake(x - width1 - WIDTH / 2.0, centerY) controlPoint:CGPointMake(x - width1 - WIDTH + WIDTH/4.0, centerY - 14)];
            [shapePath1 addQuadCurveToPoint:CGPointMake(x - width1, centerY) controlPoint:CGPointMake(x - width1 - WIDTH/4.0, centerY + 14)];
            
            
            [shapePath2 addQuadCurveToPoint:CGPointMake(x - width2 - WIDTH / 2.0, centerY) controlPoint:CGPointMake(x - width2 - WIDTH + WIDTH/4.0, centerY - 20)];
            [shapePath2 addQuadCurveToPoint:CGPointMake(x - width2, centerY) controlPoint:CGPointMake(x - width2 - WIDTH/4.0, centerY + 20)];
            x += width;
        }
        // 路径
        self.layer.path = shapePath.CGPath;
        self.layer1.path = shapePath1.CGPath;
        self.layer2.path = shapePath2.CGPath;
        
        // 添加
        [self.view.layer addSublayer:self.layer];
        [self.view.layer addSublayer:self.layer1];
        [self.view.layer addSublayer:self.layer2];
        
    }
    
    

    里面的注释是我添加的,如有不对请指正,由于对动画不熟,百度了一波,mark下来
    for循环内的代码起到了最重要的作用,它用一个一个点和控制点(和锚点略像?)把这些波浪画了出来。后面有对i改变的效果。

    http://blog.csdn.net/yongyinmg/article/details/38755955

    http://blog.sina.com.cn/s/blog_484d782b010139vv.html

    上面代码的作用就是画了三个图层, 他们的效果是这样的。 画出了三个静态的图层。

    4D470B19-3C79-4987-AF93-BD4B7823B447.png

    经过上面代码的一连串运算(数学渣开始是算不出来的,一脸懵逼,看不懂的,多看几遍代码,会有收获) ,三个layer已经画出来了, 如何让他们动起来呢。 简单在~ 看这里。

    // 开始layer动画
    - (void)starLayerAnimation
    {
        CABasicAnimation *animation1 = [CABasicAnimation animation];
        // 周期
        animation1.duration = 1.0;
        // 重复次数 
        animation1.repeatCount = INFINITY;
        // 告诉系统要执行什么样的动画
        animation1.keyPath = @"transform";
        // 设置通过动画,将layer从哪儿移动到哪儿 目测 xyz
        animation1.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(WIDTH, 0, 0)];
        
    //    [self.layer addAnimation:animation1 forKey:nil];
    //    [self.layer1 addAnimation:animation1 forKey:nil];
    //    [self.layer2 addAnimation:animation1 forKey:nil];
    }
    // http://www.cnblogs.com/wendingding/p/3801157.html
    

    重复次数 == 英菲尼迪。 哈哈。

    如何结束

    // 结束layer动画
    
    - (void)stopLayerAnimation
    {
        [self.layer removeAllAnimations];
        [self.layer1 removeAllAnimations];
        [self.layer2 removeAllAnimations];
    }
    
    

    上面就是对这个动画的解析了,都在注释里, 一句一句的看就会有收获,不懂得就选中右键search lookup
    虽然对动画底层理解不深,但是在这个理解基础上进行修改一些东西还是可以的。
    想想确实是看起来很高深的东西,自己有耐心去慢慢探索,也会有几分收获。

    附上一些参数,免得报错, 自己画几条划拨乱跳的线试试吧。

    // [self starLayerAnimation];

    .h声明

    
    /** 上部分试图 */
    @property(nonatomic,strong)UIView *viewTop;
    
    /** 头像试图,一般封装在viewTop */
    @property(nonatomic,strong)UIImageView *imgIconView;
    
    /** 下部分试图 */
    @property(nonatomic,strong)UIView *viewBottom;
    
    /** 跳转类型 */
    @property (nonatomic ,assign) QQPhonePressentType pressentType;
    
    /** 电话试图展开前的位置 */
    @property (nonatomic ,assign) CGPoint lastDismissPoint;
    
    
    /** 开始波浪动画 */
    - (void)starLayerAnimation;
    
    /** 停止波浪动画 */
    - (void)stopLayerAnimation;
    
    

    .m声明与宏

    
    #define WIDTH 240
    
    #define SCALE (568.0/[UIScreen mainScreen].bounds.size.height)
    
    #import "---"
    
    @interface ---
    
    /** 波浪图层 */
    @property(nonatomic,strong) CAShapeLayer * layer;
    /** 波浪图层 */
    @property(nonatomic,strong) CAShapeLayer * layer1;
    /** 波浪图层 */
    @property(nonatomic,strong) CAShapeLayer * layer2;
    
    
    
    @end
    

    OK啦 达哥秒仿版。

    qqPhone waveLine2dg.gif

    // 写完回头又来看了一遍,发现解释的好不清楚啊。再来补充一波。
    for循环内的代码起到了最重要的作用,根据控制点来走的。
    如果把条件i改成1 效果会是

    qqPhone waveLine2dg12.gif

    这样

    2呢

    qqPhone waveLine2dg123.gif

    它就这样一直往前推着画。
    好了好了 ,撤退。

    hiahiahiahiahiahiahiahi 最后 感谢这位大神。
    下班肥家。

    刚才看代码的时候困得不行不行的了,昨晚玩OW万圣节模式到深夜凌晨,不行了。今晚回去不玩。。。 算了。。 就玩一j。。。 一个小。。。不行不行, 一。。。 一。。。一会儿吧,这个时间比较合我意!

    hiahiahiahiahiahia~ ,我爱学习,学习使我快乐,放我去学习~~~~

    相关文章

      网友评论

          本文标题:分析一波 浪的停不下来的 QQ电话波浪线 via@JosQiao

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