CATransformLayer(正方体)

当我们在构造复杂的3D事物的时候,如果能够组织独立元素就太方便了。比如说,你想创造一个孩子的手臂:你就需要确定哪一部分是孩子的手腕,哪一部分是孩子的前臂,哪一部分是孩子的肘,哪一部分是孩子的上臂,哪一部分是孩子的肩膀等等。

当然是允许独立地移动每个区域的啦。以肘为指点会移动前臂和手,而不是肩膀。Core Animation图层很容易就可以让你在2D环境下做出这样的层级体系下的变换,但是3D情况下就不太可能,因为所有的图层都把他的孩子都平面化到一个场景中

CATransformLayer解决了这个问题,CATransformLayer不同于普通的CALayer,因为它不能显示它自己的内容。只有当存在了一个能作用域子图层的变换它才真正存在。CATransformLayer并不平面化它的子图层,所以它能够用于构造一个层级的3D结构

gitHub地址在transform/TransformLayer里面

为了作对比,这里先用UIView来实现一个正方体。下面是代码:
首先用Interface Builder布局正方体的六个面,如图:


正方体的六个面

然后将这六个正方体的面添加到

@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *faces;

中。
在3号上面添加了一个按钮,添加按钮方法:

  • (IBAction)click:(UIButton *)sender;

.m中代码:

//将正方体的六个面添加到self.view上,并创建face.layer的transform
- (void)addFace:(NSInteger)index withTransform:(CATransform3D)transform{
    //get the face view and add it to the container”
    UIView * face = self.faces[index];
//如果添加face的时候,3号不是最后添加的话,则button的按钮点击事件会被拦截,虽然变换了位置;可以设置其他界面的userInteractionEnabled为NO;或者最后一个添加3号视图
//    if (index != 2) {
//        face.userInteractionEnabled = NO;
//    }
    [self.view addSubview:face];
    //center the face view within the container
    CGSize containerSize = self.view.bounds.size;
    face.center = CGPointMake(containerSize.width/2, containerSize.height/2);
    //apply the transfrom
    face.layer.transform = transform;
    face.layer.borderWidth = .5;
}

接下来就是设置六个面的transform:

//设置正方体的六个面的transform
-(void)transforms{
    /**
     *ios上坐标系规则为:x轴右边为正,y轴下边为正,z轴前面为正
     */
    //add cube face 1(正方体前面)
    CATransform3D transform = CATransform3DMakeTranslation(0, 0, kLength);
    [self addFace:0 withTransform:transform];
    //add cube face 2(正方体右面)
    transform = CATransform3DMakeTranslation(kLength, 0, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
    [self addFace:1 withTransform:transform];
    //add cube face 4(正方体下面)
    transform = CATransform3DMakeTranslation(0, kLength, 0);
    transform = CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);
    [self addFace:3 withTransform:transform];
    //add cube face 5(正方体左边)
    transform = CATransform3DMakeTranslation(-kLength, 0, 0);
    transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
    [self addFace:4 withTransform:transform];
    //add cube face 6(正方体后面)
    transform = CATransform3DMakeTranslation(0, 0, -kLength);
    transform = CATransform3DRotate(transform, M_PI, 0, 1, 0);
    [self addFace:5 withTransform:transform];
    //add cube face 3(正方体上面)
    transform = CATransform3DMakeTranslation(0, -kLength, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 1, 0, 0);
    [self addFace:2 withTransform:transform];
}

调用

[self transforms];

实现效果为:


正方体1

如图所示,根本看不出来是一个正方体,所以下面要对self.view.layer的perspective变换矩阵

    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1.0/500.0;
////    //绕着X轴向左旋转45度
    perspective = CATransform3DRotate(perspective, -M_PI_4, 1, 0, 0);
////    //绕着Y轴向下旋转45度
    perspective = CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0);
    self.view.layer.sublayerTransform = perspective;

显示效果:


正方体2

这个是通过view改变layer的transform来显示正方体的。

2、通过CATransformLayer来实现正方体

//创建layer并设置背景色和transform
-(CALayer *)faceWithTransform:(CATransform3D)transform{
    CALayer * face = [CALayer layer];
    face.frame = CGRectMake(-50, -50, 100, 100);
    CGFloat red = (rand()/(double)INT_MAX);
    CGFloat green = (rand()/(double)INT_MAX);
    CGFloat blue = (rand()/(double)INT_MAX);
    face.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1].CGColor;
    face.transform = transform;
    return face;
}

//创建transformLayer,并添加layer
-(CALayer*)cubeWithTransform:(CATransform3D)transform{
    //create cube layer
    CATransformLayer * cube = [CATransformLayer layer];
    //add cube face 1,Z轴位移50
    CATransform3D ct = CATransform3DMakeTranslation(0, 0, 50);
    [cube addSublayer:[self faceWithTransform:ct]];
    //add cube face 2,Z轴位移-50,Y轴旋转M_PI
    ct = CATransform3DMakeTranslation(0, 0, -50);
    ct = CATransform3DRotate(ct, M_PI, 0, 1, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    //add cube face 3,X轴位移50,Y轴旋转M_PI_2
    ct = CATransform3DMakeTranslation(50, 0, 0);
    ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    //add cube face 4,X轴位移-50,Y轴旋转-M_PI_2
    ct = CATransform3DMakeTranslation(-50, 0, 0);
    ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    //add cube face 5,Y轴位移50,X轴旋转M_PI_2
    ct = CATransform3DMakeTranslation(0, 50, 0);
    ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    //add cube face 6,Y轴位移-50,X轴旋转-M_PI_2
    ct = CATransform3DMakeTranslation(0, -50, 0);
    ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    
    CGSize containerSize = self.view.bounds.size;
    cube.position = CGPointMake(containerSize.width/2.0, containerSize.height/2.0);
    cube.transform = transform;
    return cube;
}

调用:

//    CATransformLayer
//    创建第一个cube
    CATransform3D ct1 = CATransform3DIdentity;
    //x轴位移
    ct1 = CATransform3DTranslate(ct1, -100, 0, 0);
    //创建cube的六个面
    CALayer * cube1 = [self cubeWithTransform:ct1];
    [self.view.layer addSublayer:cube1];
    
//    创建第二个cube
    CATransform3D ct2 = CATransform3DIdentity;
    //x轴平移100
    ct2 = CATransform3DTranslate(ct2, 100, 0, 0);
    //绕着X轴旋转-45
    ct2 = CATransform3DRotate(ct2, -M_PI_4, 1, 0, 0);
    //绕着Y轴旋转-45
    ct2 = CATransform3DRotate(ct2, -M_PI_4, 0, 1, 0);
    CALayer * cube2 = [self cubeWithTransform:ct2];
    [self.view.layer addSublayer:cube2];

显示效果:


正方体3

你可能感兴趣的:(CATransformLayer(正方体))