iOS CALayer图层漫谈（四）

CALayer的仿射变换

`transform`属性是用作于二维空间旋转、缩放和平移的这样一个属性，为`CGAffineTransform`类型，实质是一个可以和二维空间向量做乘法的`3*2`矩阵。说到矩阵可能有人会说对矩阵知识掌握的并不是很多，不要害怕，Core Graphics为我们提供了一系列的函数，即使没有数学基础也可以进行一些相应的变换操作。

``````CGAffineTransformMakeRotation(CGFloat angle);
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty);
``````

``````view.transform = CGAffineTransformMakeScale(0.5, 0.5);
``````
``````view.transform = CGAffineTransformMakeRotation(M_PI_4);
``````
``````view.transform = CGAffineTransformMakeTranslation(100, 100);
``````

``````view.layer.affineTransform = CGAffineTransformMakeScale(0.5, 0.5);

view.layer.affineTransform = CGAffineTransformMakeRotation(M_PI_4);

view.layer.affineTransform = CGAffineTransformMakeTranslation(100, 100);
``````

``````CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy);
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty);
``````

``````CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);
``````

``````CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4);
transform = CGAffineTransformScale(transform, 0.5, 0.5);
transform = CGAffineTransformTranslate(transform, 100, 100);
view.layer.affineTransform = transform;
``````

``````CGAffineTransform transform = CGAffineTransformMakeScale(0.5, 0.5);
transform = CGAffineTransformTranslate(transform, 100, 100);
transform = CGAffineTransformRotate(transform, M_PI_4);
view.layer.affineTransform = transform;
``````

CALayer的3D变换

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

``````view.layer.transform = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
``````

``````CATransform3D transform3D = CATransform3DIdentity;
transform3D.m34 = -1.f /500.f;
transform3D = CATransform3DRotate(transform3D, M_PI_4, 0, 1, 0);
view.layer.transform = transform3D;
``````

旋转抵消问题

``````CATransform3D transform3D = CATransform3DIdentity;
transform3D.m34 = -1.f /700.f;
transform3D = CATransform3DRotate(transform3D, M_PI_4, 0, 1, 0);
view.layer.transform = transform3D;

CATransform3D transform3D1 = CATransform3DIdentity;
transform3D1.m34 = -1.f/700.f;
layer.transform = CATransform3DRotate(transform3D1, -M_PI_4, 0, 1, 0);
``````

固体对象

https://pan.baidu.com/s/1jJ8xt10

``````UIView * containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 100, 375, 375)];

UIButton * faceBtn1 = [UIButton buttonWithType:UIButtonTypeCustom];
[faceBtn1 setFrame:CGRectMake(0, 0, 140, 140)];
[faceBtn1 setCenter:CGPointMake(containerView.frame.size.width/2,containerView.frame.size.height/2)];
[faceBtn1 setImage:[UIImage imageNamed:@"1.png"] forState:UIControlStateNormal];
[faceBtn1 setTag:1];
[faceBtn1 addTarget:self action:@selector(clickFaceBtn:) forControlEvents:UIControlEventTouchUpInside];
faceBtn1.layer.doubleSided = NO; // 不绘制图层的背面

...

// 由于其他faceBtn2、faceBtn3、faceBtn4、faceBtn5、faceBtn6的创建跟faceBtn1相同，这里就省略了
``````

``````CATransform3D transform3D;

transform3D = CATransform3DMakeTranslation(0, 0, 70);
faceBtn1.layer.transform = transform3D; // 前面

transform3D = CATransform3DMakeTranslation(-70, 0, 0);
transform3D = CATransform3DRotate(transform3D, -M_PI_2, 0, 1, 0);
faceBtn2.layer.transform = transform3D; // 左面

transform3D = CATransform3DMakeTranslation(70, 0, 0);
transform3D = CATransform3DRotate(transform3D, M_PI_2, 0, 1, 0);
faceBtn3.layer.transform = transform3D; // 右面

transform3D = CATransform3DMakeTranslation(0, -70, 0);
transform3D = CATransform3DRotate(transform3D, M_PI_2, 1, 0, 0);
faceBtn4.layer.transform = transform3D; // 上面

transform3D = CATransform3DMakeTranslation(0, 70, 0);
transform3D = CATransform3DRotate(transform3D, -M_PI_2, 1, 0, 0);
faceBtn5.layer.transform = transform3D; // 下面

transform3D = CATransform3DMakeTranslation(0, 0, -70);
transform3D = CATransform3DRotate(transform3D, M_PI, 0, 1, 0);
faceBtn6.layer.transform = transform3D; // 后面
``````

• 旋转1
``````CATransform3D containerTransform = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
containerTransform = CATransform3DRotate(containerTransform, M_PI_4, 1, 0, 0);
containerView.layer.sublayerTransform = containerTransform;
``````
• 旋转2
``````CATransform3D containerTransform = CATransform3DMakeRotation(-M_PI_4, 0, 1, 0);
containerTransform = CATransform3DRotate(containerTransform, M_PI_4, 1, 0, 0);
containerView.layer.sublayerTransform = containerTransform;
``````
• 旋转3
``````CATransform3D containerTransform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
containerTransform = CATransform3DRotate(containerTransform, M_PI_4, 0, 1, 0);
containerTransform = CATransform3DRotate(containerTransform, M_PI_4, 1, 0, 0);
containerView.layer.sublayerTransform = containerTransform;
``````

光亮和阴影

``````#define LIGHT_DIRECTION 1, 0, 0
#define AMBIENT_LIGHT 0.5

CATransform3D transform = face.transform;
GLKMatrix4 matrix4 = *(GLKMatrix4 *)&transform;
GLKMatrix3 matrix3 = GLKMatrix4GetMatrix3(matrix4);
// 获得平面法向量
GLKVector3 normal = GLKVector3Make(1, 0, 0);
normal = GLKMatrix3MultiplyVector3(matrix3, normal);
normal = GLKVector3Normalize(normal);
// 计算平面法向量与光源向量叉乘
GLKVector3 light = GLKVector3Normalize(GLKVector3Make(LIGHT_DIRECTION));
float dotProduct = GLKVector3DotProduct(light, normal);

CGFloat shadow = 1 + dotProduct - AMBIENT_LIGHT;

CALayer *layer = [CALayer layer];
layer.frame = face.bounds;
layer.backgroundColor = [UIColor colorWithWhite:0 alpha:shadow].CGColor;