1 /*
2  * Copyright (C) 2013 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.camera;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorSet;
21 import android.animation.ObjectAnimator;
22 import android.view.View;
23 
24 /**
25  * Class to handle animations.
26  */
27 
28 public class AnimationManager {
29 
30     public static final float FLASH_ALPHA_START = 0.3f;
31     public static final float FLASH_ALPHA_END = 0f;
32     public static final int FLASH_DURATION = 300;
33 
34     public static final int SHRINK_DURATION = 400;
35     public static final int HOLD_DURATION = 2500;
36     public static final int SLIDE_DURATION = 1100;
37 
38     private ObjectAnimator mFlashAnim;
39     private AnimatorSet mCaptureAnimator;
40 
41     /**
42      * Starts capture animation.
43      * @param view a thumbnail view that shows a picture captured and gets animated
44      */
startCaptureAnimation(final View view)45     public void startCaptureAnimation(final View view) {
46         if (mCaptureAnimator != null && mCaptureAnimator.isStarted()) {
47             mCaptureAnimator.cancel();
48         }
49         View parentView = (View) view.getParent();
50         float slideDistance = (float) (parentView.getWidth() - view.getLeft());
51 
52         float scaleX = ((float) parentView.getWidth()) / ((float) view.getWidth());
53         float scaleY = ((float) parentView.getHeight()) / ((float) view.getHeight());
54         float scale = scaleX > scaleY ? scaleX : scaleY;
55 
56         int centerX = view.getLeft() + view.getWidth() / 2;
57         int centerY = view.getTop() + view.getHeight() / 2;
58 
59         ObjectAnimator slide = ObjectAnimator.ofFloat(view, "translationX", 0f, slideDistance)
60                 .setDuration(AnimationManager.SLIDE_DURATION);
61         slide.setStartDelay(AnimationManager.SHRINK_DURATION + AnimationManager.HOLD_DURATION);
62 
63         ObjectAnimator translateY = ObjectAnimator.ofFloat(view, "translationY",
64                 parentView.getHeight() / 2 - centerY, 0f)
65                 .setDuration(AnimationManager.SHRINK_DURATION);
66         translateY.addListener(new Animator.AnimatorListener() {
67             @Override
68             public void onAnimationStart(Animator animator) {
69                 // Do nothing.
70             }
71 
72             @Override
73             public void onAnimationEnd(Animator animator) {
74                 view.setClickable(true);
75             }
76 
77             @Override
78             public void onAnimationCancel(Animator animator) {
79                 // Do nothing.
80             }
81 
82             @Override
83             public void onAnimationRepeat(Animator animator) {
84                 // Do nothing.
85             }
86         });
87 
88         mCaptureAnimator = new AnimatorSet();
89         mCaptureAnimator.playTogether(
90                 ObjectAnimator.ofFloat(view, "scaleX", scale, 1f)
91                         .setDuration(AnimationManager.SHRINK_DURATION),
92                 ObjectAnimator.ofFloat(view, "scaleY", scale, 1f)
93                         .setDuration(AnimationManager.SHRINK_DURATION),
94                 ObjectAnimator.ofFloat(view, "translationX",
95                         parentView.getWidth() / 2 - centerX, 0f)
96                         .setDuration(AnimationManager.SHRINK_DURATION),
97                 translateY,
98                 slide);
99         mCaptureAnimator.addListener(new Animator.AnimatorListener() {
100             @Override
101             public void onAnimationStart(Animator animator) {
102                 view.setClickable(false);
103                 view.setVisibility(View.VISIBLE);
104             }
105 
106             @Override
107             public void onAnimationEnd(Animator animator) {
108                 view.setScaleX(1f);
109                 view.setScaleX(1f);
110                 view.setTranslationX(0f);
111                 view.setTranslationY(0f);
112                 view.setVisibility(View.INVISIBLE);
113                 mCaptureAnimator.removeAllListeners();
114                 mCaptureAnimator = null;
115             }
116 
117             @Override
118             public void onAnimationCancel(Animator animator) {
119                 view.setVisibility(View.INVISIBLE);
120             }
121 
122             @Override
123             public void onAnimationRepeat(Animator animator) {
124                 // Do nothing.
125             }
126         });
127         mCaptureAnimator.start();
128     }
129 
130    /**
131     * Starts flash animation.
132     * @params flashOverlay the overlay that will animate on alpha to make the flash impression
133     */
startFlashAnimation(final View flashOverlay)134     public void startFlashAnimation(final View flashOverlay) {
135         // End the previous animation if the previous one is still running
136         if (mFlashAnim != null && mFlashAnim.isRunning()) {
137             mFlashAnim.cancel();
138         }
139         // Start new flash animation.
140         mFlashAnim = ObjectAnimator.ofFloat(flashOverlay, "alpha",
141                 AnimationManager.FLASH_ALPHA_START, AnimationManager.FLASH_ALPHA_END);
142         mFlashAnim.setDuration(AnimationManager.FLASH_DURATION);
143         mFlashAnim.addListener(new Animator.AnimatorListener() {
144             @Override
145             public void onAnimationStart(Animator animator) {
146                 flashOverlay.setVisibility(View.VISIBLE);
147             }
148 
149             @Override
150             public void onAnimationEnd(Animator animator) {
151                 flashOverlay.setAlpha(0f);
152                 flashOverlay.setVisibility(View.GONE);
153                 mFlashAnim.removeAllListeners();
154                 mFlashAnim = null;
155             }
156 
157             @Override
158             public void onAnimationCancel(Animator animator) {
159                 // Do nothing.
160             }
161 
162             @Override
163             public void onAnimationRepeat(Animator animator) {
164                 // Do nothing.
165             }
166         });
167         mFlashAnim.start();
168     }
169 
170     /**
171      * Cancels on-going flash animation and capture animation, if any.
172      */
cancelAnimations()173     public void cancelAnimations() {
174         // End the previous animation if the previous one is still running
175         if (mFlashAnim != null && mFlashAnim.isRunning()) {
176             mFlashAnim.cancel();
177         }
178         if (mCaptureAnimator != null && mCaptureAnimator.isStarted()) {
179             mCaptureAnimator.cancel();
180         }
181     }
182 }
183