# 实现3D旋转效果的方法

Android中有一种旋转效果，是将一个图片进行360度的旋转。

Matrix的作用是对平面上的View进行缩放、平移、旋转，每一种操作都配了setXXX、preXXX、postXXX三个函数。

Camera不是物理摄像头，是android.graphic下的一个类，相当于手机的屏幕，他的坐标系是带有Z坐标的。

Android APIDemos中已经提供了一种例子

 1 /**
2  * An animation that rotates the view on the Y axis between two specified angles.
3  * This animation also adds a translation on the Z axis (depth) to improve the effect.
4  */
5 public class Rotate3dAnimation extends Animation {
6     private final float mFromDegrees;
7     private final float mToDegrees;
8     private final float mCenterX;
9     private final float mCenterY;
10     private final float mDepthZ;
11     private final boolean mReverse;
12     private Camera mCamera;
13
14     /**
15      * Creates a new 3D rotation on the Y axis. The rotation is defined by its
16      * start angle and its end angle. Both angles are in degrees. The rotation
17      * is performed around a center point on the 2D space, definied by a pair
18      * of X and Y coordinates, called centerX and centerY. When the animation
19      * starts, a translation on the Z axis (depth) is performed. The length
20      * of the translation can be specified, as well as whether the translation
21      * should be reversed in time.
22      *
23      * @param fromDegrees the start angle of the 3D rotation
24      * @param toDegrees the end angle of the 3D rotation
25      * @param centerX the X center of the 3D rotation
26      * @param centerY the Y center of the 3D rotation
27      * @param reverse true if the translation should be reversed, false otherwise
28      */
29     public Rotate3dAnimation(float fromDegrees, float toDegrees,
30             float centerX, float centerY, float depthZ, boolean reverse) {
31         mFromDegrees = fromDegrees;
32         mToDegrees = toDegrees;
33         mCenterX = centerX;
34         mCenterY = centerY;
35         mDepthZ = depthZ;
36         mReverse = reverse;
37     }
38
39     @Override
40     public void initialize(int width, int height, int parentWidth, int parentHeight) {
41         super.initialize(width, height, parentWidth, parentHeight);
42         mCamera = new Camera();
43     }
44
45     @Override
46     protected void applyTransformation(float interpolatedTime, Transformation t) {
47         final float fromDegrees = mFromDegrees;
48         float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
49
50         final float centerX = mCenterX;
51         final float centerY = mCenterY;
52         final Camera camera = mCamera;
53
54         final Matrix matrix = t.getMatrix();
55
56         camera.save();
57         if (mReverse) {
58             camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
59         } else {
60             camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
61         }
62         camera.rotateY(degrees);
63         camera.getMatrix(matrix);
64         camera.restore();
65
66         matrix.preTranslate(-centerX, -centerY);
67         matrix.postTranslate(centerX, centerY);
68     }
69 }

 1 import android.graphics.Camera;
2 import android.graphics.Matrix;
3 import android.view.animation.Animation;
4 import android.view.animation.Transformation;
5
6 /**
7  * @author Administrator
8  *
9  */
10 public class Rotate3DAnimation extends Animation {
11     // 开始角度
12     private final float mFromDegrees;
13     // 结束角度
14     private final float mToDegrees;
15     // 中心点
16     private final float mCenterX;
17     private final float mCenterY;
18     private final float mDepthZ;
19     // 是否需要扭曲 ，也就是是否有Z轴方向深度的变化
20     private final boolean mReverse;
21     // 摄像头
22     private Camera mCamera;
23     public Rotate3DAnimation(float fromDegrees, float toDegrees, float centerX,
24             float centerY, float depthZ, boolean reverse) {
25         mFromDegrees = fromDegrees;
26         mToDegrees = toDegrees;
27         mCenterX = centerX;
28         mCenterY = centerY;
29         mDepthZ = depthZ;
30         mReverse = reverse;
31     }
32     @Override
33     public void initialize(int width, int height, int parentWidth,
34             int parentHeight) {
35         super.initialize(width, height, parentWidth, parentHeight);
36         mCamera = new Camera();
37     }
38
39     /**
40      * 生成Transformation,整个动画的过程中会不停的被调用
41      * @param interpolatedTime 会逐渐从0增大到1
42      * @param Transformation 变换对象
43      */
44     @Override
45     protected void applyTransformation(float interpolatedTime, Transformation t) {
46         /**
47          * 实际上整个过程就是通过Camera计算出要旋转所要修改的Matrix的值
48          * 整个函数结束之后，会根据这个Matrix的值进行变化
49          * 也就是说实际最终变换依据的依然是Matrix的值
50          */
51         final float fromDegrees = mFromDegrees;
52         //生成每次的角度
53         float degrees = fromDegrees
54                 + ((mToDegrees - fromDegrees) * interpolatedTime);
55         final float centerX = mCenterX;
56         final float centerY = mCenterY;
57         final Camera camera = mCamera;
58         final Matrix matrix = t.getMatrix();//获取动画对象的矩阵
59         camera.save();//保存摄像机的状态
60         if (mReverse) { //变化的方向是从小往大变
61             camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
62         }
63         //旋转到指定的角度
64         camera.rotateY(degrees);
65         //取得变换后的矩阵，修改Matrix的值
66         camera.getMatrix(matrix);
67         camera.restore();//恢复摄像机的状态 ，每次摄像机变换完后，下次又从摄像机初始位置开始变化
68         //将变换的中心点设成中心点
69         matrix.preTranslate(-centerX, -centerY);
70         matrix.postTranslate(centerX, centerY);
71     }
72 }

Activity中的代码

 1 import org.cxjchen.animation.Rotate3DAnimation;
2 import android.app.Activity;
3 import android.content.Intent;
4 import android.os.Bundle;
5 import android.view.View;
6 import android.view.View.OnClickListener;
7 import android.view.animation.*;
8 import android.widget.ImageView;
9 import android.widget.TextView;
10
11
12 /**
13  * @author Administrator
14  *
15  */
16 public class Logo_Activity extends Activity {
17
18     private TextView logo_title = null;
19
20     @Override
21     protected void onCreate(Bundle savedInstanceState) {
22
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.logo_activity);
25
26         logo_title = (TextView)findViewById(R.id.logo_title);
27         logo_title.setOnClickListener(new OnClickListener() {
28
29             @Override
30             public void onClick(View v) {
31                 applyRotation(0,360);
32             }
33         });
34     }
35
36
37     private void applyRotation(float start, float end) {
38         // 计算中心点
39         final float centerX = logo_title.getWidth() / 2.0f;
40         final float centerY = logo_title.getHeight() / 2.0f;
41         final Rotate3DAnimation rotation = new Rotate3DAnimation(start, end,
42                 centerX, centerY, 360.0f, false);
43         rotation.setDuration(1000L);
44         //设置变换后是否维持变换状态
45         rotation.setFillAfter(true);
46         rotation.setInterpolator(new AccelerateInterpolator());
47         // 设置监听
48         rotation.setAnimationListener(new Animation.AnimationListener() {
49
50             @Override
51             public void onAnimationStart(Animation animation) {
52             }
53
54             @Override
55             public void onAnimationRepeat(Animation animation) {
56
57             }
58
59             @Override
60             public void onAnimationEnd(Animation animation) {
61
62             }
63         });
64         logo_title.startAnimation(rotation);
65     }
66
67 }

posted on 2014-05-21 15:40  曾经的你|  阅读(1065)  评论(0编辑  收藏  举报