Home | History | Annotate | Download | only in camera
      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      */
     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