手把手教你使用Core animation 做动画(下)

手把手教你使用Core animation 做动画(下)

来源:Airfei

链接:http://www.jianshu.com/p/1e2b8ff3519e

2.上下横线的动画效果。

此动画效果,需要使用transform.rotation.z转动角度。

上横线转动的角度顺序为 0 -> 10° -> (-55°) -> (-45°)

这是一组数据,使用关键帧处理动画。

CAKeyframeAnimation *rotationAnimation1 = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];

   rotationAnimation1.values = @[[NSNumber numberWithFloat:0],

                                [NSNumber numberWithFloat:Radians(10) ],

                                [NSNumber numberWithFloat:Radians(-10) - M_PI_4 ],

                                [NSNumber numberWithFloat:- M_PI_4 ]

                                ];

下横线转动的角度顺序为0 -> (-10°) -> (55°) -> (45°)

CAKeyframeAnimation *rotationAnimation2 = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];

   rotationAnimation2.values = @[[NSNumber numberWithFloat:0],

                                [NSNumber numberWithFloat:Radians(-10) ],

                                [NSNumber numberWithFloat:Radians(10)  + M_PI_4 ],

                                [NSNumber numberWithFloat: M_PI_4 ]

                                ];

你认为这么就结束了? 最终结束的动画如下:

发现相交的直线没有居中,而是靠左显示。

向左平移,使用transform.translation.x

//平移量

   CGFloat toValue = lineWidth *(1- cos(M_PI_4)) /2.0;

即旋转角度又发生偏移量,使用组合动画。

上横线组合动画

//平移x

   CABasicAnimation *translationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];

   translationAnimation.fromValue = [NSNumber numberWithFloat:0];

   translationAnimation.toValue = [NSNumber numberWithFloat:-toValue];

//角度关键帧 上横线的关键帧 0 - 10° - (-55°) - (-45°)

CAKeyframeAnimation *rotationAnimation1 = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];

rotationAnimation1.values = @[[NSNumber numberWithFloat:0],

[NSNumber numberWithFloat:Radians(10) ],

[NSNumber numberWithFloat:Radians(-10) - M_PI_4 ],

[NSNumber numberWithFloat:- M_PI_4 ]

];

CAAnimationGroup *transformGroup1 = [CAAnimationGroup animation];

transformGroup1.animations = [NSArray arrayWithObjects:rotationAnimation1,translationAnimation, nil];

transformGroup1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

transformGroup1.duration = kStep3Duration;

transformGroup1.removedOnCompletion = YES;

[_topLineLayer addAnimation:transformGroup1 forKey:nil];

下横线组合动画

//角度关键帧 下横线的关键帧 0 - (-10°) - (55°) - (45°)

   CAKeyframeAnimation *rotationAnimation2 = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];

   rotationAnimation2.values = @[[NSNumber numberWithFloat:0],

                                [NSNumber numberWithFloat:Radians(-10) ],

                                [NSNumber numberWithFloat:Radians(10) + M_PI_4 ],

                                [NSNumber numberWithFloat: M_PI_4 ]

                                ];

CAAnimationGroup *transformGroup2 = [CAAnimationGroup animation];

transformGroup2.animations = [NSArray arrayWithObjects:rotationAnimation2,translationAnimation, nil];

transformGroup2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

transformGroup2.duration = kStep3Duration ;

transformGroup2.delegate = self;

transformGroup2.removedOnCompletion = YES;

[_bottomLineLayer addAnimation:transformGroup2 forKey:nil];

Part1到此结束。最终效果图

Part2的思路和Part1思路是一样的。你可以参考代码自己思考一下。核心代码

-(void)cancelAnimation

{

   //最关键是path路径

UIBezierPath *path = [UIBezierPath bezierPath];

//30度,经过反复测试,效果最好

CGFloat angle = Radians(30);

CGFloat startPointX = self.center.x + Raduis * cos(angle);

CGFloat startPointY = kCenterY - Raduis * sin(angle);

CGFloat controlPointX = self.center.x + Raduis *acos(angle);

CGFloat controlPointY = kCenterY;

CGFloat endPointX = self.center.x + lineWidth /2;

CGFloat endPointY = kCenterY;

//组合path 路径 起点 -150° 顺时针的圆

path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.center.x,kCenterY)

radius:Raduis

startAngle:-M_PI + angle

endAngle:M_PI + angle

clockwise:YES];

//起点为 180°-> (360°-30°)

UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.center.x,kCenterY)

radius:Raduis

startAngle:M_PI + angle

endAngle:2 * M_PI - angle

