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
17package com.android.camera;
18
19import android.animation.Animator;
20import android.animation.AnimatorSet;
21import android.animation.ObjectAnimator;
22import android.view.View;
23
24/**
25 * Class to handle animations.
26 */
27
28public 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     */
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    */
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     */
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