今天興趣來潮,擼了一個(gè)動(dòng)畫特效,我把他應(yīng)用在登錄的界面,當(dāng)然也可以用在其他地方,先來預(yù)覽一下我的特效吧
預(yù)覽.gif
使用方法
- 在build.gradle里面配置如下
dependencies {
compile 'com.jzp:rotate3D:1.0.0'
}
- 生成一個(gè)Rotate3D對象
Rotate3D anim = new Rotate3D.Builder(this)
.bindParentView(parent_ll)
.bindPositiveView(account_login_ll)
.bindNegativeView(account_phone_ll)
.create();
這里面必須要設(shè)置的參數(shù)是bindParentView,bindPositiveView,bindNegativeView,這些分別是父類View,正面View,以及旋轉(zhuǎn)后的反面View,有提供可選參數(shù)
- setDuration 設(shè)置動(dòng)畫時(shí)間
- setDepthZ 設(shè)置Z軸深度
可選參數(shù)未設(shè)置的話就使用默認(rèn)的
- 啟動(dòng)動(dòng)畫
anim.transform();
實(shí)現(xiàn)原理
由于android提供的動(dòng)畫 alpha(淡入淡出),translate(位移),scale(縮放大?。瑀otate(旋轉(zhuǎn)),這些都是平面上的動(dòng)畫,那想要做3D立體的動(dòng)畫,我們就需要從寫animation,3D立體動(dòng)畫用到android的Camera庫,Camera提供了三種旋轉(zhuǎn)方法:
- rotateX()
- rotateY()
- rotateX()
調(diào)用這三種方法,傳入旋轉(zhuǎn)角度參數(shù),即可實(shí)現(xiàn)視圖沿著坐標(biāo)軸旋轉(zhuǎn)的功能。
實(shí)現(xiàn)的核心代碼
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; // 像素密度
/**
* 創(chuàng)建一個(gè)繞 y 軸旋轉(zhuǎn)的3D動(dòng)畫效果,旋轉(zhuǎn)過程中具有深度調(diào)節(jié),可以指定旋轉(zhuǎn)中心。
*
* @param context 上下文,用于獲取像素密度
* @param fromDegrees 起始時(shí)角度
* @param toDegrees 結(jié)束時(shí)角度
* @param centerX 旋轉(zhuǎn)中心x坐標(biāo)
* @param centerY 旋轉(zhuǎn)中心y坐標(biāo)
* @param depthZ 最遠(yuǎn)到達(dá)的z軸坐標(biāo)
* @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;
// 獲取手機(jī)像素密度 (即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();
// 調(diào)節(jié)深度
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
// 繞y軸旋轉(zhuǎn)
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
// 修正失真
float[] mValues = new float[9];
matrix.getValues(mValues); //獲取數(shù)值
mValues[6] = mValues[6] / scale; //數(shù)值修正
mValues[7] = mValues[7] / scale; //數(shù)值修正
matrix.setValues(mValues); //重新賦值
// 調(diào)節(jié)中心點(diǎn),旋轉(zhuǎn)中心默認(rèn)是坐標(biāo)原點(diǎn),對于圖片來說就是左上角位置。
matrix.preTranslate(-centerX, -centerY); // 使用pre將旋轉(zhuǎn)中心移動(dòng)到和Camera位置相同
matrix.postTranslate(centerX, centerY); // 使用post將圖片(View)移動(dòng)到原來的位置
}
}
總結(jié)
代碼中的作用我都有寫注釋,所以在這里就不多解釋了,有的時(shí)候,我們看一些特效覺得做起來一定很麻煩,其實(shí)只要你掌握其實(shí)現(xiàn)原理,并不是很難,所以給大家一句忠告,多讀源碼,對技術(shù)的提升很有幫助。
參考文獻(xiàn):http://www.lxweimin.com/p/153d9f31288d 我是根據(jù)這篇博客進(jìn)行封裝的,謝謝亦楓大神的分享