1. 程式人生 > >Android 3D旋轉動畫庫

Android 3D旋轉動畫庫

今天興趣來潮,擼了一個動畫特效,我把他應用在登入的介面,當然也可以用在其他地方,先來預覽一下我的特效吧

預覽.gif

使用方法


1. 在build.gradle裡面配置如下

    dependencies {
       compile 'com.jzp:rotate3D:1.0.0'
    }


2. 生成一個Rotate3D物件

   Rotate3D  anim = new Rotate3D.Builder(this)
            .bindParentView(parent_ll)
            .bindPositiveView(account_login_ll)
            .bindNegativeView
(account_phone_ll) .create();

這裡面必須要設定的引數是bindParentView,bindPositiveView,bindNegativeView,這些分別是父類View,正面View,以及旋轉後的反面View,有提供可選引數
- setDuration 設定動畫時間
- setDepthZ 設定Z軸深度
可選引數未設定的話就使用預設的

3. 啟動動畫

   anim.transform();

實現原理

由於android提供的動畫 alpha(淡入淡出),translate(位移),scale(縮放大小),rotate(旋轉),這些都是平面上的動畫,那想要做3D立體的動畫,我們就需要從寫animation,3D立體動畫用到android的Camera庫,Camera提供了三種旋轉方法:
- rotateX()
- rotateY()
- rotateX()
呼叫這三種方法,傳入旋轉角度引數,即可實現檢視沿著座標軸旋轉的功能。

實現的核心程式碼

public class Rotate3dAnimation extends Animation {
    private final float mFromDegrees;
    private final float mToDegrees;
    private final float mCenterX;
    private final float mCenterY;
    private final float mDepthZ;
    private final boolean mReverse;
    private Camera mCamera;
    float
scale = 1; // 畫素密度 /** * 建立一個繞 y 軸旋轉的3D動畫效果,旋轉過程中具有深度調節,可以指定旋轉中心。 * * @param context 上下文,用於獲取畫素密度 * @param fromDegrees 起始時角度 * @param toDegrees 結束時角度 * @param centerX 旋轉中心x座標 * @param centerY 旋轉中心y座標 * @param depthZ 最遠到達的z軸座標 * @param reverse true 表示由從0到depthZ,false相反 */ public Rotate3dAnimation(Context context, float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) { mFromDegrees = fromDegrees; mToDegrees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthZ = depthZ; mReverse = reverse; // 獲取手機畫素密度 (即dp與px的比例) scale = context.getResources().getDisplayMetrics().density; } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); mCamera = new Camera(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); camera.save(); // 調節深度 if (mReverse) { camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } // 繞y軸旋轉 camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); // 修正失真 float[] mValues = new float[9]; matrix.getValues(mValues); //獲取數值 mValues[6] = mValues[6] / scale; //數值修正 mValues[7] = mValues[7] / scale; //數值修正 matrix.setValues(mValues); //重新賦值 // 調節中心點,旋轉中心預設是座標原點,對於圖片來說就是左上角位置。 matrix.preTranslate(-centerX, -centerY); // 使用pre將旋轉中心移動到和Camera位置相同 matrix.postTranslate(centerX, centerY); // 使用post將圖片(View)移動到原來的位置 } }

總結

程式碼中的作用我都有寫註釋,所以在這裡就不多解釋了,有的時候,我們看一些特效覺得做起來一定很麻煩,其實只要你掌握其實現原理,並不是很難,所以給大家一句忠告,多讀原始碼,對技術的提升很有幫助。

Github原始碼下載:3D旋轉動畫庫