Android 3D旋轉動畫——Rotate3dAnimation
阿新 • • 發佈:2019-02-20
在Android中如果想要實現3D效果一般有兩種選擇,一是使用Open GL ES,二是使用Camera。Open GL ES使用起來太過複雜,一般是用於比較高階的3D特效或遊戲,像比較簡單的一些3D效果,使用Camera就足夠了。
Camera中提供了三種旋轉方法,分別是rotateX()、rotateY()和rotateZ,呼叫這三個方法,並傳入相應的角度,就可以讓檢視圍繞這三個軸進行旋轉,而今天我們要做的中軸旋轉效果其實就是讓檢視圍繞Y軸進行旋轉。使用Camera讓檢視進行旋轉的示意圖,如下所示:
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.rotatepicbrowserdemo; import android.view.animation.Animation; import android.view.animation.Transformation; import android.graphics.Camera; import android.graphics.Matrix; /** * An animation that rotates the view on the Y axis between two specified * angles. This animation also adds a translation on the Z axis (depth) to * improve the effect. */ 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; /** * Creates a new 3D rotation on the Y axis. The rotation is defined by its * start angle and its end angle. Both angles are in degrees. The rotation * is performed around a center point on the 2D space, definied by a pair of * X and Y coordinates, called centerX and centerY. When the animation * starts, a translation on the Z axis (depth) is performed. The length of * the translation can be specified, as well as whether the translation * should be reversed in time. * * @param fromDegrees * the start angle of the 3D rotation * @param toDegrees * the end angle of the 3D rotation * @param centerX * the X center of the 3D rotation * @param centerY * the Y center of the 3D rotation * @param reverse * true if the translation should be reversed, false otherwise */ public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) { mFromDegrees = fromDegrees; mToDegrees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthZ = depthZ; mReverse = reverse; } @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(); // camera.translate,這個方法接受3個引數,分別是x,y,z三個軸的偏移量,我們這裡只將z軸進行了偏移, if (mReverse) { // z的偏移會越來越大。這就會形成這樣一個效果,view從近到遠 camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { // z的偏移會越來越小。這就會形成這樣一個效果,我們的View從一個很遠的地方向我們移過來,越來越近,最終移到了我們的視窗上面~ camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } // 是給我們的View加上旋轉效果,在移動的過程中,檢視還會移Y軸為中心進行旋轉。 camera.rotateY(degrees); // 是給我們的View加上旋轉效果,在移動的過程中,檢視還會移X軸為中心進行旋轉。 // camera.rotateX(degrees); // 這個是將我們剛才定義的一系列變換應用到變換矩陣上面,呼叫完這句之後,我們就可以將camera的位置恢復了,以便下一次再使用。 camera.getMatrix(matrix); // camera位置恢復 camera.restore(); // 以View的中心點為旋轉中心,如果不加這兩句,就是以(0,0)點為旋轉中心 matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } }