iOS动画我爱编程特效动画

iOS 动画四:transform 动画

2018-06-21  本文已影响475人  _浅墨_

一、iOS transform 动画

@property(nonatomic) CGAffineTransform transform;  *// view 的属性*
@property CATransform3D transform; *// layer 的属性*

两者的区别就是在 二维和 三维的区别,是用 CGAffineTransform 和 CATransform3D 的区别。

transform 几个常用的函数:

/// 用来连接两个变换效果并返回。返回的t = t1 * t2
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2)
 
/// 矩阵初始值。[ 1 0 0 1 0 0 ]
CGAffineTransformIdentity
 
/// 自定义矩阵变换,需要掌握矩阵变换的知识才知道怎么用。参照上面推荐的原理链接
CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty)
 
/// 旋转视图。传入参数为 角度 * (M_PI / 180)。等同于 CGAffineTransformRotate(self.transform, angle)
CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
 
/// 缩放视图。等同于CGAffineTransformScale(self.transform, sx, sy)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
 
/// 缩放视图。等同于CGAffineTransformTranslate(self.transform, tx, ty)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)

1、平移

//平移
[UIView animateWithDuration:0.5 animations:^{
//使用Make,它是相对于最原始的位置做的形变.
//self.imageV.transform = CGAffineTransformMakeTranslation(0, -100);
//相对于上一次做形变.
self.imageV.transform = CGAffineTransformTranslate(self.imageV.transform, 0, -100);
}];
/* Return a transform which translates by `(tx, ty)':
         t' = [ 1 0 0 1 tx ty ] */
public init(translationX tx: CGFloat, y ty: CGFloat)

经过坐标变换,可以得到

x' = x + tx
y' = y + ty

2、旋转

[UIView animateWithDuration:0.5 animations:^{

//旋转(旋转的度数, 是一个弧度)
//self.imageV.transform = CGAffineTransformMakeRotation(M_PI_4);

self.imageV.transform = CGAffineTransformRotate(self.imageV.transform, M_PI_4);

}];
/* Return a transform which scales by `(sx, sy)':
         t' = [ sx 0 0 sy 0 0 ] */
public init(scaleX sx: CGFloat, y sy: CGFloat)

经过坐标变换,可以得到

x' = x * sx
y' = y * sy

3、缩放

[UIView animateWithDuration:0.5 animations:^{
//缩放
//self.imageV.transform = CGAffineTransformMakeScale(0.5, 0.5);
  self.imageV.transform = CGAffineTransformScale(self.imageV.transform, 0.8, 0.8);
}];
/* Return a transform which rotates by `angle' radians:
         t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] */
public init(rotationAngle angle: CGFloat)

这里入参是一个弧度值,角度 x 转换为弧度

angle

angle = x*Double.pi/180

假设 v 点的坐标是(x,y),那么可以推导得到 v’ 点的坐标(x’,y’)(设原点到 v 的距离是 r,原点到 v 点的向量与 x 轴的夹角是 ϕ )

x = rcosϕ, y = rsinϕ
x′ = rcos(θ+ϕ), y′= rsin(θ+ϕ)

通过三角函数展开得到

x′ = rcosθcosϕ − rsinθsinϕ
y′ = rsinθcosϕ + rcosθsinϕ

带入 x 和 y 表达式得到

x′ = xcosθ − ysinθ
y′ = xsinθ + ycosθ

写成矩阵的形式即:

二、CGAffineTransform 仿射变换

CGAffineTransform 结构体定义如下:

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

假设 b = c = 0
那么可以有下面两个情况:

a表示x水平方向的缩放,tx表示x水平方向的偏移
d表示y垂直方向的缩放,ty表示y垂直方向的偏移
如果b和c不为零的话,那么视图肯定发生了旋转

放射矩阵一个常用的情形就是根据用户的手势来相应的改变视图的变换,如:

UIPanGestureRecognizer 位移
UIPinchGestureRecognizer 缩放
UIRotationGestureRecognizer 旋转

苹果官方建议,如果我们想对对象进行缩放和旋转操作,我们不用直接创建 affine transforms,我们可以调用 CGContextTranslateCTM,CGContextScaleCTM, CGContextRotateCTM 这样的方法来实现我们想要的旋转、缩放、移动的效果。

Note that you do not typically need to create affine transforms directly. If you want only to draw an object that is scaled or rotated, for example, it is not necessary to construct an affine transform to do so. The most direct way to manipulate your drawing—whether by movement, scaling, or rotation—is to call the functions CGContextTranslateCTM,CGContextScaleCTM, orCGContextRotateCTM, respectively. You should generally only create an affine transform if you want to reuse it later.

小结:想想我们大学时候学习的高数、线性代数、概率论,知道它们在现实中有什么用处了吧!计算机问题归根到底是数学的问题。数学没学好的同学,努力补习功课吧,欠的债早晚要还的。接下来我得好好去学学数学了,(⊙﹏⊙) …

2018.06.21 夜
上海 虹桥

附: demo下载地址

参考链接:

  1. iOS 动画 —— transform - 简书
  2. iOS 开发之动画篇 - Transform和KeyFrame动画
  3. CGAffineTransform 放射变换 - CSDN博客
  4. CGAffineTransform二维视图旋转、缩放、平移变换详解 - 掘金
  5. CGAffineTransform - 简书
上一篇下一篇

猜你喜欢

热点阅读