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 
17 package com.example.android.apis.animation;
18 
19 import android.view.animation.Animation;
20 import android.view.animation.Transformation;
21 import android.graphics.Camera;
22 import 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  */
28 public 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      */
Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse)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
initialize(int width, int height, int parentWidth, int parentHeight)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
applyTransformation(float interpolatedTime, Transformation t)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