牛顿摆动画
自己看动画有一段时间了,但是还是不是很能理解其中的一些属性方法之类的东西,琢磨了一下午写了一个牛顿摆的动画,这里记录一下,一遍以后查看先上图
先说下思路
说下牛顿摆的大致运动过程
根据牛顿摆的原理,中间是不动得,只有两边在动
两边运动是一个以这条线的上方位原点,长为半径,然后做半圆运动
运动模式是先快后慢
当左边的摆下来的时候,右边的开始向上摆动,右边的摆下来的时候,左边的开始向上摆动,一直循环下去
这样的话,我们用CAShapeLayer来进行画图,然后用CAAnimation来实现上述的运动过程
下边说流程
- 整体用CAShaepLayer + CAAnimation实现上述效果
- 图形全是画出来
- 划中间的四条线
- 划下边的四个圆
- 划左边的线
- 划左边的圆
- 划右边的线
- 划右边的圆
- 最后划上边的横线
- 加阴影
- 做动画
一步一来
1. 画线
1.1 全局变量
做成全局变量,方便后边使用
由于上边的大横线是不用动得,所以可以位局部变量
还有一个问题就是,如果直接用
[self.layer subLayers]
来取值的话,会取到多一些其他的layer,之前自己添加的layer是subLyaer的第一个,现在貌似是第三个,默认多了两个,这个具体原因不详,自己创建一个数组,来存放所有用到的layer,动画结束后,移除他们动画结束后,需要回调一个block来做一些事情,下边会说到
//自身的宽高
CGFloat _height;
CGFloat _width;
//左边的竖线,左边的圆,左边的旋转路径
CAShapeLayer * _leftLine;
CAShapeLayer * _leftCircle;
CGMutablePathRef _leftPath;
//右边的竖线,右边的圆,右边的旋转路径
CAShapeLayer * _rightLine;
CAShapeLayer * _rightCircle;
CGMutablePathRef _rightPath;
//左边的动画
CABasicAnimation * _leftBaseAnimation;
CABasicAnimation * _rightBaseAnimation;
//右边的动画
CAKeyframeAnimation * _leftKeyframeAnimation;
CAKeyframeAnimation * _rightKeyframeAnimation;
//动画结束调用的block
void(^animationFinishBlock)(CAAnimation * animation);
//存放所有图层的数组
NSMutableArray * _array;
1.2 初始化
初始化宽,高,数组
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//初始化
_height = self.frame.size.height;
_width = self.frame.size.width;
_array = [[NSMutableArray alloc]init];
}
return self;
}
1.3 创建中间的四个横线和圆
因为在初始化的时候设置的宽高都是100,所以,循环创建中间者四个视图,使他们的位置依次排列,然后放在中间
然后添加到self.layer上
同样也添加到数组中
至于怎么算,额..数学不太好,自己琢磨琢磨把
-(void)creatLayer
{
for (int i = 0; i < 6; i++) {
if (i >=1 && i<=4 )
{
CAShapeLayer * layer = [self creatFourLineX:i*10+25 andY:10];
CAShapeLayer * layer2 = [self creatRoundLayerX:i*10+25 andY:70];
[self.layer addSublayer:layer];
[self.layer addSublayer:layer2];
[_array addObject:layer];
[_array addObject:layer2];
}
}
}
1.4 创建四个线
-(CAShapeLayer *)creatFourLineX:(CGFloat)x andY:(CGFloat)y
{
CAShapeLayer * layer = [CAShapeLayer layer];
//首先,根据传递过来的参数,布局,然后设置宽位2 高为70
layer.frame = CGRectMake(x, y, 2, 70);
//创建路径
CGMutablePathRef path = CGPathCreateMutable();
//移动到 (0,0)的位置
CGPathMoveToPoint(path, nil, 0, 0);
//然后话一条60长度的线
CGPathAddLineToPoint(path, nil, 0, 60);
//设置layer的路径位划的路径
layer.path = path;
//填充颜色,这里的颜色要转化位CGColor
layer.strokeColor = [UIColor colorWithRed:0.188 green:0.188 blue:0.216 alpha:1].CGColor;
//设置线宽
layer.lineWidth = 2;
//设置lineCape(不知道怎么说了)就是那个线的端点的样式,这里是圆形,
layer