michael@0: /* michael@0: * Copyright (C) 2007 The Android Open Source Project michael@0: * michael@0: * Licensed under the Apache License, Version 2.0 (the "License"); michael@0: * you may not use this file except in compliance with the License. michael@0: * You may obtain a copy of the License at michael@0: * michael@0: * http://www.apache.org/licenses/LICENSE-2.0 michael@0: * michael@0: * Unless required by applicable law or agreed to in writing, software michael@0: * distributed under the License is distributed on an "AS IS" BASIS, michael@0: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. michael@0: * See the License for the specific language governing permissions and michael@0: * limitations under the License. michael@0: */ michael@0: michael@0: package org.mozilla.gecko.animation; michael@0: michael@0: import android.view.animation.Animation; michael@0: import android.view.animation.Transformation; michael@0: michael@0: import android.graphics.Camera; michael@0: import android.graphics.Matrix; michael@0: michael@0: /** michael@0: * An animation that rotates the view on the Y axis between two specified angles. michael@0: * This animation also adds a translation on the Z axis (depth) to improve the effect. michael@0: */ michael@0: public class Rotate3DAnimation extends Animation { michael@0: private final float mFromDegrees; michael@0: private final float mToDegrees; michael@0: michael@0: private final float mCenterX; michael@0: private final float mCenterY; michael@0: michael@0: private final float mDepthZ; michael@0: private final boolean mReverse; michael@0: private Camera mCamera; michael@0: michael@0: private int mWidth = 1; michael@0: private int mHeight = 1; michael@0: michael@0: /** michael@0: * Creates a new 3D rotation on the Y axis. The rotation is defined by its michael@0: * start angle and its end angle. Both angles are in degrees. The rotation michael@0: * is performed around a center point on the 2D space, definied by a pair michael@0: * of X and Y coordinates, called centerX and centerY. When the animation michael@0: * starts, a translation on the Z axis (depth) is performed. The length michael@0: * of the translation can be specified, as well as whether the translation michael@0: * should be reversed in time. michael@0: * michael@0: * @param fromDegrees the start angle of the 3D rotation michael@0: * @param toDegrees the end angle of the 3D rotation michael@0: * @param centerX the X center of the 3D rotation michael@0: * @param centerY the Y center of the 3D rotation michael@0: * @param reverse true if the translation should be reversed, false otherwise michael@0: */ michael@0: public Rotate3DAnimation(float fromDegrees, float toDegrees, michael@0: float centerX, float centerY, float depthZ, boolean reverse) { michael@0: mFromDegrees = fromDegrees; michael@0: mToDegrees = toDegrees; michael@0: mCenterX = centerX; michael@0: mCenterY = centerY; michael@0: mDepthZ = depthZ; michael@0: mReverse = reverse; michael@0: } michael@0: michael@0: @Override michael@0: public void initialize(int width, int height, int parentWidth, int parentHeight) { michael@0: super.initialize(width, height, parentWidth, parentHeight); michael@0: mCamera = new Camera(); michael@0: mWidth = width; michael@0: mHeight = height; michael@0: } michael@0: michael@0: @Override michael@0: protected void applyTransformation(float interpolatedTime, Transformation t) { michael@0: final float fromDegrees = mFromDegrees; michael@0: float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); michael@0: michael@0: final Camera camera = mCamera; michael@0: final Matrix matrix = t.getMatrix(); michael@0: michael@0: camera.save(); michael@0: if (mReverse) { michael@0: camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); michael@0: } else { michael@0: camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); michael@0: } michael@0: camera.rotateX(degrees); michael@0: camera.getMatrix(matrix); michael@0: camera.restore(); michael@0: michael@0: matrix.preTranslate(-mCenterX * mWidth, -mCenterY * mHeight); michael@0: matrix.postTranslate(mCenterX * mWidth, mCenterY * mHeight); michael@0: } michael@0: }