手把手教你使用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 投诉
写留言