ios动画相关技术

一,iOS动画概念

      UI就是 App 的门面,它的体验伴随着用户使用 App 的整个过程。如果UI失败,用户是不会有打开第二次的欲望的!在AppStore中的应用越来越重视动画效果的使用,一个良好动画效果可以让两个状态之间平滑地过度,也可以利用动画吸引住用户的眼球.

1, 计算机动画的实现方式

      我们一般在计算机上用 FPS ( Frames Per Second) ,即 每秒的帧数 来表示动画的刷新速度,基于屏幕的刷新率等其他原因,在计算机上一般采用 60 FPS。
如果运动变化幅度较缓,减半到 30 FPS 时,我们肉眼也是可接受的。
较低的 FPS 会让我们有“卡顿”的感觉。

      iOS 为开发者提供了丰富的 Framework(UIKit,Core Animation,Core Graphic,OpenGL 等等)来满足开发从上层到底层各种各样的需求!绚丽动画效果是IOS系统的一大特点,通过UIView层封装的动画,基本可以满足应用开发的大部分需求,但如果想要满足自由的控制动画的展示,就需要使用CoreAnimation框架中的一些类和方法!下图就很好的展示了UIKit与CoreAnimation的关系!如下图:
core Graphic是高级绘图引擎,OpenGL ES/OpenGL是一个功能强大的图形库
注释:
OpenGL ES/OpenGL 是一个功能强大的图形库,还包括音视频渲染,滤镜等。。。
core Graphic是高级绘图引擎
2018年之后,苹果内核将用metal
例如EAGLContext类相关!
在这里插入图片描述
client:指的是在CPU上存储的一些代码,例如OpenGL的API和一些本地代码
server:
1,Arrtibutes指的是属性,该属性只能是cpu传递给(Vertex Shader)顶点着色器,并不是直接传递给(Gragment Shader)片元着色器,指的是顶点数据,颜色,纹理坐标等。
2,uniforms 数据可以直接传递给顶点着色器也可以直接传递给片元着色器,uniforms指的是具有统一性的数据,比如一个图形发生旋转等,也可以理解为是一个数据通道,在视频处理我们一般用YUV颜色空间,而转换需要为RGB才可以被现实,这个矩阵就用uniforms传递。
3,Texture Data 传递的是纹理数据. 例如做滤功能,滤镜是对图片本身做处理,也就是对文理做处理(纹理其实就是图片),别的还有像素填充/颜色填充等也都可以使用.
4,顶点着色器的Outs(输出)我们目前是无法干预的,应为OpenGL并没有给出相应的接口

顶点着色器分为输入和输出两部分,负责的功能是把输入的数据进行矩阵变换位置,计算光照公式生成逐顶点颜⾊,⽣成/变换纹理坐标
片元着色器的作用是处理由光栅化阶段生成的每个片元,最终计算出每个像素的最终颜色。归根结底,实际上就是数据的集合。
顶点着色器下一个阶段是图元装配,图元(prmitive)是三角形、直线或者点精灵等几何对象。这个阶段,把顶点着色器输出的顶点组合成图元。

METAL渲染是什么?
Metal渲染是由苹果公司为iOS8以及更新版本开发的全新的底层渲染APIMetal 是一个和 OpenGL ES 类似的面向底层的图形编程接口,通过使用相关的 api 可以直接操作 GPU!它侧重于减少GPU驱动的工作量,从而当Metal调用时,CPU的消耗将降至最低。这样一来,游戏就可以利用节省下来的CPU做出更多酷炫的效果。使用要引用框架#import <Metal/Metal.h>

2, Layer和view的关系与区别

      UIView通过内部图层layer显示在屏幕上,本身并不能显示。当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的layer图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示,如图:
在这里插入图片描述
      Layer是专门用来辅助我们绘制图像的层,通过每个坐标点与矩阵的运算,来决定最后绘制的状态!而view是要用来接受事件和处理用户交互的。然而,每一个view中,都有一个layer属性来辅助我们进行图形的绘制,并且Layer是可以层级嵌套的。

区别:
1,UIView控制界面交互,CALayer控制界面显示。
2,UIView继承UIRespinder,CALayer继承自NSObject。
3,核心动画要加在CALayer上时3D变换,而UIView是2D变换。

3, view的基础动画

      在UIKit中,系统提供了animate标题打头的属于UIView的类方法让我们可以轻松的制作动画效果,每一个这样的类方法提供了名为animations的block代码块,这些代码会在方法调用后立刻或者延迟一段时间以动画的方式执行。

[UIView beginAnimations:@"firstAnimation" context:nil];
[UIView setAnimationDuration:2.f];
[UIView commitAnimations];

      但是在上面介绍的方法已经在ios13后被建议废弃掉了,取而代之的是UIView的block动画

/**
      *  关键帧动画
      *  第一个参数:动画持续时间
      *  第二个参数:动画延时开始的时间
      *  第三个参数:动画的过渡效果:UIViewKeyframeAnimationOption
      *  第四个参数:执行的动画代码
      *  第五个参数:动画执行完成之后的回调
  */
  [UIView animateKeyframesWithDuration:1.0 delay:2.0 options:UIViewKeyframeAnimationOptionRepeat animations:^{
    self.containerView.transform = CGAffineTransformMake(10, 8, 20, 1, 0, 0);
  } completion:^(BOOL finished) {
    self.containerView.transform = CGAffineTransformMake(12, 23, 34, 1, 0, 0);
  }];

4, view的transform2D形变

UIView有个transform的属性,通过设置该属性,我们可以实现调整该view在其superView中的大小和位置,具体来说,Transform(变化矩阵)是一种3×3的矩阵,通过这个矩阵我们可以对一个坐标系统进行缩放,平移,旋转以及这两者的任意组着操作。而且矩阵的操作不具备交换律,即矩阵的操作的顺序不同会导致不同的结果。

struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//原本默认的设置
self.containerView.transform = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
//添加简单的动画
  [UIView animateWithDuration:1.0f animations:^{
    self.containerView.transform = CGAffineTransformMakeRotation(-30);
  }];

系统已经给出了方便的api调用

//平移
CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty)
//缩放
CGAffineTransformMakeScale(CGFloat sx,CGFloat sy)
//旋转
CGAffineTransformMakeRotation(CGFloat angle) (angle 旋转的角度)
//恢复
CGAffineTransformInvert(CGAffineTransform t)

案例:user4

5, layer的transform3D形变

      CALayer同样也有一个transform属性,但它的类型是CATransform3D,而不是CGAffineTransform。CALayer对应于UIView的transform属性叫做affineTransform.CATransform3D也是一个矩阵,但是和2x3的矩阵不同,CATransform3D是一个可以在3维空间内做变换的4x4的矩阵. ,如图
在这里插入图片描述

struct CATransform3D
{
CGFloatm11(x缩放),m12(y切变),m13(旋转),m14();
 
CGFloatm21(x切变),m22(y缩放),m23(),m24();
 
CGFloatm31(旋转),m32( ),m33(),m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义);
 
CGFloatm41(x平移),m42(y平移),m43(z平移),m44();
};

6, 正投影与透视投影

在这里插入图片描述
m34:管理z方向的深度,m34 = -1/z中,当z为正的时候,是我们人眼观察现实世界的效果,即在投影平面上表现出近大远小的效果,z越靠近原点则这种效果越明显,越远离原点则越来越不明显,当z为正无穷大的时候,则失去了近大远小的效果,此时投影线垂直于投影平面!
案例:user2
在这里插入图片描述
在这里插入图片描述

绕任意一个轴旋转公式:
在这里插入图片描述)

CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz) 
CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)

二, 图层及其相关子类

1,显示动画与隐式动画

当对非Root Layer的部分属性进行修改时,默认会自动产生一些动画效果!而这些属性称为Animatable Properties(可动画属性)
列举几个常见的Animatable Properties:
bounds:用于设置CALayer的宽度和高度。修改这个属性会产生缩放动画
backgroundColor:用于设置CALayer的背景色。修改这个属性会产生背景色的渐变动画
position:用于设置CALayer的位置。修改这个属性会产生平移动画
可以通过动画事务(CATransaction)关闭默认的隐式动画效果

CATransaction:
CATransaction是事务,用于批量提交多个对layer-tree的操作,并且是原子性的。所有对layer-tree的修改都必须包含在事务内。事务可以嵌套。

隐式CATransaction:
所有对layer-tree的操作都必须处于事务。修改UIView的属性最终也是修改到了layer-tree。当我们改动到layer-tree时,如果当前没有显式创建过CATransaction,则系统会创建一个隐式的CATransaction,这个隐式CATransaction会在RunLoop结束后commit。
另外事务可以嵌套,当事务嵌套时候,只有最外层的事务commit了之后,整个动画才会执行。

案例CATransaction

2,锚点

锚点:锚点决定了图层的绘制位置以及在动画被展示时其参照的点,瞄点的取值范围为0~1(Layer层的position参照点始终和和锚点重合)(决定了旋转,放大,缩小的参照点)(anchorPoint设置锚点)如图:
简单点来说就是决定着CALayer身上的哪个点会在position属性所指的位置!
在这里插入图片描述
案例anchorPoint
在这里插入图片描述

