iOS 动画Animation-4-5: CALayer子类:CATransformLayer

来源:互联网 发布:vr软件app排行榜 编辑:程序博客网 时间:2024/05/17 07:10

首先说明:这是一系列文章,参考本专题下其他的文章有助于你对本文的理解。

今天周六,希望大家都有一个愉快的周末。
今天来讲解一下CATransformLayer:CATransformLayer是一个专门用来创建三维视图的一个layer,也可以说是多个layer的集合。他没有多余的API,可以这么说,他只是承载了子layer。

下面就看一个例子,通过例子来讲解。

国际惯例先上图:
这里写图片描述

图就是这样的纯手工打造。
先创建一个CATransformLayer对象:

var transformLayer = CATransformLayer()transformLayer.frame = someView.boundssomeView.layer.addSublayer(transformLayer)

这个没有任何技术含量。同样someView为我用storyboard创建的一个view

然后创建他的子layer,将layer添加到transformLayer上

var layer = sideLayerWithColor(redColor)transformLayer.addSublayer(layer)layer = sideLayerWithColor(orangeColor)var transform = CATransform3DMakeTranslation(sideLength / 2, 0.0, sideLength / -2)transform = CATransform3DRotate(transform, degreesToRadians(90.0), 0.0, 1.0, 0.0)layer.transform = transformtransformLayer.addSublayer(layer)layer = sideLayerWithColor(yellowColor)layer.transform = CATransform3DMakeTranslation(0.0, 0.0, -sideLength)transformLayer.addSublayer(layer)layer  = sideLayerWithColor(greenColor)transform = CATransform3DMakeTranslation(sideLength / -2, 0.0, sideLength / -2)transform = CATransform3DRotate(transform, degreesToRadians(90.0), 0.0, 1.0, 0.0)layer.transform = transformtransformLayer.addSublayer(layer)layer = sideLayerWithColor(blueColor)transform = CATransform3DTranslate(transform, 0.0, sideLength / -2, sideLength / 2)transform = CATransform3DRotate(transform, degreesToRadians(90.0), 1.0, 0.0, 0.0)layer.transform = transformtransformLayer.addSublayer(layer)layer = sideLayerWithColor(purpleColor)transform = CATransform3DMakeTranslation(0.0, sideLength / 2.0, sideLength / -2.0)transform = CATransform3DRotate(transform, degreesToRadians(90.0), 1.0, 0.0, 0.0)layer.transform = transformtransformLayer.addSublayer(layer)transformLayer.anchorPointZ = sideLength / -2.0
  • 解释:
    可以看到代码分为六块,这分别是创建一个立方体的六个面。不外乎都是根据第一个做了下旋转和平移(如果有对这个不太理解的请看:iOS 动画Animation-3: CATransform3D 特效详解)
    再说到:sideLayerWithColor(purpleColor)这是什么鬼?
    不要急,这是为了方便写的一个创建layer的方法,内容如下
func sideLayerWithColor(color: UIColor) -> CALayer {    let layer = CALayer()    layer.frame = CGRect(origin: CGPointZero, size:   CGSize(width: sideLength, height: sideLength))    layer.backgroundColor = color.CGColor    return layer}

还有一个:degreesToRadians(),这个是转换角度,看上去更方便也更顺眼。

func degreesToRadians(degrees: Double) -> CGFloat {    return CGFloat(degrees * M_PI / 180.0)}

括号内的参数分别是我定义的颜色来区分每个面的颜色不同

var redColor = UIColor.redColor()var orangeColor = UIColor.orangeColor()var yellowColor = UIColor.yellowColor()var greenColor = UIColor.grayColor()var purpleColor = UIColor.purpleColor()var blueColor = UIColor.blueColor()

最后一行设置锚点,将锚点设置为立方体的中心

现在一个立方体已经做好了,但是运行之后看到的仍然是平面,因为这个立方体是正对着屏幕,其他面都被遮挡了。

下面就写个方法让他旋转角度

