Android 3D旋轉動畫庫
阿新 • • 發佈:2019-01-28
今天興趣來潮,擼了一個動畫特效,我把他應用在登入的介面,當然也可以用在其他地方,先來預覽一下我的特效吧
使用方法
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)移動到原來的位置
}
}
總結
程式碼中的作用我都有寫註釋,所以在這裡就不多解釋了,有的時候,我們看一些特效覺得做起來一定很麻煩,其實只要你掌握其實現原理,並不是很難,所以給大家一句忠告,多讀原始碼,對技術的提升很有幫助。