1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.example.android.apis.animation;
18
19import android.view.animation.Animation;
20import android.view.animation.Transformation;
21import android.graphics.Camera;
22import android.graphics.Matrix;
23
24/**
25 * An animation that rotates the view on the Y axis between two specified angles.
26 * This animation also adds a translation on the Z axis (depth) to improve the effect.
27 */
28public class Rotate3dAnimation extends Animation {
29    private final float mFromDegrees;
30    private final float mToDegrees;
31    private final float mCenterX;
32    private final float mCenterY;
33    private final float mDepthZ;
34    private final boolean mReverse;
35    private Camera mCamera;
36
37    /**
38     * Creates a new 3D rotation on the Y axis. The rotation is defined by its
39     * start angle and its end angle. Both angles are in degrees. The rotation
40     * is performed around a center point on the 2D space, definied by a pair
41     * of X and Y coordinates, called centerX and centerY. When the animation
42     * starts, a translation on the Z axis (depth) is performed. The length
43     * of the translation can be specified, as well as whether the translation
44     * should be reversed in time.
45     *
46     * @param fromDegrees the start angle of the 3D rotation
47     * @param toDegrees the end angle of the 3D rotation
48     * @param centerX the X center of the 3D rotation
49     * @param centerY the Y center of the 3D rotation
50     * @param reverse true if the translation should be reversed, false otherwise
51     */
52    public Rotate3dAnimation(float fromDegrees, float toDegrees,
53            float centerX, float centerY, float depthZ, boolean reverse) {
54        mFromDegrees = fromDegrees;
55        mToDegrees = toDegrees;
56        mCenterX = centerX;
57        mCenterY = centerY;
58        mDepthZ = depthZ;
59        mReverse = reverse;
60    }
61
62    @Override
63    public void initialize(int width, int height, int parentWidth, int parentHeight) {
64        super.initialize(width, height, parentWidth, parentHeight);
65        mCamera = new Camera();
66    }
67
68    @Override
69    protected void applyTransformation(float interpolatedTime, Transformation t) {
70        final float fromDegrees = mFromDegrees;
71        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
72
73        final float centerX = mCenterX;
74        final float centerY = mCenterY;
75        final Camera camera = mCamera;
76
77        final Matrix matrix = t.getMatrix();
78
79        camera.save();
80        if (mReverse) {
81            camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
82        } else {
83            camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
84        }
85        camera.rotateY(degrees);
86        camera.getMatrix(matrix);
87        camera.restore();
88
89        matrix.preTranslate(-centerX, -centerY);
90        matrix.postTranslate(centerX, centerY);
91    }
92}
93