3D变换

来源:互联网 发布:淘宝卖家数据采集 编辑:程序博客网 时间:2024/06/05 04:07

CATransform3D

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

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

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

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模式

-(void)innerAndOutView{CATransform3D outer = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);self.outView.layer.transform = outer;//rotate the inner layer -45 degreesCATransform3D inner = CATransform3DMakeRotation(-M_PI_4, 0, 0, 1);self.innerView.layer.transform = inner;}

20170702149896783255215.png

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

-(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 degreesCATransform3D 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的子类来解决这个问题”

.

原创粉丝点击