欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

详解iOS的Core Animation框架中的CATransform3D图形变换

程序员文章站 2024-02-10 15:23:22
一、矩阵坐标 catransform3d定义了一个变化矩阵,通过对矩阵参数的设置,我们可以改变layer的一些属性,这个属性的改变,可以产生动画的效果。 catrans...

一、矩阵坐标
catransform3d定义了一个变化矩阵,通过对矩阵参数的设置,我们可以改变layer的一些属性,这个属性的改变,可以产生动画的效果。
catransform3d catransform3dmaketranslation (cgfloat tx, cgfloat ty, cgfloat tz)
tx:x轴偏移位置,往下为正数。
ty:y轴偏移位置,往右为正数。
tz:z轴偏移位置,往外为正数。
例:
如果有2个图层,一个是绿色的,一个是红色的。先加载绿色,后加载红色。
tx,ty的左右偏移先不说了。
如果绿色的tz为-10 ,红色的tz为 0 效果如下。

详解iOS的Core Animation框架中的CATransform3D图形变换

如果绿色的tz为 0 ,红色的tz为-10 效果如下。

详解iOS的Core Animation框架中的CATransform3D图形变换

对于tz来说,值越大,那么图层就越往外(接近屏幕),值越小,图层越往里(屏幕里)。
catransform3d catransform3dtranslate (catransform3d t, cgfloat tx, cgfloat ty, cgfloat tz);
t:就是上一个函数。其他的都一样。
就可以理解为:函数的叠加,效果的叠加。
catransform3d catransform3dmakescale (cgfloat sx, cgfloat sy, cgfloat sz);
sx:x轴缩放,代表一个缩放比例,一般都是 0 --- 1 之间的数字。
sy:y轴缩放。
sz:整体比例变换时,也就是m11(sx)== m22(sy)时,若m33(sz)>1,图形整体缩小,若0<1,图形整体放大,若m33(sz)<0,发生关于原点的对称等比变换。
当sx = 1,sy = 1时。如图:

详解iOS的Core Animation框架中的CATransform3D图形变换

当sx = 0.5,sy = 0.5时。如图:

详解iOS的Core Animation框架中的CATransform3D图形变换

catransform3d catransform3dscale (catransform3d t, cgfloat sx, cgfloat sy, cgfloat sz)
t:就是上一个函数。其他的都一样。
就可以理解为:函数的叠加,效果的叠加。
catransform3d catransform3dmakerotation (cgfloat angle, cgfloat x, cgfloat y, cgfloat z);
旋转效果。
angle:旋转的弧度,所以要把角度转换成弧度:角度 * m_pi / 180。
x:向x轴方向旋转。值范围-1 --- 1之间
y:向y轴方向旋转。值范围-1 --- 1之间
z:向z轴方向旋转。值范围-1 --- 1之间
例:向x轴旋转60度。

详解iOS的Core Animation框架中的CATransform3D图形变换

向y轴旋转60度。

详解iOS的Core Animation框架中的CATransform3D图形变换

向z轴旋转60度。

详解iOS的Core Animation框架中的CATransform3D图形变换

向 x轴,y轴都旋转60度,就是沿着对角线旋转。

详解iOS的Core Animation框架中的CATransform3D图形变换
可以通过x,y,z轴同时变化,来旋转图像。
catransform3d catransform3drotate (catransform3d t, cgfloat angle, cgfloat x, cgfloat y, cgfloat z);
t:就是上一个函数。其他的都一样。
就可以理解为:函数的叠加,效果的叠加。
catransform3d catransform3dinvert (catransform3d t);
翻转效果。

详解iOS的Core Animation框架中的CATransform3D图形变换详解iOS的Core Animation框架中的CATransform3D图形变换

cgaffinetransform catransform3dgetaffinetransform (catransform3d t);
bool catransform3disaffine (catransform3d t);
仿射效果。
就是把一个 catransform3d 对象转换成一个 cgaffinetransform 对象。
也就是把 catransform3d 矩阵 转换成 cgaffinetransform 矩阵
变换函数同时提供了可以比较一个变换矩阵是否是单位矩阵,或者两个矩阵是否相等。
bool catransform3disidentity (catransform3d t);
bool catransform3dequaltotransform (catransform3d a, catransform3d b);
也可以通过修改数据结构和键值来设置变换效果。
struct catransform3d
               {

                 cgfloat m11, m12, m13, m14;

                           cgfloat m21, m22, m23, m24;

                           cgfloat m31, m32, m33, m34;

                                  cgfloat m41, m42, m43, m44;
}
可以直接修改 其中的一个值,来达到相同的效果。
或者修改键值
[mylayer setvalue:[nsnumber numberwithint:0] forkeypath:@"transform.rotation.x"];