func applyRoationForXOffset(xOffset: Double, yOffset: Double){    let totalOffset = sqrt(xOffset * xOffset + yOffset * yOffset)    let totalRotation = CGFloat(totalOffset * M_PI / 180.0)    let xRotationalFactor = CGFloat(xOffset) / totalRotation    let yRotationalFactor = CGFloat(yOffset) / totalRotation    let currentTransform = CATransform3DTranslate(transformLayer.sublayerTransform, 0.0, 0.0, 0.0)    let rotationTransform = CATransform3DRotate(transformLayer.sublayerTransform, totalRotation, xRotationalFactor * currentTransform.m12 - yRotationalFactor * currentTransform.m11,  xRotationalFactor * currentTransform.m22 - yRotationalFactor * currentTransform.m21, xRotationalFactor * currentTransform.m32 - yRotationalFactor * currentTransform.m31)    print(currentTransform.m12, currentTransform.m11)    transformLayer.sublayerTransform = rotationTransform    }
  • 解释
    第一个函数是求平方和然后开根,算出直线距离,
    CGFloat(totalOffset * M_PI / 180.0)是将移动距离转回为角度
    初始化Transform
    关于矩阵变换不懂得也请参考:iOS 动画Animation-3: CATransform3D 特效详解)
    然后在适当的地方调用这个方法,(就是在添加完所有的子layer后)

给参数设定值之后就可以看到一个有立体效果的立方体了,
下面就开始让这个立方体动起来,
手势的操作,当然少不了touchBegan和touchMoved了。

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {    let touch: UITouch = touches.first!    startPoint = touch.locationInView(someView)}override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {    let touch: UITouch = touches.first!    let currentPoint = touch.locationInView(someView)    let deltaX = currentPoint.x - startPoint.x    let deltaY = currentPoint.y - startPoint.y    applyRoationForXOffset(Double(deltaX), yOffset: Double(deltaY))    startPoint = touch.locationInView(someView)}
  • 解释
    在touchBegan的时候记录下手指开始位置(startPoint)
    在touchMoved的时候记录下手指当前的位置(currentPoint)
    然后通过计算的到x轴和y轴移动的距离
    调用让立方体旋转的方法:applyRoationForXOffset(Double(deltaX), yOffset: Double(deltaY))
    并且要及时的更新(startPoint)。
    好了,相信如上图的效果也出来了,在这里放上自己做的Demo,以便还不是很懂的童鞋参考一下。

对CALayer子类的介绍也告一段落了,但是不代表动画的介绍就结束了,还没呢!继续关注吧!

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 很害怕一件事怎么办 高中老师误会我怎么办 家长讹老师老师怎么办 小孩子老说头疼怎么办 孩子总是否定自己怎么办 孩子总是否定别人怎么办 老师屏蔽家长该怎么办 初二学生学疲劳怎么办 孩子不愿补英语怎么办 培训班孩子不学怎么办 小孩不想去学校怎么办 讨厌父母的性格怎么办 老师揪孩子耳朵怎么办 老师整天骂孩子怎么办 教师被学生骂怎么办 幼儿园学生骂老师怎么办 学生骂老师外号怎么办 小孩上课很多嘴怎么办 学生老玩手机怎么办 和校长有了矛盾怎么办 家长打了我怎么办 小朋友不想去幼儿园怎么办 小朋友不想上幼儿园怎么办 高中老师打学生家长怎么办 老师偏心学生该怎么办? 老师能打孩子怎么办 有的幼儿打老师怎么办? 孩子特别怕老师怎么办 孩子跟老师认生怎么办 和搭班老师不合怎么办 学生厌学了老师怎么办 孩子很怕我怎么办 斗米报名之后怎么办 孩子鼻子长疮怎么办 六年级孩子不爱学习怎么办 孩子不要爱学习怎么办? 孩子说不愿意读书怎么办 孩子三天没吃饭怎么办 孩子三天不吃饭怎么办 初中学生不爱学习怎么办 孩子写字头歪怎么办