clockwise:YES];

[path appendPath:path1];

//三点曲线

UIBezierPath *path2 = [UIBezierPath bezierPath];

[path2 moveToPoint:CGPointMake(startPointX, startPointY)];

[path2 addCurveToPoint:CGPointMake(endPointX,endPointY)

controlPoint1:CGPointMake(startPointX, startPointY)

controlPoint2:CGPointMake(controlPointX, controlPointY)];

[path appendPath:path2];

//比原始状态向左偏移5个像素

UIBezierPath *path3 = [UIBezierPath bezierPath];

[path3 moveToPoint:CGPointMake(endPointX,endPointY)];

[path3 addLineToPoint:CGPointMake(self.center.x - lineWidth/2 -5,endPointY)];

[path appendPath:path3];

_changedLayer.path = path.CGPath;

//平移量

CGFloat toValue = lineWidth *(1- cos(M_PI_4)) /2.0;

//finished 最终状态

CGAffineTransform transform1 = CGAffineTransformMakeRotation(0);

CGAffineTransform transform2 = CGAffineTransformMakeTranslation(0, 0);

CGAffineTransform transform3 = CGAffineTransformMakeRotation(0);

CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);

_topLineLayer.affineTransform = transform;

transform = CGAffineTransformConcat(transform3, transform2);

_bottomLineLayer.affineTransform = transform;

//一个圆的长度比

CGFloat endPercent = 2* M_PI *Raduis / ([self calculateTotalLength] + lineWidth);

//横线占总path的百分比

CGFloat percent = lineWidth / ([self calculateTotalLength] + lineWidth);

_changedLayer.strokeStart = 1.0 -percent;

CAKeyframeAnimation *startAnimation = [CAKeyframeAnimation animationWithKeyPath:@"strokeStart"];

startAnimation.values = @[@0.0,@0.3,@(1.0 -percent)];

//在π+ angle

CAKeyframeAnimation *EndAnimation = [CAKeyframeAnimation animationWithKeyPath:@"strokeEnd"];

EndAnimation.values = @[@(endPercent),@(endPercent),@1.0];

CAAnimationGroup *animationGroup = [CAAnimationGroup animation];

animationGroup.animations = [NSArray arrayWithObjects:startAnimation,EndAnimation, nil];

animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

animationGroup.duration = kStep4Duration;

animationGroup.delegate = self;

animationGroup.removedOnCompletion = YES;

[animationGroup setValue:@"animationStep4" forKey:@"animationName"];

[_changedLayer addAnimation:animationGroup forKey:nil];

//平移x

CABasicAnimation *translationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];

translationAnimation.fromValue = [NSNumber numberWithFloat:-toValue];

translationAnimation.toValue = [NSNumber numberWithFloat:0];

//角度关键帧 上横线的关键帧  (-45°) -> (-55°)-> 10° -> 0

CAKeyframeAnimation *rotationAnimation1 = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];

rotationAnimation1.values = @[[NSNumber numberWithFloat:- M_PI_4 ],

[NSNumber numberWithFloat:- Radians(10) - M_PI_4 ],

[NSNumber numberWithFloat:Radians(10) ],

[NSNumber numberWithFloat:0]

];

CAAnimationGroup *transformGroup1 = [CAAnimationGroup animation];

transformGroup1.animations = [NSArray arrayWithObjects:rotationAnimation1,translationAnimation, nil];

transformGroup1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

transformGroup1.duration = kStep4Duration;

transformGroup1.removedOnCompletion = YES;

[_topLineLayer addAnimation:transformGroup1 forKey:nil];

//角度关键帧 下横线的关键帧  (45°)-> (55°)- >(-10°)-> 0

CAKeyframeAnimation *rotationAnimation2 = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];

rotationAnimation2.values = @[[NSNumber numberWithFloat: M_PI_4 ],

[NSNumber numberWithFloat:Radians(10) + M_PI_4 ],

[NSNumber numberWithFloat:-Radians(10) ],

[NSNumber numberWithFloat:0]

];

CAAnimationGroup *transformGroup2 = [CAAnimationGroup animation];

transformGroup2.animations = [NSArray arrayWithObjects:rotationAnimation2,translationAnimation, nil];

transformGroup2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

transformGroup2.duration = kStep4Duration;

transformGroup2.delegate = self;

transformGroup2.removedOnCompletion = YES;

[_bottomLineLayer addAnimation:transformGroup2 forKey:nil];

}

最终效果图:

本篇文章讲解结束!

阅读 6765 投诉

写留言

 

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

推荐阅读更多精彩内容