Android新姿式:3D翻轉效果原理

首先,android裏是沒有3D翻轉的動畫效果的,可是呢,android有提供一個Camera的類,能夠利用這個類來實現。java


先看代碼,Rotate3d是繼承了Animation的一個動畫類,多餘的代碼我就不給出了,只看applyTransformation方法內是怎麼實現的。android

public class Rotate3d extends Animation {app

    ...ide

        @Overridepost

protected void applyTransformation(float interpolatedTime, Transformation t) {動畫

final float fromDegrees = mFromDegrees;spa

// 生成中間角度3d

float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);rest

final float centerX = mCenterX;orm

final float centerY = mCenterY;

final Camera camera = mCamera;

final Matrix matrix = t.getMatrix();


camera.save();

                // 左右翻轉

camera.rotateY(degrees);

// 取得變換後的矩陣

camera.getMatrix(matrix);

camera.restore();


matrix.preTranslate(-centerX, -centerY);

matrix.postTranslate(centerX, centerY);

        } 

    ...


接下來解析下原理。

一、先獲取視圖的Matrix:

    final Matrix matrix = t.getMatrix();

二、利用camera改變matrix的參數:

    camera.rotateY(degrees);//翻轉必定的角度

    camera.getMatrix(matrix);//改變matrix


 PS:注意這裏是用getMatrix的方法來改變,順便普及一下小知識,java的方法傳入的參數若是是對象的話,是能夠在方法內改變對象的屬性值的;不過若是傳入的是一個int、float、String之類的基礎類型,則不會改變。舉例:

    假若有個方法 set(int i){ i++; } 而後用了 int i=3; set(i); 這時打印出的 i 仍是3。

    可是 假若有個方法 set(C c){ c.i++; } 而後用了 c = new C(); c.i=3; set(c); 這時打印出 c 對象的 i 就是4了。 


三、繼續,通常上面的步驟已經能夠見到3D翻轉效果了,可是很難看,由於這種翻轉是沒有中心點的,接下來就是將翻轉後的視圖弄到一個位置上去(其實這麼說也不太對)。

    matrix.preTranslate(-centerX, -centerY);

    matrix.postTranslate(centerX, centerY);

這個的話其實我也研究了很久最後沒研究出個因此然來,反正記住這樣寫就能夠設置以某個座標爲中心進行翻轉了。 



---------------------------我叫分割線-------------------------- 


最近搞的一個項目須要用到有3D翻轉效果的gallery,卡了我很久。


上面給出的代碼是製做一個3D翻轉的動畫效果,可是若是要在gallery中用到這種動畫效果的話天然不行。主要是翻轉角度的計算問題。


animation動畫類中能夠根據動畫發生的時間點來計算角度,而gallery就不行,由於gallery是隨手勢滑動發生動畫的,時間不固定,還能夠左右來回滑動。


不過只要解決了角度的問題,3D翻轉效果天然不是問題。先看代碼。

@Override

protected boolean getChildStaticTransformation(View child, Transformation t) {

final float centerX = App.width / 2;

final float centerY = App.height / 2;

final Camera camera = mCamera;


camera.save();

float rotate = -child.getLeft() * 90 / 480;

camera.rotateY(rotate);

camera.getMatrix(t.getMatrix());

camera.restore();


t.getMatrix().preTranslate(-centerX, -centerY);

t.getMatrix().postTranslate(centerX, centerY);

   return true; 

}

這是重寫gallery的一個方法,具體的角度計算,其實就是根據當前視圖View child與左屏幕的距離來計算(也能夠當成是x座標)。


好~效果出來了!仍是挺有成就感的~~ >v<

相關文章
相關標籤/搜索