当前位置: 移动技术网 > 移动技术>移动开发>IOS > 详解iOS的Core Animation框架中的CATransform3D图形变换

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

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

201671191954573.png (152×150)

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

201671192029709.png (151×150)

对于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时。如图:

201671192103475.png (151×152)

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

201671192120345.png (152×154)

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度。

201671192143349.png (224×229)

向y轴旋转60度。

201671192202793.png (224×229)

向z轴旋转60度。

201671192545073.png (304×292)

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

201671192648071.png (227×226)
可以通过x,y,z轴同时变化,来旋转图像。
catransform3d catransform3drotate (catransform3d t, cgfloat angle, cgfloat x, cgfloat y, cgfloat z);
t:就是上一个函数。其他的都一样。
就可以理解为:函数的叠加,效果的叠加。
catransform3d catransform3dinvert (catransform3d t);
翻转效果。

201671192247252.png (304×292)201671192357331.png (292×287)

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;
效果如下:

201671192753788.png (206×383)

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;
效果如下:

201671192812038.png (212×378)

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;
效果如下:

201671192840809.png (210×395)

另外,当我们有垂直于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轴的旋转变换,第二个有透视效果,第一个没有,运行如下:

201671192903446.png (208×394)

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);

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网