2.进行旋转
某次旋转的核心变换:(重点理解两次变换,为什么要这么变?需要一定的空间几何思维)
CGFloat radius = DEGREE_TO_RADIUS(90*(float)(count - 1 - index)/(float)(count -1));//计算旋转的角度;其中count是旋转路径节点数目,index是第几个节点 (一共旋转90度)
CATransform3D transform3d = CATransform3DMakeTranslation(0, -r*sinf(radius), -r*(1-cosf(radius)));//计算偏移矩(表示在Y轴上偏移量为-r*sinf(radius),Z轴上为后者)
transform3d = CATransform3DRotate(transform3d, radius, 1.f, 0, 0);//在上述基础上计算旋转矩阵
NSValue *value = [NSValue valueWithCATransform3D:transform3d];
[values addObject:value];//将矩阵值加入路径中
if (index > 0) {
[timingFunctions addObject:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];//将时间控制加入
NOTE:CATransform3DRotate()方法制造旋转矩阵,控制旋转角度和方向。这里有一个诀窍就是向量值某个坐标值的正负影响向量的指向方向也影响视图的旋转方向。
创建路径:
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:keyPath];
NSMutableArray *values = [NSMutableArray array]; //矩阵表示的路径
NSMutableArray *timingFunctions = [NSMutableArray array];//对应的时间控制
for (int i = 0; i
{
//执行上面的代码快
}
animation.values = values;
animation.timingFunctions = timingFunctions;
animation.duration = duration;
3.至此,路径创建成功,最难的部分已经过去。继续我们的旅程:
创建 CAAnimationGroup :
CAAnimationGroup *cubicAnimation = [CAAnimationGroup animation];
cubicAnimation.duration = duration;
cubicAnimation.delegate = delegate;
cubicAnimation.animations = [NSArray arrayWithObjects:transform,nil]; //transform就是上一个部分我们辛苦创造的CAKeyframeAnimation *animation
4.组装,实现动画
CATransform3D transform = CATransform3DIdentity;
[self.layer setSublayerTransform:transform]; //还原3D设置(没有试过不还原,官方要求必须还原)
[CATransaction begin];
[CATransaction setAnimationDuration:duration]; //设置动画运行时长
[CATransaction setCompletionBlock:completionBlock]; //完成后执行的动作
[subViewIn.layer addAnimation:inAnimation forKey:@"cubeIn"]; //在层里加入动画,系统会自动将他开始
[CATransaction commit];
5.重要:最后的最后,黎明前总是最黑暗的时刻,这次也不例外。我们所做的只是将一个面转了一下,要想形成立方体效果,我们还得把另外的面跟着做对应旋转。晕了吧,慢慢回来,再苦逼的做一遍工作吧。不过幸好我们有电脑帮我们做那些烦人的重复的事情,写个函数体,copy,修改参数值,OK!
第四部分
CATransform3D myTransform;
myTransform = CATransform3DMakeRotation(angle, x, y, z);
该CATransform3DMakeRotation函数创建了一个转变,将在三维轴坐标系以任意弧度旋转层。x-y-z轴的有个确定的范围(介于-1 和+1之间) 。相应的坐标轴指定的值告诉系统在该轴上旋转。例如,如果X轴是设置为-1或1 ,该对象将的X轴的方向上旋转,这意味着将把它垂直旋转。把这些值看做是插入在图像每个坐标轴上的秸秆(Think of these values as inserting straws through the image for each axis.)。如果秸秆插过x轴,图像将沿着秸秆垂直旋转。您可以使用坐标轴角度值创建更复杂的旋转。。对于大多数的用途,但是,值介于-1和+1已经足够。
要水平(垂直)旋转45度,您可以使用下面的代码:
myTransform = CATransform3DMakeRotation(0.78, 1.0, 0.0, 0.0);
要在Y轴上旋转相同的值:
myTransform = CATransform3DMakeRotation(0.78, 0.0, 1.0, 0.0);
0.78 ,用在前面的例子,是由角度值经计算转化为弧度值。要把角度值转化为弧度值,可以使用一个简单的公式Mπ/180 。例如, 45π/180 = 45 ( 3.1415 ) / 180 = 0.7853 。如果你打算在你的程序里面一直都用角度值的话,你可以写一个简单的转化方法,以帮助保持您的代码是可以理解的:
double radians(float degrees) {
return ( degrees * 3.14159265 ) / 180.0;
}
当你创建一个转换的时候,你将要调用这个方法:
myTransform = CATransform3DMakeRotation(radians(45.0), 0.0, 1.0, 0.0);
当变换(transformation)被创建好了以后,应用在你正在操作的层上。CALayer对象提供了一个transform属性来连接转换。层将执行分配给transform属性的转换:
imageView.layer.transform = myTransform;
当对象被显示后,将会显示应用到它的转换效果。在你的代码中,你任然把它当做是个2D对象。但是它根据提供的转换类型来渲染。