二、catransform3d中的属性和方法
//初始化一个transform3d对象,不做任何变换
const catransform3d catransform3didentity;
//判断一个transform3d对象是否是初始化的对象
bool catransform3disidentity (catransform3d t);
//比较两个transform3d对象是否相同
bool catransform3dequaltotransform (catransform3d a, catransform3d b);
//将两个 transform3d对象变换属性进行叠加,返回一个新的transform3d对象
catransform3d catransform3dconcat (catransform3d a, catransform3d b);
1、平移变换
//返回一个平移变换的transform3d对象 tx,ty,tz对应x,y,z轴的平移
catransform3d catransform3dmaketranslation (cgfloat tx, cgfloat ty, cgfloat tz);
//在某个transform3d变换的基础上进行平移变换,t是上一个transform3d,其他参数同上
catransform3d catransform3dtranslate (catransform3d t, cgfloat tx, cgfloat ty, cgfloat tz);
例如:

    uiimageview * imageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 100, 100, 100)];
    imageview.image = [uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addsubview:imageview];
   
    uiimageview * newimageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 100, 100, 100)];
    newimageview.image=[uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addsubview:newimageview];
    catransform3d trans = catransform3dmaketranslation(10, 200, 0);
    newimageview.layer.transform =trans;
效果如下:

详解iOS的Core Animation框架中的CATransform3D图形变换

2、缩放变换
//x,y,z分别对应x轴,y轴,z轴的缩放比例
catransform3d catransform3dmakescale (cgfloat sx, cgfloat sy, cgfloat sz);
//在一个transform3d变换的基础上进行缩放变换,其他参数同上
catransform3d catransform3dscale (catransform3d t, cgfloat sx, cgfloat sy, cgfloat sz);
例如:
uiimageview * imageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 100, 100, 100)];
    imageview.image = [uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addsubview:imageview];
   
    uiimageview * newimageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 300, 100, 100)];
    newimageview.image=[uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addsubview:newimageview];
    catransform3d trans = catransform3dmakescale(2, 1, 1);
    newimageview.layer.transform =trans;
效果如下:

详解iOS的Core Animation框架中的CATransform3D图形变换

3、旋转变换
//angle参数是旋转的角度,为弧度制 0-2π
//x,y,z决定了旋转围绕的中轴,取值为-1——1之间,例如(1,0,0),则是绕x轴旋转(0.5,0.5,0),则是绕x轴与y轴中
//间45度为轴旋转,依次进行计算
catransform3d catransform3dmakerotation (cgfloat angle, cgfloat x, cgfloat y, cgfloat z);
//在一个transform3d的基础上进行旋转变换,其他参数如上
catransform3d catransform3drotate (catransform3d t, cgfloat angle, cgfloat x, cgfloat y, cgfloat z);
例如:
uiimageview * imageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 100, 100, 100)];
    imageview.image = [uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addsubview:imageview];
   
    uiimageview * newimageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 300, 100, 100)];
    newimageview.image=[uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addsubview:newimageview];
    catransform3d trans = catransform3dmakerotation(m_pi/2, 0, 0, 1);
    newimageview.layer.transform =trans;
效果如下:

详解iOS的Core Animation框架中的CATransform3D图形变换

另外,当我们有垂直于z轴的旋转分量时,设置m34的值可以增加透视效果,也可以理解为景深效果,例如:

    uiimageview * imageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 100, 100, 100)];
    imageview.image = [uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    imageview.layer.transform = catransform3dmakerotation(m_pi/4, 0, 1, 0);
    [self.view addsubview:imageview];
   
    uiimageview * newimageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 300, 100, 100)];
    newimageview.image=[uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addsubview:newimageview];
    catransform3d trans = catransform3didentity;
    trans.m34 = -1/100.0;
    trans = catransform3drotate(trans, m_pi/4, 0, 1, 0); 
    newimageview.layer.transform =trans;
两个imageview都进行了y轴的旋转变换,第二个有透视效果,第一个没有,运行如下:

详解iOS的Core Animation框架中的CATransform3D图形变换

4、旋转翻转变换
//将一个旋转的效果进行翻转
catransform3d catransform3dinvert (catransform3d t);
例如:
    uiimageview * imageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 100, 100, 100)];
    imageview.image = [uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    imageview.layer.transform = catransform3dmakerotation(m_pi/4, 0, 0, 1);
    [self.view addsubview:imageview];
   
    uiimageview * newimageview = [[uiimageview alloc]initwithframe:cgrectmake(100, 300, 100, 100)];
    newimageview.image=[uiimage imagenamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addsubview:newimageview];
    catransform3d trans = catransform3dmakerotation(m_pi/4, 0, 0, 1);
    trans = catransform3dinvert(trans);
   
    newimageview.layer.transform =trans;
5、catransform3d与cgaffinetransform的转换
cgaffinetransform是uikit框架中一个用于变换的矩阵,其作用与catransform类似,只是其可以直接作用于view,而不用作用于layer,这两个矩阵也可以进行转换,方法如下:
//将一个cgaffinrtransform转化为catransform3d
catransform3d catransform3dmakeaffinetransform (cgaffinetransform m);
//判断一个catransform3d是否可以转换为caaffinetransform
bool catransform3disaffine (catransform3d t);
//将catransform3d转换为cgaffinetransform
cgaffinetransform catransform3dgetaffinetransform (catransform3d t);