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.ui;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorSet;
21 import android.animation.ValueAnimator;
22 import android.content.Context;
23 import android.content.res.Configuration;
24 import android.graphics.Canvas;
25 import android.graphics.Color;
26 import android.graphics.Paint;
27 import android.graphics.RectF;
28 import android.util.AttributeSet;
29 import android.view.Gravity;
30 import android.view.View;
31 import android.view.animation.Interpolator;
32 import android.view.animation.LinearInterpolator;
33 import android.widget.FrameLayout;
34 
35 import com.android.camera.debug.Log;
36 import com.android.camera.util.Gusterpolator;
37 import com.android.camera2.R;
38 
39 /**
40  * This class handles all the animations at capture time. Post capture animations
41  * will be handled in a separate place.
42  */
43 public class CaptureAnimationOverlay extends View
44     implements PreviewStatusListener.PreviewAreaChangedListener {
45     private final static Log.Tag TAG = new Log.Tag("CaptureAnimOverlay");
46 
47     private final static int FLASH_COLOR = Color.WHITE;
48 
49     private static final float FLASH_MAX_ALPHA = 0.85f;
50     private static final long FLASH_FULL_DURATION_MS = 65;
51     private static final long FLASH_DECREASE_DURATION_MS = 150;
52     private static final float SHORT_FLASH_MAX_ALPHA = 0.75f;
53     private static final long SHORT_FLASH_FULL_DURATION_MS = 34;
54     private static final long SHORT_FLASH_DECREASE_DURATION_MS = 100;
55 
56     private RectF mPreviewArea = new RectF();
57 
58     private AnimatorSet mFlashAnimation;
59     private final Paint mPaint = new Paint();
60     private final Interpolator mFlashAnimInterpolator;
61     private final ValueAnimator.AnimatorUpdateListener mFlashAnimUpdateListener;
62     private final Animator.AnimatorListener mFlashAnimListener;
63 
CaptureAnimationOverlay(Context context, AttributeSet attrs)64     public CaptureAnimationOverlay(Context context, AttributeSet attrs) {
65         super(context, attrs);
66         mPaint.setColor(FLASH_COLOR);
67         mFlashAnimInterpolator = new LinearInterpolator();
68         mFlashAnimUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
69             @Override
70             public void onAnimationUpdate(ValueAnimator animation) {
71                 setAlpha((Float) animation.getAnimatedValue());
72                 invalidate();
73             }
74         };
75         mFlashAnimListener = new Animator.AnimatorListener() {
76             @Override
77             public void onAnimationStart(Animator animation) {
78                 setVisibility(VISIBLE);
79             }
80 
81             @Override
82             public void onAnimationEnd(Animator animation) {
83                 mFlashAnimation = null;
84                 setVisibility(INVISIBLE);
85             }
86 
87             @Override
88             public void onAnimationCancel(Animator animation) {
89 
90             }
91 
92             @Override
93             public void onAnimationRepeat(Animator animation) {
94 
95             }
96         };
97     }
98 
99     /**
100      * Start flash animation.
101      *
102      * @param shortFlash show shortest possible flash instead of regular long version.
103      */
startFlashAnimation(boolean shortFlash)104     public void startFlashAnimation(boolean shortFlash) {
105         if (mFlashAnimation != null && mFlashAnimation.isRunning()) {
106             mFlashAnimation.cancel();
107         }
108         float maxAlpha;
109 
110         if (shortFlash) {
111             maxAlpha = SHORT_FLASH_MAX_ALPHA;
112         } else {
113             maxAlpha = FLASH_MAX_ALPHA;
114         }
115 
116         ValueAnimator flashAnim1 = ValueAnimator.ofFloat(maxAlpha, maxAlpha);
117         ValueAnimator flashAnim2 = ValueAnimator.ofFloat(maxAlpha, .0f);
118 
119         if (shortFlash) {
120             flashAnim1.setDuration(SHORT_FLASH_FULL_DURATION_MS);
121             flashAnim2.setDuration(SHORT_FLASH_DECREASE_DURATION_MS);
122         } else {
123             flashAnim1.setDuration(FLASH_FULL_DURATION_MS);
124             flashAnim2.setDuration(FLASH_DECREASE_DURATION_MS);
125         }
126 
127         flashAnim1.addUpdateListener(mFlashAnimUpdateListener);
128         flashAnim2.addUpdateListener(mFlashAnimUpdateListener);
129         flashAnim1.setInterpolator(mFlashAnimInterpolator);
130         flashAnim2.setInterpolator(mFlashAnimInterpolator);
131 
132         mFlashAnimation = new AnimatorSet();
133         mFlashAnimation.play(flashAnim1).before(flashAnim2);
134         mFlashAnimation.addListener(mFlashAnimListener);
135         mFlashAnimation.start();
136     }
137 
138     @Override
onDraw(Canvas canvas)139     public void onDraw(Canvas canvas) {
140         if (mFlashAnimation != null && mFlashAnimation.isRunning()) {
141             canvas.drawRect(mPreviewArea, mPaint);
142         }
143     }
144 
145     @Override
onPreviewAreaChanged(RectF previewArea)146     public void onPreviewAreaChanged(RectF previewArea) {
147         mPreviewArea.set(previewArea);
148     }
149 }
150