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

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

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~ ,我爱学习,学习使我快乐,放我去学习~~~~

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

推荐阅读更多精彩内容