3,CAShapeLayer

 用于绘制立体贝塞尔曲线
 - (void)setupShapeLayer{
    //创建路径
    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(50, 320)];
    [path addQuadCurveToPoint:CGPointMake(300, 320) controlPoint:CGPointMake(100, 400)];
    [path addQuadCurveToPoint:CGPointMake(50, 320) controlPoint:CGPointMake(100, 350)];
    // 创建 shapeLayer
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc]init];
    [self.view.layer addSublayer:shapeLayer];
    //呈现的形状的路径
    shapeLayer.path = path.CGPath;
    //填充路径的颜色,默认颜色为不透明的黑色。
    shapeLayer.fillColor = [UIColor redColor].CGColor;
    //设置描边色,默认无色。
    shapeLayer.strokeColor = [UIColor greenColor].CGColor;
    //线的宽度,默认为1
    shapeLayer.lineWidth = 2;
    //lineJoin为线连接类型,其值也有三个类型,分别为kCALineJoinMiter、kCALineJoinRound、kCALineJoinBevel,默认值是Miter
    shapeLayer.lineJoin = kCALineJoinRound;
    //lineCap为线端点类型,值有三个类型,分别为kCALineCapButt 、kCALineCapRound 、kCALineCapSquare,默认值为Butt
    shapeLayer.lineCap = kCALineCapRound;
}

4,CAEmitterLayer

用于控制粒子效果,例如,钱包雨,烟花,火焰等效果
案例:FFEmitterDemo

5,CTransformLayer

用于渲染3D Layer 层次结构,就像在其子view上可以实现layer任意的旋转
案例:user3

//以下两行同时设置才能保持移动后的位置状态不变
  animation.fillMode=kCAFillModeForwards;
  animation.removedOnCompletion = NO;

6,CAGradientLayer

用于控制颜色渐变,项目里经常用到
案例:CAGradient

三,核心动画

      在CoreAnimation中,动画效果都是添加在图层的变化上的,通过CALayer,我们组织复杂的层级结构。例如:改变图层的大小,颜色,圆角等。layer层并不决定视图的展示,它只是存储了视图的几何状态。
在这里插入图片描述

1,转场动画(CATransition)

CATransition类实现层的转场动画。你可以从一组预定义的转换或者通过提供定制的CIFilter实例来指定转场效果。
案例:CATransition
例子:

UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
        
    UIView *yellowView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    yellowView.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:yellowView];
    
    UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button2 setTitle:@"改变2" forState:UIControlStateNormal];
    button2.frame = CGRectMake(10, 500, 300, 40);
    [button2 addTarget:self action:@selector(changeUIView2) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button2];
- (void)changeUIView2
{
   CATransition *transition = [CATransition animation];
   transition.delegate = self;
   transition.duration = 1.5f;
   transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
   //@"cube" @"moveIn" @"reveal" @"fade"(default) @"pageCurl" @"pageUnCurl" @"suckEffect" @"rippleEffect" @"oglFlip"
   transition.type = @"rippleEffect";//另一种设置动画效果方法
   transition.subtype = kCATransitionFromLeft;
   [self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
   [self.view.layer addAnimation:transition forKey:@"animation"];
}

2,CABasicAnimation && CAAnimationGroup

CABasicAnimation 为layer属性提供了基础的帧动画能力。
CAAnimationGroup是可以保存一组动画对象,将 CAAnimationGroup对象加入图层后,组中所有动画对象可以同时并发运行。
案例:CABasicAnimation

CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.fromValue = @(self.containerView.center.y);
positionAnima.toValue = @(self.containerView.center.y-100);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
transformAnima.fromValue = @(0);
transformAnima.toValue = @(3 * M_PI);
transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 4;
animaGroup.fillMode = kCAFillModeForwards;
///为了让呈现树的图形不移除
animaGroup.removedOnCompletion = NO;
/*
 kCAFillModeForwards   动画结束后,layer会一直保持动画最后的状态
 kCAFillModeBackwards  在动画开始时,只要加入一个layer,layer会立即进入动画的初始状态并等待动画开始
 kCAFillModeBoth kCAFillModeForwards && kCAFillModeBackwards
 kCAFillModeRemoved 默认,回到初始的状态
 */
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.repeatCount = 1;
animaGroup.animations = @[positionAnima,transformAnima];

[self.containerView.layer addAnimation:animaGroup forKey:@"Animation"];

3,CASpringAnimation

iOS 9 新出的CASpringAnimation,是苹果专门解决开发者关于弹簧动画的这个需求而封装的类。
案例:CASpringAnimation

- (void)springAnimationTextAction:(CGPoint)point {
  CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:@"bounds"];
  //路径计算模式 (@"position")
  if ([springAnimation.keyPath isEqualToString:@"position"]) {
      springAnimation.fromValue = [NSValue valueWithCGPoint:self.containerView.layer.position];
      springAnimation.toValue = [NSValue valueWithCGPoint:point];
  }else if ([springAnimation.keyPath isEqualToString:@"position.x"]) {  
      springAnimation.fromValue = @(self.containerView.layer.position.x);
      springAnimation.toValue = @(point.x);
  }else if ([springAnimation.keyPath isEqualToString:@"position.y"]) {
      springAnimation.fromValue = @(self.containerView.layer.position.y);
      springAnimation.toValue = @(point.y);
  }else if ([springAnimation.keyPath isEqualToString:@"bounds"]) {
      springAnimation.fromValue = [NSValue valueWithCGRect:CGRectMake(point.x, point.y, 500, 500)];
      springAnimation.toValue = [NSValue valueWithCGRect:self.containerView.frame];
  }  
  //质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大 Defaults to one
  springAnimation.mass = 5;
  //刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快 Defaults to 100
  springAnimation.stiffness = 100;
  //阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快 Defaults to 10
  springAnimation.damping = 3;
  //初始速率,动画视图的初始速度大小 Defaults to zero
  //速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反
  springAnimation.initialVelocity = 10;
  //估算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算
  NSLog(@"====%f",springAnimation.settlingDuration);
  springAnimation.duration = springAnimation.settlingDuration;
  //removedOnCompletion 默认为YES 为YES时,动画结束后,恢复到原来状态
  springAnimation.removedOnCompletion = NO;
  [self.containerView.layer addAnimation:springAnimation forKey:@"springAnimation"];
}

