实现类似Twitter的启动动画

来来来,今天咱们通过实现一个类似Twitter的启动动画来看看CAKeyFrame Animation和CAAnimation Group怎么玩。

所以今天咱们的重点到了第七章,CAKeyFrame Animation和CAAnimation Group。最后的那个启动动画完全是为了实践一下看看CAKeyFrame Animation和CAAnimation Group怎么使用。

有读者私下说更新速度太慢了。在码云上看了一下下载的统计,发现其实下载的童鞋并不是特别多。如果只是看看思路,或者复习一下这些基础知识,确实是很快。但是如果对于这些内容不是特别熟悉,建议还是敲一边代码,看看自己能碰到什么坑。

俺写一篇分享文章大约要4~6个小时,大体是三部分:想到合适的例子,敲代码写注释,写文章。通常都会看自己当前的情况,决定是先写swift版还是OC版,然后不动脑子的翻译成另外一版调整一下BUG。这样也是为了训练自己,前段时间发现自己有时候会不自觉的把两种语言混在一起,这个习惯特别不好,所以想用这种方式自己纠正一下。到最后更新写文章的时候反而更轻松了,因为不用动脑。哈哈~

Come on~下面这张图纯粹是为了简书当作封面使用的。也不知道为什么,以前简书还能自动把GIF的第一桢当作封面,现在不好使了。


CAKeyFrame Animation和CAAnimation Group.png

下面展示一下写完之后的成果:


ani.gif

源代码可以在这里下载,里面有OC和Swift两版。https://git.oschina.net/atypical/CAKeyFrame-_Group_Animation.git

iOS动画系列之CAKeyFrame Animation和CAAnimation Group(OC和Swift两版)

1. CAKeyframeAnimation

CAKeyframeAnimation是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值。

创建步骤:

  1. 创建关键帧动画对象
  2. 设置属性
  3. 添加到要作用的layer上
  4. 如果使用rect椭圆的方式,动画会不连贯,停顿一下。原因是因为矩形的周长比椭圆的长,动画路径按照椭圆执行完之后,需要等待一下最大周长走完。
    这些都是因为计算模式导致的。

1.1 创建一个抖动的小方块

我们用一个简单的demo来感受一下CAKeyframeAnimation,来做一个会抖动的小方块。


抖动的小方块.gif
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
//设置一些列的关键帧动画
    animation.values = @[@(-M_PI_4 / 5),@(M_PI_4 / 5),@(-M_PI_4 / 5)];
    animation.repeatCount = CGFLOAT_MAX;
    [self.view.layer addAnimation:animation forKey:@"rotation"];

1.2 创建一个沿椭圆路径运动的小飞机

我们创建一个UIBezierPath,让小飞机沿着这个路径运动。

//创建动画对象
    CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置属性:创建beziper路径,并把路径作为运动轨迹
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 200, 500)];
    keyFrameAnimation.path = bezierPath.CGPath;
//设置动画时间
    keyFrameAnimation.duration = 2;
//设置动画循环播放的次数
    keyFrameAnimation.repeatCount = CGFLOAT_MAX;
//设置动画的计算模式
    keyFrameAnimation.calculationMode = kCAAnimationPaced;

//将动画添加到layer上
    [self.planeView.layer addAnimation:keyFrameAnimation forKey:nil];

1.3 动画叠加

刚才添加了一个沿路径运动的飞机,我们同时还可以给飞机再把抖动的那个动画也添加上去。前几篇提到后面那个forKey,可能还有童鞋不知道干啥用。现在看到了木有?一个layer里面好几个动画,如何找到对应的动画吶?现在通过这个key就能找到了。

    //        为小飞机同时添加抖动的动画和椭圆路径旋转的动画
    [self.planeImageView.layer addAnimation:[self shakeAni] forKey:nil];
    [self.planeImageView.layer addAnimation:[self ovalAni] forKey:nil];

2. CAAnimationGroup

单一的动画在实际中往往是不能满足需求的,这时就需要用到动画组。

  • 是CAAnimation的子类
  • 可以保存一组动画对象,将CAAnimationGroup对象加入图层后,组中所有动画对象可以同时并发运行.

我们试着做一个包行旋转、缩放、按一定弧度路径组合在一起的动画。效果如下:


arcAni.gif
- (CAAnimationGroup *)groupAni{
    //        实例化一个组动画对象
        CAAnimationGroup *groupAni = [[CAAnimationGroup alloc] init];

    //        创建旋转的动画
        CABasicAnimation *basicRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    basicRotation.toValue = @(M_PI * 2);

    //        创建缩放的动画
        CABasicAnimation *basicScale = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    basicScale.toValue = @(0.2);

    //        创建按照路径移动的动画
        CAKeyframeAnimation *keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *arcPath = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:150 startAngle:0 endAngle:M_PI * 2 clockwise:YES];

    keyFrameAni.path = arcPath.CGPath;
    keyFrameAni.calculationMode = kCAAnimationPaced;
    keyFrameAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    //        将旋转、缩放、移动的动画添加到组动画中
    groupAni.animations = @[basicRotation,basicScale,keyFrameAni];
    //        组动画重复次数
        groupAni.repeatCount = CGFLOAT_MAX;
    //        组动画时长
        groupAni.duration = 2;

    return groupAni;
}

