iOS在图层上使用CATransform3D制做三维动画

时隔三天后,各位终于等到我的简书更新了.今天我的主题是如何在图层上实现三维变形.

在UIView上,我们可以使用CGAffineTransform来对视图进行:平移(translation),旋转(Rotation),缩放(scale),倾斜(Invert)操作,但这些操作是没有动态立体效果的, 这只能称为二维变形.而在图层中,我们可以使用CATransform3D进行"视角旋转"来完成三维变形的效果,但这常称为2.5D,而非真正意义上的3D,因为他不能让图层真正成为三维对象,而只是模拟出三维的动画效果.

请看三维动画效果:


下面我就来一步一步的来实现它.
1.从图中的显示效果来看,我们需要创建六个图层,来表示一个立体图形六个不同的面.并且创建一个CATransformLayer类来作为容器:

/**底部容器*/
@property (nonatomic,strong) CATransformLayer *contentLayer;
/**上面*/
@property (nonatomic,strong) CALayer *topLayer;
/**下面*/
@property (nonatomic,strong) CALayer *bottomLayer;
/**左面*/
@property (nonatomic,strong) CALayer *leftLayer;
/**右面*/
@property (nonatomic,strong) CALayer *rightLayer;
/**前面*/
@property (nonatomic,strong) CALayer *frontLayer;
/**后面*/
@property (nonatomic,strong) CALayer *backLayer;

通常情况下,像这种批量创建对象的工作,不要做傻傻的码农,要学会封装,这样我们只需要传入图层所必须的变量参数就可以创建一个图层了.

- (CALayer *)layerAtX:(CGFloat)x y:(CGFloat)y z:(CGFloat)z color:(UIColor *)color transform:(CATransform3D)transform{
    
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = color.CGColor;
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.position = CGPointMake(x, y);
    layer.zPosition = z;
    layer.transform = transform;
    [self.contentLayer addSublayer:layer];
    
    return layer;
}

其中,我要说一下上面代码中layer的zPosition与transfrom属性,在这个例子中,我会使用CATransformLayer类,这个类是CALayer的子类,在官方文档上有一句话是这么描述的"CATransformlayer objects are used to create sure 3D layer hierarchies".那他到底和CALayer有什么区别呢?是这样的.在CALayer中的zPosition属性,如果只使用CALayer,那么zPosition只能用于计算图层的显示顺序,这样会使图形看起来是扁平的.而在CATransformLayer这个类当中,zPosition就可以用来决定空间位置.他会让图形的position不限于X,Y轴上,也可以在Z轴上设置相应值来让图形添加景深,从而让图形具有立体效果.所以,x,y,z分别是X轴,Y轴,Z轴方向的值.

下面说说本文的核心部分:CALayer的transfrom属性:这个属性主要是操作CATranfrom3D类对图层进行三维变形.在我们这个例子中,主要是对图层进行旋转,所以着重讲一下CATranfrom3D类当中进行3D旋转的方法:

CA_EXTERN CATransform3D CATransform3DMakeRotation (CGFloat angle, CGFloat x,
    CGFloat y, CGFloat z)

可以看出来,这是一个c语言封装好的函数,里面的参数我来说明:第一个参数:里面的角度是图层需要旋转的角度,是以弧度为单位,我列举一下几个常用的:M_PI是表示180度,M_PI_2表示90度,M_PI_4表示45度.后面的三个参数x,y,z:我们知道,在二维形变中,旋转效果是围绕着一个点进行变化的,而在三维变化中,却是围绕着一条轴.而这三个参数在立体平面中的坐标系中确定一个点,这个点与圆点(左上角)的连线确定一条轴,我举一个特殊的例子:比如绕着y轴旋转45度?绕着y轴旋转,那么必然这三个参数确定的点在Y轴上,在Y轴上,那么其他值必然为0,所以里面的参数应该这样填:CATransform3DMakeRotation (M_PI_4, 0, 1, 0);

好了,那么现在初始化CATransformLayer,然后将六个图层添加到这个容器中.

    // 创建CATransformLayer对象
    CATransformLayer *contentLayer = [CATransformLayer layer];
    contentLayer.frame =self.view.layer.bounds;
    CGSize size = contentLayer.bounds.size;
    contentLayer.transform = CATransform3DMakeTranslation(size.width / 2, size.height / 2, 0);
    self.contentLayer = contentLayer;
    [self.view.layer addSublayer:contentLayer];
// 初始化六个图层
    // 顶部与底部的沿着x轴旋转90度
    self.topLayer = [self layerAtX:0 y:-kSize/2  z:0 color:[UIColor redColor] transform:CATransform3DMakeRotation(M_PI_2, 1, 0, 0)];
    
    self.bottomLayer = [self layerAtX:0 y:kSize/2 z:0 color:[UIColor greenColor] transform:CATransform3DMakeRotation(M_PI_2, 1, 0, 0)];
    // 左边与右边的沿着y轴旋转90度
    self.leftLayer = [self layerAtX:-kSize / 2 y:0 z:0 color:[UIColor blueColor] transform:CATransform3DMakeRotation(M_PI_2, 0, 1, 0)];
    
    self.rightLayer = [self layerAtX:kSize/2 y:0 z:0 color:[UIColor blackColor] transform:CATransform3DMakeRotation(M_PI_2, 0, 1, 0)];
    
    // 前面与后面的不需要变化,所以使用CATransform3DIdentity
    self.frontLayer = [self layerAtX:0 y:0 z:kSize / 2 color:[UIColor brownColor] transform:CATransform3DIdentity];
    
    self.backLayer = [self layerAtX:0 y:0 z:-kSize / 2 color:[UIColor brownColor] transform:CATransform3DIdentity];

说明一点:kSize 是我定义的一个宏,表示的是这个正方体的边长.
现在的视图上显示的是什么效果呢



为什么只显示前面图层给的brownColor呢?这就是对的,由于旋转90度后,上下与左右都收在前面图层的四侧,与视图垂直,所以我们看不到,那么我就给一个pan手势,随着手指的移动,旋转这个立体图形.

- (void)pan:(UIPanGestureRecognizer *)recognizer{
   //获取到的是手指移动后,在相对坐标中的偏移量(以手指接触屏幕的第一个点为坐标原点)
    CGPoint translation = [recognizer translationInView:self.view];
    CATransform3D transform = CATransform3DIdentity;
    transform = CATransform3DRotate(transform, translation.x * 1 / 100, 0, 1, 0);
    transform = CATransform3DRotate(transform, translation.y * - 1 / 100, 1, 0, 0);
    self.view.layer.sublayerTransform = transform;
    
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,176评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,928评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 171,252评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,700评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,717评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,231评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,608评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,572评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,117评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,137评论 3 344
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,280评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,908评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,597评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,067评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,202评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,784评论 3 380
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,308评论 2 365

推荐阅读更多精彩内容

  • Core Animation其实是一个令人误解的命名。你可能认为它只是用来做动画的,但实际上它是从一个叫做Laye...
    小猫仔阅读 3,731评论 1 4
  • 转载:http://www.jianshu.com/p/32fcadd12108 每个UIView有一个伙伴称为l...
    F麦子阅读 6,226评论 0 13
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,123评论 5 13
  • 一共上了5节大学生心理委员培训课收获颇多,感触颇深。 原先我并不懂大学为什么还要创立一个心理委员,认为这是多此一举...
    509405ae8d53阅读 502评论 0 0
  • 家,家是什么?家是有个保护的盖子,下面代表猪,就是有肉吃。 如果这个家,不能挡风雨没有安全感,没有...
    胡长溪阅读 508评论 1 2