4,CAKeyFrameAnimation

任何动画要表现运动或变化,至少前后要给出两个不同的关键状态,而中间状态的变化和衔接电脑可以自动完成,在Flash中,表示关键状态的帧动画叫做关键帧动画
案例:CAKeyFrameAnimation

   CALayer *layer = [CALayer layer];
   layer.bounds = CGRectMake(0, 0, 120, 120);
   //与基础动画不同,关键帧动画必须指明动画初始值
   layer.position = CGPointMake(100, 300);
   layer.cornerRadius = 60;
   layer.masksToBounds = YES;
   layer.contents = (id)[UIImage imageNamed:@"timg"].CGImage;
   [self.view.layer addSublayer:layer];
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    CALayer *layer = [self.view.layer.sublayers lastObject];
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    //设置关键帧
    //与基础动画不同,关键帧动画必须指明动画初始值
    NSValue *value1 = [NSValue valueWithCGPoint:layer.position];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(50, 300)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(50, 100)];
    animation.duration = 2;
    animation.values = @[value1,value2,value3];
    animation.autoreverses = YES;
    [layer addAnimation:animation forKey:nil];
}

四,参考:

1,https://www.jianshu.com/p/469a406db8a3
2,https://www.jianshu.com/p/941fc7105c7a
3,https://blog.csdn.net/ssirreplaceable/article/details/52979399
4,https://www.cnblogs.com/LifeTechnologySupporter/p/10353073.html

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非线性动画下载iOS是一种可以在iOS设备上下载和使用的非线性动画制作工具。非线性动画是指在制作动画时可以自由排列和编辑各个动画片段的技术。在传统的线性动画制作中,动画片段是按照顺序排列,一帧接着一帧播放,而非线性动画则可以根据用户的需求随意组合和编辑动画片段,灵活地调整动画的时间轴,达到更加自由和创意的效果。 下载非线性动画制作工具可以为用户提供更多的创作空间和动画效果选择。用户可以通过该工具自主选择和组合各种动画片段,创作出丰富多样的非线性动画效果。非线性动画下载iOS也提供了一些方便实用的功能,如拖拽式操作界面、时间轴编辑、特效添加等,使得用户能够更加轻松地制作出精美独特的动画作品。 对于那些喜欢制作动画的用户来说,非线性动画下载iOS是一个极具吸引力的工具。它不仅可以帮助用户实现一些基本的动画效果,还可以为用户提供更高级的创作工具和功能,满足他们对于动画创作的需求。而且,由于该工具适用于iOS设备,用户可以轻松地在iPad或iPhone上进行动画创作,随时随地展现他们的创意和才华。 综上所述,非线性动画下载iOS是一种能够提供更多创作空间和丰富功能的动画制作工具,它能够帮助用户制作出独特、富有创意的动画作品,并在各种iOS设备上进行展示和分享。无论是对于专业动画师,还是对于爱好者来说,非线性动画下载iOS都是一个值得尝试的工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值