iOS 旋转动画添加3D效果

本文 出处 参考   http://blog.sina.com.cn/s/blog_71715bf801019ut9.html  自己mark下

例子代码可以在 http://download.csdn.net/detail/p709723778/5034622 下载
 本文重点在改变CALayer默认使用的正交投影,去使用透视投影矩阵。
iOS的UI是基于UIView类的,我们能看到的每个UI元素都是UIView或者UIView的子类。View按树形结构组织起来,树根是UIWindow。

View负责界面的交互和显示,其中显示部分由CALayer来完成。每个UIView包含一个CALayer实例。可以这么认为,UIView本身是不可见的,我们能看到的都是CALayer,UIView只是负责对CALayer进行管理。

UIView的显示设置都是对CALayer属性的封装,但是这层封装掩盖了CALayer提供的3D显示功能。所以我们想让UIView显示3D的效果的话,需要直接操作CALayer。

要操作CALayer对象,首先要在工程中包含QuartzCore.framework,在文件中import 头文件。QuartzCore.framework中包含了CALayer以及CALayer一些官方子类的定义。

通过设置CALayer的transform属性,可以使CALayer产生3D空间内的平移、缩放、旋转等变化。

第一个例子:绕坐标轴的旋转

原始场景如图

 

使用 image.layer.transform = CATransform3DMakeRotation(M_PI/6, 0, 0, 1); 绕Z轴旋转30度后的效果

使用 image.layer.transform = CATransform3DMakeRotation(M_PI/6, 0, 1, 0); 绕Y轴旋转30度后的效果

使用 image.layer.transform = CATransform3DMakeRotation(M_PI/6, 1, 0, 0); 绕X轴旋转30度后的效果

能够发现,绕Z轴的旋转比较符合预期,但是绕X轴Y轴的旋转只是在Y轴X轴上进行了一些缩放而已。这是因为,在CALayer的显示系统中,默认的相机使用正交投影,正交投影没有远小近大效果,所以在本例中,只能造成相应轴上的缩放。

第二个例子:透视投影

CALayer默认使用正交投影,因此没有远小近大效果,而且没有明确的API可以使用透视投影矩阵。所幸可以通过矩阵连乘自己构造透视投影矩阵。构造透视投影矩阵的代码如下:
    CATransform3D CATransform3DMakePerspective(CGPoint center, float disZ)
    {
        CATransform3D transToCenter = CATransform3DMakeTranslation(-center.x, -center.y, 0);
        CATransform3D transBack = CATransform3DMakeTranslation(center.x, center.y, 0);
        CATransform3D scale = CATransform3DIdentity;
        scale.m34 = -1.0f/disZ;
        return CATransform3DConcat(CATransform3DConcat(transToCenter, scale), transBack);
    }

CATransform3D CATransform3DPerspect(CATransform3D t, CGPoint center, float disZ)
    {
        return CATransform3DConcat(t, CATransform3DMakePerspective(center, disZ));
    }

这个函数的实现原理要参考计算机图形学的3D变换部分,以后再做解释。现在只需要了解接口的含义,center指的是相机 的位置,相机的位置是相对于要进行变换的CALayer的来说的,原点是CALayer的anchorPoint在整个CALayer的位置,例如CALayer的大小是(100, 200), anchorPoint值为(0.5, 0.5),此时anchorPoint在整个CALayer中的位置就是(50, 100),正中心的位置。传入透视变换的相机位置为(0, 0),那么相机所在的位置相对于CALayer就是(50, 100)。如果希望相机在左上角,则需要传入(-50, -100)。disZ表示的是相机离z=0平面(也可以理解为屏幕)的距离。带透视效果的旋转,效果如下:


CATransform3D rotate = CATransform3DMakeRotation(M_PI/6, 1, 0, 0);
    image.layer.transform = CATransform3DPerspect(rotate, CGPointMake(0, 0), 200);

CATransform3D rotate = CATransform3DMakeRotation(M_PI/6, 0, 0, 1);
    image.layer.transform = CATransform3DPerspect(rotate, CGPointMake(0, 0), 200);

