本文由我们团队的刚毕业的帅小伙真帅
童鞋在学校写的一个小动画。发出来分享一下。
做了一个小动画,放上来请大家拍砖指教。
牛顿摆大家应该都不陌生的吧,其实用代码实现起来,挺简单的,下边我们就来实际的写一下这个动画。
0 动画拆分
这个动画看起来并不是很难,由6根线,5个圆组成,其实拆分来看的话,其中中间的三根线和最上边的一根线是不用动的,做动画的只是两边的两条线和两个圆,其中,左边的动画来说,就是先摆动起来,然后回落,当落下来的时候,右边的开始向上摆动,然后回落,当落下来的时候,左边的开始摆动,以此循环。
也就是说,我们只需要控制两个动画,然后让其交替进行即可。
单个动画拆分
对于左边动画来说,是由两个动画组成的:线的动画,圆的动画
- 线的动画:对于左边的额线来说,只是绕着上方的端点旋转了45°
- 圆的动画:对于左边的圆来说,也只是沿着一个以左边线为长度的弧,走了45°
两者结合起来就形成了,线和球是在一起摆动的视觉效果,但其实在实现的过程中,他们是分开的
1 动画的实现
在该例子中,所有的图形都是由CAShaplayer绘制的。
1.1 绘制线
首选,我们需要绘制6条线,来构成牛顿摆的基本图形,下边我们来看代码,
1 2 3 4 5 6 7 8 |
CAShapeLayer * layer = [CAShapeLayer layer]; //创建一个layer CGMutablePathRef path = CGPathCreateMutable(); //初始化一个路径 CGPathMoveToPoint(path, nil, startPoint.x, startPoint.y); //移动到开始的地方 CGPathAddLineToPoint(path, nil, endPoint.x, endPoint.y); //划线,画到结束的点 layer.path = path; // 指定layer的Path layer.lineCap = kCALineCapRound; //设置线端点的形状 layer.lineWidth = self.lineWithd; //设置线宽 layer.strokeColor = [UIColor redColor].CGColor; //设置线的颜色 |
这是绘制一条线我们所需要做的工作,其中,我们要指定这个线从哪开始,到哪结束,其中关于lineCap,这里有张图可以很好理解这是个什么玩意
其实我们可以封装一个方法循环来创建这些个线条,这样,我们的界面会看起来像这个样子
1.2 绘制圆
同上边绘制线一样,我们需要绘制5个圆,看代码
1 2 3 4 5 |
CAShapeLayer * cycleLayer = [CAShapeLayer layer]; //创建一个layer CGMutablePathRef path = CGPathCreateMutable(); //初始化一个路径 CGPathAddArc(path, nil, center.x, center.y, radius, 0, M_PI * 2, YES); // 画一个圆 cycleLayer.path = path; //指定layer的path cycleLayer.fillColor = [UIColor grayColor].CGColor; //填充layer的颜色 |
对于CGPathAddArc来说,参数分别是,路径,形变,圆心的X,圆心的Y,圆的半径,开始角度,结束角度,是否为顺时针
画完之后,我们的界面看起来像是这个样子
这样我们的牛顿摆就画完了,当然,你可以适当的加一些阴影开始这个形状看起来更有立体感。下边我们就可以来做动画了。
2 动画
就像上边我们所说的一样,我们拆开来做这些动画,首先我们先做左边的动画。
2.1.1 左边线的动画
左边的线的动画,就是让左边的线,围绕着上边的而端点,顺时针摆动45°,我们先来看代码。
1 2 3 4 5 6 7 8 9 |
_leftLineBaseAnimation = [CABasicAnimation animation]; //初始化一个动画 _leftLineBaseAnimation.keyPath = @"transform.rotation.z"; //动画运动的方式,现在指定的是围绕Z轴旋转 _leftLineBaseAnimation.duration = 0.4; //动画持续时间 _leftLineBaseAnimation.fromValue = [NSNumber numberWithFloat:0]; //开始的角度 _leftLineBaseAnimation.toValue = [NSNumber numberWithFloat:M_PI_4/2]; //结束的角度 _leftLineBaseAnimation.timingFunction =[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseOut]; //动画的运动方式, _leftLineBaseAnimation.autoreverses = YES; //是否反向移动动画 _leftLineBaseAnimation.delegate = self; //动画的代理 _leftLineBaseAnimation.fillMode = kCAFillModeForwards;//动画结束后的状态 |
- 首先我们先来看
keyPath
这个属性,这个是行是一个字符串,指定了你要让那个CALayer或CALayer的子类的某个可以做动画的属性的值,关于这个值,大家可以在这里 fromeValue
和toValue
都好理解,从一个值,到另一值,这里从0°到45°- 我们来看
timingFunction
这个属性,一图省千言
这里我们能够看出,也就是运动的速度曲线,先快后慢,先慢后快等等,我们也可以用贝塞尔曲线来定制我们自己的运动速度曲线,这样可以实现更加优美的动画。
autoreverses
这个就是是否反向动画,也就是,逆序在播放一遍动画,因为这里我们要的效果是先摆上去,然后在摆下来,正好是动画播放一遍然后在反向播放一遍,所以我们指定为YES。fillMode
这个属性是提供了一个动画结束后的状态,是应该移除,还是继续保持,反向等等。
2.1.2 左边圆的动画
我们来看左边圆的动画
1 2 3 4 5 6 7 8 9 10 11 |
CGMutablePathRef path = CGPathCreateMutable(); // 创建一个路径 CGPathAddArc(path, nil, 0, 10, self.height - 20, M_PI_2, M_PI_2+M_PI_4/2, NO); //这里的圆心我们制定左边第一条线的上边的端点,长为线的长度,角度为45° _leftCycleKeyframeAnimation = [CAKeyframeAnimation animation]; //创建一个动画 _leftCycleKeyframeAnimation.keyPath = ="crayon-sy">; //创建一个动画 _leftCycleKeyframeAnimation.keyPath = sinaimg.cn/mw690/005NFHyQgw1f6pm82st5rg306x08740d.gif" width="249" height="295">
效果图
0 动画拆分这个动画看起来并不是很难,由6根线,5个圆组成,其实拆分来看的话,其中中间的三根线和最上边的一根线是不用动的,做动画的只是两边的两条线和两个圆,其中,左边的动画来说,就是先摆动起来,然后回落,当落下来的时候,右边的开始向上摆动,然后回落,当落下来的时候,左边的开始摆动,以此循环。 也就是说,我们只需要控制两个动画,然后让其交替进行即可。 单个动画拆分对于左边动画来说,是由两个动画组成的:线的动画,圆的动画
两者结合起来就形成了,线和球是在一起摆动的视觉效果,但其实在实现的过程中,他们是分开的 1 动画的实现
1.1 绘制线首选,我们需要绘制6条线,来构成牛顿摆的基本图形,下边我们来看代码,
这是绘制一条线我们所需要做的工作,其中,我们要指定这个线从哪开始,到哪结束,其中关于lineCap,这里有张图可以很好理解这是个什么玩意 其实我们可以封装一个方法循环来创建这些个线条,这样,我们的界面会看起来像这个样子 1.2 绘制圆同上边绘制线一样,我们需要绘制5个圆,看代码
对于CGPathAddArc来说,参数分别是,路径,形变,圆心的X,圆心的Y,圆的半径,开始角度,结束角度,是否为顺时针 画完之后,我们的界面看起来像是这个样子 这样我们的牛顿摆就画完了,当然,你可以适当的加一些阴影开始这个形状看起来更有立体感。下边我们就可以来做动画了。 2 动画就像上边我们所说的一样,我们拆开来做这些动画,首先我们先做左边的动画。 2.1.1 左边线的动画左边的线的动画,就是让左边的线,围绕着上边的而端点,顺时针摆动45°,我们先来看代码。
这里我们能够看出,也就是运动的速度曲线,先快后慢,先慢后快等等,我们也可以用贝塞尔曲线来定制我们自己的运动速度曲线,这样可以实现更加优美的动画。
2.1.2 左边圆的动画我们来看左边圆的动画
|