iOS动画:变换

学习手记,每天进步一点!

前言

本章学习图层旋转,缩放或者移动的CGAffineTransform,以及可以将扁平物体转换成三维空间对象CATransform3D

仿射变换

CGAffineTransform是一个可以和二维空间向量做乘法的3*2的矩阵。

例子:创建CGAffineTransform

1
2
3
4
5
6
7
8
9
10
11
12
13
    /// 创建AffineTransform
func affineTransform() {
//旋转45°
let transform = CGAffineTransform(rotationAngle: CGFloat.pi * 0.25)
// 缩放
// let transformScale = CGAffineTransform(scaleX: 1, y: 1.5)
// 移动
// let transformX = CGAffineTransform(translationX: 100, y: 200)
let layerView = UIView(frame: CGRect(x: 50, y: 200, width: 100, height: 100))
layerView.layer.setAffineTransform(transform)
layerView.backgroundColor = .green
view.addSubview(layerView)
}

混合变换

Core Graphics提供一系列的函数可以在一个变换的基础上做更深层次的变化。例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/// 混合变换
func mixtureAffineTransform() {

let transform = CGAffineTransform.identity
// 缩放50%
.scaledBy(x: 0.5, y: 0.5)
// 旋转45°
.rotated(by: CGFloat.pi * 0.25)
// 平移x+200
.translatedBy(x: 200, y: 0)
let layerView = UIView(frame: CGRect(x: 50, y: 200, width: 100, height: 100))
layerView.layer.setAffineTransform(transform)
layerView.backgroundColor = .green
view.addSubview(layerView)
}

注意:OC和Swift在混合变换有区别。

3D变换

在之前提到zPosition属性,可以用来让图层靠近或者远离相机,transform属性(CATransform3D类型),让图层在3D空间内移动或者旋转。

CGAffineTransform类似,CATransform3D一个矩形,一个可以在三维空间内做变换的4*4的矩阵。

可以修改参数anglexyz

常见的矩阵配置:

依次是恒等转换,平移,缩放,绕X轴,绕Y轴,绕Z轴。

例子:

1
2
3
4
5
6
7
8
func transform3D() {

let transform = CATransform3DMakeRotation(CGFloat.pi / 4, 0, 1, 0)
let layerView = UIView(frame: CGRect(x: 50, y: 200, width: 100, height: 100))
layerView.layer.transform = transform
layerView.backgroundColor = .green
view.addSubview(layerView)
}

绕Y轴旋转45°。

透视投影

CATransform3Dm34元素,默认值是0。可以通过设置m34为 -1.0/d来应用透视效果,d代表想象中视角相机和屏幕之间的距离。

1
2
3
4
5
6
7
8
9
10
11
12
// 创建transform
var transform = CATransform3DIdentity
// 设置透视
transform.m34 = -1.0 / 500.0
//绕Y轴45°
transform = CATransform3DRotate(transform, CGFloat.pi / 4, 0, 1, 0)
// 创建View
let layerView = UIView(frame: CGRect(x: 50, y: 200, width: 100, height: 100))
// 应用layer
layerView.layer.transform = transform
layerView.backgroundColor = .green
view.addSubview(layerView)

灭点

透视角度绘图的时候,远离相机视角的物体将会变小边远,当远离到一个极限距离,它们可能被缩成一个点。

Core Animation定义了这个点位于变换图层的anchorPoint。当图层发生变换时,这点永远位于图层变换之前anchorPoint的位置。

当改变一个图层的position,也就改变灭点,做3D变换的时候要时刻记住。

sublayerTransform属性

CALayer有一个属性叫做sublayerTransform。它也是CATransform3D类型,但和对一个图层的变换不同,它影响到所有的子图层。可以一次性对包含这些图层的容器做变换,于是所有的子图层都自动继承了这个变换方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 创建透视,应用到容器中
var perspective = CATransform3DIdentity
// 添加相机位置
perspective.m34 = -1.0 / 500.0
self.view.layer.sublayerTransform = perspective

//layerView绕Y轴旋转45°
let transform1 = CATransform3DMakeRotation(CGFloat.pi / 4, 0, 1, 0)
let layerView = UIView(frame: CGRect(x: 50, y: 200, width: 100, height: 100))
layerView.layer.transform = transform1
layerView.backgroundColor = .green
view.addSubview(layerView)

//layerView1绕Y轴旋转45°
let transform2 = CATransform3DMakeRotation(-CGFloat.pi / 4, 0, 1, 0)
let layerView1 = UIView(frame: CGRect(x: 200, y: 200, width: 100, height: 100))
layerView1.layer.transform = transform2
layerView1.backgroundColor = .green
view.addSubview(layerView1)

背面

CALayer有一个doubleSided的属性来控制图层的背面是否要被绘制。

小结