3. 实现类似Twitter的启动动画

3.1实现思路

1,在View上设置一个东西能够遮挡住背景图;
2,把遮罩变成五角星;
3,让遮罩慢慢变大,中间可见区域越来越大。

yes!思路就是这样的。那怎么遮住背景图片呢?

3.2 CALayer的遮罩属性

CALayer本身有一个属性,叫mask。我们来看一下官方解释:

 @property(nullable, strong) CALayer *mask;

When true an implicit mask matching the layer bounds is applied to
the layer (including the effects of the `cornerRadius' property). If
both `mask' and `masksToBounds' are non-nil the two masks are
multiplied to get the actual mask values. Defaults to NO.
Animatable.

它类似于一个子图层,相对于父图层(即拥有该属性的图层)布局,但是它却不是一个普通的子图层。不同于其他能够在父图层中绘制出图像的子图层,mask图层定义了父图层的部分可见区域。

mask图层的Color属性是无关紧要的,真正重要的是图层的轮廓。也就是说mask图层实心的部分会被保留下来,其他的则会被抛弃。如果mask图层比父图层要小,只有在mask图层里面的内容才是它关心的,除此以外的一切都会被隐藏起来。

Paste_Image.png

3.3 实现类似Twitter的启动动画

好了准备工作都做完了,我们就开始写这个动画了。这个动画其实就是一个简单的CAKeyframeAnimation。设置了三个关键帧动画的大小,以及这三个关键帧的运动节奏。

然后,就好啦~然后,就好啦~然后,就好啦~然后,就好啦~

哪尼?!!!就这样?!!对啊,就这样。

 - (CAKeyframeAnimation *)maskAni{
 //        放大缩小视图,keypath使用bounds
 CAKeyframeAnimation *maskAni = [CAKeyframeAnimation animationWithKeyPath:@"bounds"];
 //        动画时间
 maskAni.duration = 30.75;
 //        动画延迟0.5秒播放
 maskAni.beginTime = CACurrentMediaTime() + 0.5;


 //        设置关键帧动画的数值
 CGRect startRect = self.maskLayer.frame;

 CGRect tempRect = CGRectMake(0, 0, 100, 100);

 CGRect finalRect = CGRectMake(0, 0, 2000, 2000);
 maskAni.values = @[[NSValue valueWithCGRect:startRect],[NSValue valueWithCGRect:tempRect],[NSValue valueWithCGRect:finalRect]];


 //        设置关键帧动画的运动节奏
 maskAni.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];


 //        动画播放结束后是否移除动画
 maskAni.removedOnCompletion = NO;

 //        动画填充模式:kCAFillModeForwards:当动画结束后,layer会一直保持着动画最后的状态
 maskAni.fillMode = kCAFillModeForwards;

 return maskAni;


 }

留一个小问题

我在OC和Swift里面对不同的View使用了mask。一个是给背景图片的UIImageView设置了mask,另一个是直接给Controller的View设置了mask。设置这两个有神马区别咩?

好,下篇其实有一个重头,就是CAShapeLayer。因为在工作中碰到的大部分动画都是通过UIView的动画block实现,其他都基本上都是需要用到CAShapeLayer。我们下次玩点好玩的吧~
如果还有兴趣,可以看看本系列的其他文章哈。

-----------------------华丽分割线,iOS动画系列全集链接-------------------------------------------------
第一篇:iOS动画系列之一:通过实战学习CALayer和透视的原理。做一个带时分秒指针的时钟动画(上)
第二篇:iOS动画系列之二:通过实战学习CALayer和透视的原理。做一个带时分秒指针的时钟动画。包含了OC和Swift两种源代码(下)
第三篇:iOS动画系列之三:Core Animation。介绍了Core Animation的常用属性和方法。
第四篇:CABasic Animation。iOS动画系列之四:基础动画之平移篇
第五篇:CABasic Animation。iOS动画系列之五:基础动画之缩放篇&旋转篇
第六篇:iOS动画系列之六:利用CABasic Animation完成带动画特效的登录界面
第七篇:iOS动画系列之七:实现类似Twitter的启动动画
第八篇:iOS动画系列之八:使用CAShapeLayer绘画动态流量图
第九篇:iOS动画系列之九:实现点赞的动画及播放起伏指示器
第十篇:实战系列:绘制过山车场景

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值