文章目录
  1. 1. 透视投影
  2. 2. 灭点
  3. 3. sublayerTransform属性
  4. 4. 背面
  5. 5. 扁平化图层

CATransform3D

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

20170702149893501632567.gif

1
2
3
4
5
6
7
8
9
10
self.datlX+=10;
self.datlY+=10;
self.datlZ+=10;

[UIView beginAnimations:@"123" context:nil];
[UIView setAnimationDuration:2];
[UIView setAnimationRepeatCount:MAXFLOAT];
self.imageView.layer.transform = CATransform3DMakeRotation(M_PI, self.datlX, self.datlY, self.datlZ);

[UIView commitAnimations];

透视投影

CATransform3D的透视效果通过一个矩阵中一个很简单的元素来控制:m34”

20170702149893523930919.png

m34的默认值是0,我们可以通过设置m34为-1.0 / d来应用透视效果,d代表了想象中视角相机和屏幕之间的距离,以像素为单位 .因为视角相机实际上并不存在,所以可以根据屏幕上的显示效果自由决定它的防止的位置。通常500-1000就已经很好了,但对于特定的图层有时候更小后者更大的值会看起来更舒服,减少距离的值会增强透视效果,所以一个非常微小的值会让它看起来更加失真,然而一个非常大的值会让它基本失去透视效果

20170702149893622154123.png

灭点

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

当改变一个图层的position,你也改变了它的灭点,做3D变换的时候要时刻记住这一点,当你视图通过调整m34来让它更加有3D效果,应该首先把它放置于屏幕中央,然后通过平移来把它移动到指定位置(而不是直接改变它的position),这样所有的3D图层都共享一个灭点

20170702149895929771015.png

sublayerTransform属性

“如果有多个视图或者图层,每个都做3D变换,那就需要分别设置相同的m34值,并且确保在变换之前都在屏幕中央共享同一个position,如果用一个函数封装这些操作的确会更加方便,但仍然有限制(例如,你不能在Interface Builder中摆放视图),这里有一个更好的方法。”

2017070214989612315159.png

1
2
3
4
5
6
7
8
9
10
11
self.datlX=10;
self.datlY=10;
self.datlZ=10;

CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0/500;

[UIView animateWithDuration:1 animations:^{

self.fatherView.layer.sublayerTransform = CATransform3DRotate(transform,self.datlAngle, self.datlX, self.datlY, self.datlZ);
}];

优势:灭点被设置在容器图层的中点,从而不需要再对子图层分别设置了。这意味着你可以随意使用position和frame来放置子图层,而不需要把它们放置在屏幕中点,然后为了保证统一的灭点用变换来做平移。”

20170702149896241942718.png

1
2
3
4
5
6
7
8
9
10
self.n-=1;
self.datlAngle = M_PI_4*(self.n);

CATransform3D perfiver = CATransform3DIdentity;
perfiver.m34 = -1/500.0;
self.fatherView.layer.sublayerTransform = perfiver;
[UIView animateWithDuration:2 animations:^{
self.imageView.layer.transform = CATransform3DMakeRotation(-self.datlAngle, 0, 10, 0);
self.imageView2.layer.transform =CATransform3DMakeRotation(self.datlAngle, 0, 10, 0);
}];

背面

CYLayer的属性:doubleSided默认为Yes,默认是GPU会绘制背面

设置为NO,视图旋转至背面后,什么都不显示.

20170702149896388117288.gif

扁平化图层

z轴旋转 2D模式

1
2
3
4
5
6
7
8
9
-(void)innerAndOutView{
CATransform3D outer = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
self.outView.layer.transform = outer;
//rotate the inner layer -45 degrees
CATransform3D inner = CATransform3DMakeRotation(-M_PI_4, 0, 0, 1);
self.innerView.layer.transform = inner;


}

20170702149896783255215.png

z轴旋转,带有透视投影 3D

1
2
3
4
5
6
7
8
9
10
11
-(void)innerViewAndOutView{
CATransform3D outer = CATransform3DIdentity;
outer.m34 = -1.0 / 500.0;
outer = CATransform3DRotate(outer, M_PI_4, 0, 1, 0);
self.outView.layer.transform = outer;
//rotate the inner layer -45 degrees
CATransform3D inner = CATransform3DIdentity;
inner.m34 = -1.0 / 500.0;
inner = CATransform3DRotate(inner, -M_PI_4, 0, 1, 0);
self.innerView.layer.transform = inner;
}

2017070214989677941246.png

3D空间并未抵消变换是因为

“这是由于尽管Core Animation图层存在于3D空间之内,但它们并不都存在同一个3D空间。每个图层的3D场景其实是扁平化的,当你从正面观察一个图层,看到的实际上由子图层创建的想象出来的3D场景,但当你倾斜这个图层,你会发现实际上这个3D场景仅仅是被绘制在图层的表面。”

“这使得用Core Animation创建非常复杂的3D场景变得十分困难。你不能够使用图层树去创建一个3D结构的层级关系–在相同场景下的任何3D表面必须和同样的图层保持一致,这是因为每个的父视图都把它的子视图扁平化了。”

“CALayer有一个叫做CATransformLayer的子类来解决这个问题”

.

文章目录
  1. 1. 透视投影
  2. 2. 灭点
  3. 3. sublayerTransform属性
  4. 4. 背面
  5. 5. 扁平化图层