• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.android.photoeditor.animation;
18 
19 import android.graphics.Camera;
20 import android.graphics.Matrix;
21 import android.view.animation.AccelerateInterpolator;
22 import android.view.animation.Animation;
23 import android.view.animation.DecelerateInterpolator;
24 import android.view.animation.Transformation;
25 
26 /**
27  * Rotation animation that rotates a 2D view 90 degrees on either X or Y axis in 3D space. The
28  * rotation is performed around the view center point by its defined rotation direction and position
29  * it will start from or end to. The rotation duration can be specified as well as whether the
30  * rotation should be accelerated or decelerated in time.
31  */
32 public class Rotate3DAnimation extends Animation {
33 
34     public enum Rotate {
35         UP, DOWN, LEFT, RIGHT
36     }
37 
38     private enum Angle {
39         FROM_DEGREES_0, TO_DEGREES_0
40     }
41 
42     private static final float DEPTH_Z = 250.0f;
43     private static final float ROTATE_DEGREES = 90f;
44 
45     private final Rotate rotate;
46     private final Angle angle;
47     private final int duration;
48     private final boolean accelerate;
49 
50     private Camera camera;
51     private float centerX;
52     private float centerY;
53     private float fromDegrees;
54     private float toDegrees;
55 
56     /**
57      * Gets animations that flip the view by 3D rotations.
58      */
getFlipAnimations(Rotate rotate, int duration)59     public static AnimationPair getFlipAnimations(Rotate rotate, int duration) {
60         return new AnimationPair(
61                 new Rotate3DAnimation(rotate, Angle.FROM_DEGREES_0, duration, true),
62                 new Rotate3DAnimation(rotate, Angle.TO_DEGREES_0, duration, false));
63     }
64 
Rotate3DAnimation(Rotate rotate, Angle angle, int duration, boolean accelerate)65     private Rotate3DAnimation(Rotate rotate, Angle angle, int duration, boolean accelerate) {
66         this.rotate = rotate;
67         this.angle = angle;
68         this.duration = duration;
69         this.accelerate = accelerate;
70     }
71 
72     @Override
initialize(int width, int height, int parentWidth, int parentHeight)73     public void initialize(int width, int height, int parentWidth, int parentHeight) {
74         super.initialize(width, height, parentWidth, parentHeight);
75         super.setDuration(duration);
76         super.setInterpolator(
77                 accelerate ? new AccelerateInterpolator() : new DecelerateInterpolator());
78 
79         camera = new Camera();
80         centerX = width / 2.0f;
81         centerY = height / 2.0f;
82 
83         if (angle == Angle.FROM_DEGREES_0) {
84             fromDegrees = 0;
85 
86             switch (rotate) {
87                 case RIGHT:
88                 case UP:
89                     toDegrees = ROTATE_DEGREES;
90                     break;
91 
92                 case LEFT:
93                 case DOWN:
94                     toDegrees = -ROTATE_DEGREES;
95                     break;
96             }
97         } else if (angle == Angle.TO_DEGREES_0) {
98             toDegrees = 0;
99 
100             switch (rotate) {
101                 case RIGHT:
102                 case UP:
103                     fromDegrees = -ROTATE_DEGREES;
104                     break;
105 
106                 case LEFT:
107                 case DOWN:
108                     fromDegrees = ROTATE_DEGREES;
109                     break;
110             }
111         }
112     }
113 
114     @Override
applyTransformation(float interpolatedTime, Transformation t)115     protected void applyTransformation(float interpolatedTime, Transformation t) {
116         camera.save();
117 
118         if (angle == Angle.FROM_DEGREES_0) {
119             camera.translate(0.0f, 0.0f, DEPTH_Z * interpolatedTime);
120         } else if (angle == Angle.TO_DEGREES_0) {
121             camera.translate(0.0f, 0.0f, DEPTH_Z * (1.0f - interpolatedTime));
122         }
123 
124         float degrees = fromDegrees + ((toDegrees - fromDegrees) * interpolatedTime);
125         switch (rotate) {
126             case RIGHT:
127             case LEFT:
128                 camera.rotateY(degrees);
129                 break;
130 
131             case UP:
132             case DOWN:
133                 camera.rotateX(degrees);
134                 break;
135         }
136 
137         final Matrix matrix = t.getMatrix();
138         camera.getMatrix(matrix);
139         camera.restore();
140 
141         matrix.preTranslate(-centerX, -centerY);
142         matrix.postTranslate(centerX, centerY);
143     }
144 }
145