二维的动画实现比较简单,此前也有多篇文章介绍过。本次,介绍下如何基于camera和matrix实现一个3D旋转动画。以下提供了两种动画效果:Y轴旋转+透明度从1-0消失,Y轴旋转+透明度从0-1出现。直接上代码:
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;
/**
* Y轴旋转和透明度渐变动画
*/
public class RotateYAnimation extends Animation {
/** 旋转的中心点X坐标 */
private int mCenterX;
/** 旋转的中心点Y坐标 */
private int mCenterY;
/** 动画场景 */
private AnimState mState;
/** 旋转角度 */
private static final float ROTATE_ANGLE = -90;
/** 消失动画相机位置 */
private static final float CAMERA_LOCATION_DISAPPEAR = 45;
/** 出现动画相机位置 */
private static final float CAMERA_LOCATION_APPEAR = -45;
/** 动画用到的camera */
private Camera mCamera = new Camera();
public RotateYAnimation(AnimState state) {
mState = state;
}
/**
* 初始化动画坐标,设置插值器
*
* @param width
* @param height
* @param parentWidth
* @param parentHeight
*/
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
// 获得中心点坐标
mCenterX = width / 2;
mCenterY = height / 2;
// 设置相机位置
if (mState == AnimState.DISAPPEAR) {
mCamera.setLocation(0, 0, CAMERA_LOCATION_DISAPPEAR);
} else {
mCamera.setLocation(0, 0, CAMERA_LOCATION_APPEAR);
}
// 设置线性插值器,防止旋转回弹
setInterpolator(new LinearInterpolator());
}
/**
* 动画实现
*
* @param interpolatedTime
* @param t
*/
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Matrix matrix = t.getMatrix();
mCamera.save();
float degrees;
float alpha;
if (mState == AnimState.DISAPPEAR) {
// DisAppear动画:alpha从1到0,degrees从0到-90
alpha = 1.0f * (1 - interpolatedTime);
degrees = ROTATE_ANGLE * interpolatedTime;
} else {
// Appear动画:alpha从0到1,degrees从-90到0
alpha = 1.0f * interpolatedTime;
degrees = ROTATE_ANGLE * (1 - interpolatedTime);
}
// 设置透明度
t.setAlpha(alpha);
// Y轴旋转
mCamera.rotateY(degrees);
mCamera.getMatrix(matrix);
// 设置旋转中心点
matrix.preTranslate(-mCenterX, -mCenterY);
matrix.postTranslate(mCenterX, mCenterY);
mCamera.restore();
}
/**
* 动画场景
*/
enum AnimState {
/** 从无到有 */
APPEAR,
/** 从有到无 */
DISAPPEAR
}
}