image的默认anchorPoint为(0.5,0.5),也就是在图片中心;眼睛在图片中心点,距屏幕200单位。可以观察到,因为翻转,使图片的不同部分离屏幕距离不同,近大远小的效果使立体感大大提升。饶Z轴的旋转不因为透视产生变化,因为所有的点离屏幕距离相同,所以不会产生近大远小的透视感。

第三个例子:更多的效果:

CALayer的旋转和缩放是绕anchorPoint点的,改变anchorPoint的值,可以使Layer绕不同的点而不只是中心点旋转缩放。在构造透视投影矩阵的例子中就可以看到,CATransform3D可以使用CATransform3DConcat函数连接起来以构造更复杂的变换。通过这些方法,可以组合出更多的效果来。下面是个翻转的动画。使用UITimer

- (void)update
    {
        static float angle = 0;
        angle += 0.05f;

CATransform3D transloate = CATransform3DMakeTranslation(0, 0, -200);
        CATransform3D rotate = CATransform3DMakeRotation(angle, 0, 1, 0);
        CATransform3D mat = CATransform3DConcat(rotate, transloate);
        image.layer.transform = CATransform3DPerspect(mat, CGPointMake(0, 0), 500);
    }

最后是两个更复杂的例子。第一个是使用四张同样大小的图片围成一个框,让这个框动画旋转。

CATransform3D move = CATransform3DMakeTranslation(0, 0, 160);
CATransform3D back = CATransform3DMakeTranslation(0, 0, -160);

CATransform3D rotate0 = CATransform3DMakeRotation(-angle, 0, 1, 0);
    CATransform3D rotate1 = CATransform3DMakeRotation(M_PI_2-angle, 0, 1, 0);
    CATransform3D rotate2 = CATransform3DMakeRotation(M_PI_2*2-angle, 0, 1, 0);
    CATransform3D rotate3 = CATransform3DMakeRotation(M_PI_2*3-angle, 0, 1, 0);

CATransform3D mat0 = CATransform3DConcat(CATransform3DConcat(move, rotate0), back);
CATransform3D mat1 = CATransform3DConcat(CATransform3DConcat(move, rotate1), back);
CATransform3D mat2 = CATransform3DConcat(CATransform3DConcat(move, rotate2), back);
CATransform3D mat3 = CATransform3DConcat(CATransform3DConcat(move, rotate3), back);

image0.layer.transform = CATransform3DPerspect(mat0, CGPointZero, 500);
image1.layer.transform = CATransform3DPerspect(mat1, CGPointZero, 500);
image2.layer.transform = CATransform3DPerspect(mat2, CGPointZero, 500);
image3.layer.transform = CATransform3DPerspect(mat3, CGPointZero, 500);

上面的例子都使用UIImage的CALayer,但CALayer产生的动画可以应用在所有的UIView及子类上,下面是个普通界面的立体翻转效果。

float dis = 160 * 1.732f;
CATransform3D move = CATransform3DMakeTranslation(0, 0, dis);
CATransform3D back = CATransform3DMakeTranslation(0, 0, -dis);

CATransform3D rotate0 = CATransform3DMakeRotation(-angle, 0, 1, 0);
    CATransform3D rotate1 = CATransform3DMakeRotation(-angle + M_PI/3.0f, 0, 1, 0);

CATransform3D mat0 = CATransform3DConcat(CATransform3DConcat(move, rotate0), back);
CATransform3D mat1 = CATransform3DConcat(CATransform3DConcat(move, rotate1), back);

view0.layer.transform = CATransform3DPerspect(mat0, CGPointZero, 500);
view1.layer.transform = CATransform3DPerspect(mat1, CGPointZero, 500);

时间: 2024-10-06 21:09:39

iOS 旋转动画添加3D效果的相关文章

CSS3 03. 3D变换、坐标系、透视perspective、transformZ、transform-style添加3D效果、backface-visibility元素背面可见、动画animation、@keyfarmes、多列布局

1.左手坐标系 伸出左手,让拇指和食指成"L"形,大拇指向右,食指向上,中指指向前方.这样我们就建立了一个左手坐标系,拇指.食指和中指分别代表X.Y.Z轴的正方向.如下图 CSS中的3D坐标系 CSS3中的3D坐标系与上述的3D坐标系是有一定区别的,相当于其绕着X轴旋转了180度,如下图 左手法则 左手握住旋转轴,竖起拇指指向旋转轴正方向,正向就是其余手指卷曲的方向. 透视 perspective perspective:400px: 电脑显示屏是一个2D平面,图像之所以具有立体感(3

视频特效制作:如何给视频添加边框、水印、动画以及3D效果

本文内容来自raywenderlich的这篇文章的翻译:AVFoundation Tutorial: Adding Overlays and Animations to Videos 这是我当年做视频大量参考的文章.写得非常好,建议看完我的这篇去看原文. 第一节:给视频添加边框 今天第一节先讲解如何为一个视频添加边框和动画,首先说明的是,这种边框和动画并不能直接修改视频的某一帧给他增加边框或者产生动画效果,这种动画更像是给视频的上面加一个calayer,然后控制这个layer产生动画效果.因为具

iOS --旋转动画

/** * 利用图片的layer添加到转盘上 * */ //指针的锚点 相对于自身,左上角为(0,0),右下角为(1,1) self.zhen.layer.anchorPoint = CGPointMake(0.5,1); NSLog(@"%@",NSStringFromCGPoint(self.zhen.layer.anchorPoint)); //position相对于父视图的位置 self.zhen.layer.position = CGPointMake(self.pan.bo

Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)

Silverlight的基础动画包括偏移.旋转.缩放.倾斜和翻转动画,这些基础动画毫无疑问是在Silverlight中使用得最多的动画效果,其使用也是非常简单的.相信看过上一篇<偏移动画(TranslateTransform)>文章的朋友大多数对Silverlight & Blend动画设计已经产生了莫大的兴趣,本篇将继续介绍Silverlight中的基础动画之旋转动画(RotateTransform). 所谓旋转动画(RotateTransform)也就是一个元素以一个坐标点为旋转中

iOS简单动画效果:闪烁、移动、旋转、路径、组合

#define kDegreesToRadian(x) (M_PI * (x) / 180.0) #define kRadianToDegrees(radian) (radian*180.0)/(M_PI) - (void)viewDidLoad { [superviewDidLoad]; self.title = @"测试动画"; self.view.backgroundColor = [UIColorlightGrayColor]; myTest1 = [[UILabelalloc

HTML5 CSS3 诱人的实例: 3D立方体旋转动画DEMO

创意来自:http://www.html5tricks.com/demo/html5-3d-cube/index.html , 同学给我发的例子,感觉很不错,不过实在想不出来实际的用处,但是效果很炫~ 效果图: 知识点: 1.perspective ,transform 的复习 2.css3 backgroud实现格格背景,即面上的小格格 3. @-webkit-keyframes 实现动画 HTML: <body> <div class="stage"> &l

css3 3d效果及动画学习

css参考手册: http://www.phpstudy.net/css3/ http://www.css88.com/book/css/ 呈现3d效果:-webkit-transform-style:preserve-3d; 透视距离:-wenkit-perspective:300; 视角:-webkit-perspective-origin:25% 75%:/*数字正负均可*/ 旋转和变换:transform: translatex(-90px) translatez(90px) rotat

iOS开发——图形编程OC篇&amp;粘性动画以及果冻效果

粘性动画以及果冻效果 在最近做个一个自定义PageControl——KYAnimatedPageControl中,我实现了CALayer的形变动画以及CALayer的弹性动画,效果先过目: 先做个提纲: 第一个分享的主题是“如何让CALayer发生形变”,这个技术在我之前一个项目 ———— KYCuteView 中有涉及,也写了篇简短的实现原理博文.今天再举一个例子. 之前我也做过类似果冻效果的弹性动画,比如这个项目—— KYGooeyMenu. 用到的核心技术是CAKeyframeAnimat

iOS 特定图片的按钮的旋转动画

最近做的东西中,要为一个有特定图片的按钮添加旋转动画,Demo代码如下: #import "ViewController.h" @interface ViewController () { BOOL flag; } @property (strong, nonatomic) UIImageView *imageView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; flag