zoukankan      html  css  js  c++  java
  • 实现3D旋转效果的方法

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

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

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

    可以完成对指定View的X,Y,Z轴的变化,所以可以用来完成3D效果。但是变化之后并不是直接作用于View,而是修改View的Matrix的值,最终View再根据Matrix的值来变换。

    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 }
  • 相关阅读:
    Linux 多线程环境下 进程线程终止函数小结
    C++:vector中的resize()函数 VS reserve()函数
    Linux进程间通信之信号量(semaphore)、消息队列(Message Queue)和共享内存(Share Memory)
    Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)
    求全与求专
    wpf \silverlight 保存控件为图片
    软件版本号详解(转)
    WPF 自定义快捷键命令(Command)(转)
    WIN2003系统远程桌面多连接数设置终极大法
    程序集强命名与GAC
  • 原文地址:https://www.cnblogs.com/cxjchen/p/3741397.html
Copyright © 2011-2022 走看看