今天在精选 20 个优质的加载动画中发现了一个蛮有意思的加载动画:
正好最近原来的加载动画用的腻了😄
所以决定用OC实现一下这个动画来用看看。
那么我们开始
首先,分析一下这个动画:
1.元素分析
从gif上看,主体由一个盒子(三角形的洞)和一些飘落的元素组成(下方的字表示😢)。
2.动画分析
我们看到飘落的字从红框的位置随机出现,然后落向黄线的随机位置消失,同时透明度也从0开始变成1。
动画过程中,伴随着不同的角速度进行旋转,下落的速度也各不相同。
因此我们需要准备以下几个方法来实现动画效果:
1.产生随机的起点坐标
2.产生随机的终点坐标
3.产生随机的速度、角速度
4.实现位移、旋转、透明度改变的动画
从上面的分析来看,要实现这个效果并不是很困难😳。
So,Les's do it.
3.需要用到的知识储备
Core Animation
然后...嗯...貌似就够了...
4.代码实现
1.随机产生起点和终点坐标
//获取起点坐标
- (CGPoint)randomBeginPoint{
return [self getRandomFrameInRect:CGRectMake(0, 0, self.frame.size.width, 10)];
}
//获取终点坐标
- (CGPoint)randomEndPoint{
return [self getRandomFrameInRect:CGRectMake(0, self.frame.size.height - 20, self.frame.size.width, 10)];
}
//方形区域内产生随机点
- (CGPoint)getRandomFrameInRect:(CGRect)rect{
CGFloat minX = rect.origin.x;
CGFloat width = rect.size.width;
CGFloat minY = rect.origin.y;
CGFloat height = rect.size.height;
//产生随机数
CGFloat randomX = minX + (float)(arc4random() % (int)width);
CGFloat randomY = minY + (float)(arc4random() % (int)height);
return CGPointMake(randomX, randomY);
}
2.产生随机的角速度与下落速度
下落速度:通过下落到终点所需时间(即动画时间)设定
角速度:下落到终点时旋转的角度 和 动画时间 共同决定旋转的角速度
//获取随机的动画时间
- (CGFloat)getRandomDuration{
//产生随机数(这里我们定义的动画时间为0.5s~1.0s)
int time = arc4random()%50 + 50;
CGFloat duration = time/100;
return duration;
}
//获取随机的角度
- (CGFloat)getRandomRotation{
//产生随机数(这里我们定义的旋转角度范围为 -180度~180度)
int angle = arc4random()%360 - 180;
CGFloat rotation = angle*180/M_PI;
return rotation;
}
3.产生动画的方法
- (void)addAnimationToLayer:(CALayer*)layer{
//获取随机参数
CGFloat duration = [self getRandomDuration];
CGFloat rotation = [self getRandomRotation];
CGPoint beginPoint = [self getRandomBeginPoint];
CGPoint endPoint = [self getRandomEndPoint];
//平移
CABasicAnimation *positionAnim = [CABasicAnimation animationWithKeyPath:@"position"];
positionAnim.duration = duration;
positionAnim.fromValue = [NSValue valueWithCGPoint:beginPoint];
positionAnim.toValue = [NSValue valueWithCGPoint:endPoint];
positionAnim.fillMode = kCAFillModeForwards;
//旋转
CABasicAnimation *transformAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnim.duration = duration;
// 绕着(0, 0, 1)这个向量轴顺时针旋转rotation
transformAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(rotation, 0, 0, 1)];
//透明度
CABasicAnimation *opacityAnimation =[CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.fromValue = @0.f;
opacityAnimation.toValue = @1.f;
opacityAnimation.duration = duration;
opacityAnimation.fillMode = kCAFillModeForwards;
[layer addAnimation:positionAnim forKey:@"lposition"];
[layer addAnimation:transformAnim forKey:@"ltransform"];
[layer addAnimation:opacityAnimation forKey:@"lopacity"];
layer.opacity = 0;
//循环动画
if (animation) {
[self performSelector:@selector(addAnimationToLayer:) withObject:layer afterDelay:duration];
}
}
4.测试一下动画的效果
UILabel *label = [[UILabel alloc]init];
label.text = @"0";
label.font = [UIFont systemFontOfSize:20];
label.textColor = [UIColor whiteColor];
[label sizeToFit];
[self addSubview:label];
[self addAnimationToLayer:label.layer];
5.循环动画
增加一个属性animation来判断是否循环执行动画(这样如果要停止循环只要把它设置为NO就好了),然后在addAnimationToLayer:添加循环调用的方法:
//循环动画
if (_animation) {
[self performSelector:@selector(addAnimationToLayer:) withObject:layer afterDelay:duration];
}
6.添加细节
经过上面的过程,动画的效果已经解决了。
接下来就是产生4个元素,再加上下面终点的图片,基本上就可以达到想要的效果了。
上图:
好了 今天先实现到这里,后续有空到话再继续优化,代码已经上传到GZCLoding,如果有什么建议,欢迎留言告诉我哦。