CGAffineTransform和CATransform3D
上周没有分享,因为上周放假,哈哈哈哈哈哈哈~~!!!!!! 这周本来是想分享CAShapeLayer CATextLayer CATransformLayer这些Layer的子类的,但是我发现后面做变化的时候可能会用到今天的这个东西,就先拿出来说一下.
一.CGAffineTransform 仿射变换
CG(CoreGraphics框架) Affine(仿射) Transform(变化) 可想而知CGAffineTransform是CoreGraphics框架提供的一个类.UIView有一个transform的属性,这个属性的类型就是CGAffineTransform类型,用于在二维空间做旋转,缩放和平移.而CGAffineTransform是一个可以和二维空间向量(例如CGPoint)做乘法的3X2的矩阵,layer的affineTransform的属性也是CGAffineTransform.
1.1如上图,用CGPoint的每一列和CGAffineTransform矩阵的每一行对应元素相乘再求和,就形成了一个新的CGPoint类型的结果.要解释一下图中显示的灰色元素,为了能让矩阵做乘法,左边矩阵的列数一定要和右边矩阵的行数个数相同,所以要给矩阵填充一些标志值,使得既可以让矩阵做乘法,又不改变运算结果,并且没必要存储这些添加的值,因为它们的值不会发生变化,但是要用来做运算.
简单的仿射变换:
CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
混合仿射变化:
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
创建一个CGAffineTransform类型的空值,矩阵论中称作单位矩阵,Core Graphics同样提供了一个方便的常量:
CGAffineTransformIdentity
最后,如果需要混合两个已经存在的变换矩阵,就可以使用如下方法,在两个变换的基础上创建一个新的变换
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);
接下来上代码
/**
*
CGAffineTransform,属于CoreGraphics框架中的一个类.
UIView有一个transform的属性,这个属性的类型就是CGAffineTransform类型,用于在二维空间做旋转,缩放和平移.CGAffineTransform是一个可以和二维空间向量(例如CGPoint)做乘法的3X2的矩阵,layer的affineTransform的属性也是CGAffineTransform.
简单仿射变化:
CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
混合仿射变化:
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
*/
@interface ViewController ()
@end
@implementation ViewController
-(UIView *)getTest{
UIView *view = [[UIView alloc]init];
view = [[UIView alloc]init];
view.backgroundColor = [UIColor cyanColor];
return view;
}
- (void)viewDidLoad {
[super viewDidLoad];
//view简单仿射变换
UIView *testV1 = [self getTest];
testV1.frame = CGRectMake(100, 50, 100, 100);
[self.view addSubview:testV1];
testV1.transform = CGAffineTransformMakeRotation(M_PI_4);
//layer简单仿射变换
UIView *testV2 = [self getTest];
testV2.frame = CGRectMake(100, 200, 100, 100);
[self.view addSubview:testV2];
testV2.layer.affineTransform = CGAffineTransformMakeRotation(M_PI_4);
//混合仿射变化
//创建一个CGAffineTransform类型的空值,矩阵论中称作单位矩阵,CoreGraphics同样提供了一个方便的常量 CGAffineTransformIdentity
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformScale(transform, 0.5, 0.5);
transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);
transform = CGAffineTransformTranslate(transform, 200, 0);
UIView *testV3 = [self getTest];
testV3.frame = CGRectMake(100, 350, 100, 100);
[self.view addSubview:testV3];
testV3.transform = transform;
}
二. CATransform3D 3D变换
CATransform3D属于CoreAnimation框架的一个类.可以用来让图层靠近或者远离相机(用户视角),transform属性(CATransform3D类型)可以真正做到这点,即让图层在3D空间内移动或者旋转.和CGAffineTransform类似,CATransform3D也是一个矩阵,但是和2x3的矩阵不同,CATransform3D是一个可以在3维空间内做变换的4x4的矩阵.
2.1和CGAffineTransform矩阵类似,Core Animation提供了一系列的方法用来创建和组合CATransform3D类型的矩阵,但是3D的平移和旋转多处了一个z参数,并且旋转函数除了angle之外多出了x,y,z三个参数,分别决定了每个坐标轴方向上的旋转
CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz)
CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)
m34
CATransform3D的m34元素,用来做透视m34的默认值是0,我们可以通过设置m34为-1.0 / d来应用透视效果,d代表了想象中视角相机和屏幕之间的距离,以像素为单位实际上并不需要,大概估算一个就好了.因为视角相机实际上并不存在,所以可以根据屏幕上的显示效果自由决定它的防止的位置.通常500-1000就已经很好了,但对于特定的图层有时候更小后者更大的值会看起来更舒服,减少距离的值会增强透视效果,所以一个非常微小的值会让它看起来更加失真,然而一个非常大的值会让它基本失去透视效果.
继续上代码
-(UIView *)getTest{
UIView *view = [[UIView alloc]init];
view = [[UIView alloc]init];
view.backgroundColor = [UIColor cyanColor];
return view;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIView *test1 = [self getTest];
test1.frame = CGRectMake(100, 100, 100, 100);
[self.view addSubview:test1];
CATransform3D transform = CATransform3DIdentity;
transform.m34 = - 1.0 / 500.0;
transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
test1.layer.transform = transform;
}