Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2012 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.os.SystemClock;
     20 import android.util.Log;
     21 
     22 import com.android.gallery3d.glrenderer.GLCanvas;
     23 import com.android.gallery3d.glrenderer.RawTexture;
     24 
     25 /**
     26  * Class to handle the animation when switching between back and front cameras.
     27  * An image of the previous camera zooms in and fades out. The preview of the
     28  * new camera zooms in and fades in. The image of the previous camera is called
     29  * review in this class.
     30  */
     31 public class SwitchAnimManager {
     32     private static final String TAG = "SwitchAnimManager";
     33     // The amount of change for zooming in and out.
     34     private static final float ZOOM_DELTA_PREVIEW = 0.2f;
     35     private static final float ZOOM_DELTA_REVIEW = 0.5f;
     36     private static final float ANIMATION_DURATION = 400;  // ms
     37     public static final float INITIAL_DARKEN_ALPHA = 0.8f;
     38 
     39     private long mAnimStartTime;  // milliseconds.
     40     // The drawing width and height of the review image. This is saved when the
     41     // texture is copied.
     42     private int mReviewDrawingWidth;
     43     private int mReviewDrawingHeight;
     44     // The maximum width of the camera screen nail width from onDraw. We need to
     45     // know how much the preview is scaled and scale the review the same amount.
     46     // For example, the preview is not full screen in film strip mode.
     47     private int mPreviewFrameLayoutWidth;
     48 
     49     public SwitchAnimManager() {
     50     }
     51 
     52     public void setReviewDrawingSize(int width, int height) {
     53         mReviewDrawingWidth = width;
     54         mReviewDrawingHeight = height;
     55     }
     56 
     57     // width: the width of PreviewFrameLayout view.
     58     // height: the height of PreviewFrameLayout view. Not used. Kept for
     59     //         consistency.
     60     public void setPreviewFrameLayoutSize(int width, int height) {
     61         mPreviewFrameLayoutWidth = width;
     62     }
     63 
     64     // w and h: the rectangle area where the animation takes place.
     65     public void startAnimation() {
     66         mAnimStartTime = SystemClock.uptimeMillis();
     67     }
     68 
     69     // Returns true if the animation has been drawn.
     70     // preview: camera preview view.
     71     // review: snapshot of the preview before switching the camera.
     72     public boolean drawAnimation(GLCanvas canvas, int x, int y, int width,
     73             int height, CameraScreenNail preview, RawTexture review) {
     74         long timeDiff = SystemClock.uptimeMillis() - mAnimStartTime;
     75         if (timeDiff > ANIMATION_DURATION) return false;
     76         float fraction = timeDiff / ANIMATION_DURATION;
     77 
     78         // Calculate the position and the size of the preview.
     79         float centerX = x + width / 2f;
     80         float centerY = y + height / 2f;
     81         float previewAnimScale = 1 - ZOOM_DELTA_PREVIEW * (1 - fraction);
     82         float previewWidth = width * previewAnimScale;
     83         float previewHeight = height * previewAnimScale;
     84         int previewX = Math.round(centerX - previewWidth / 2);
     85         int previewY = Math.round(centerY - previewHeight / 2);
     86 
     87         // Calculate the position and the size of the review.
     88         float reviewAnimScale = 1 + ZOOM_DELTA_REVIEW * fraction;
     89 
     90         // Calculate how much preview is scaled.
     91         // The scaling is done by PhotoView in Gallery so we don't have the
     92         // scaling information but only the width and the height passed to this
     93         // method. The inference of the scale ratio is done by matching the
     94         // current width and the original width we have at first when the camera
     95         // layout is inflated.
     96         float scaleRatio = 1;
     97         if (mPreviewFrameLayoutWidth != 0) {
     98             scaleRatio = (float) width / mPreviewFrameLayoutWidth;
     99         } else {
    100             Log.e(TAG, "mPreviewFrameLayoutWidth is 0.");
    101         }
    102         float reviewWidth = mReviewDrawingWidth * reviewAnimScale * scaleRatio;
    103         float reviewHeight = mReviewDrawingHeight * reviewAnimScale * scaleRatio;
    104         int reviewX = Math.round(centerX - reviewWidth / 2);
    105         int reviewY = Math.round(centerY - reviewHeight / 2);
    106 
    107         // Draw the preview.
    108         float alpha = canvas.getAlpha();
    109         canvas.setAlpha(fraction); // fade in
    110         preview.directDraw(canvas, previewX, previewY, Math.round(previewWidth),
    111                 Math.round(previewHeight));
    112 
    113         // Draw the review.
    114         canvas.setAlpha((1f - fraction) * INITIAL_DARKEN_ALPHA); // fade out
    115         review.draw(canvas, reviewX, reviewY, Math.round(reviewWidth),
    116                 Math.round(reviewHeight));
    117         canvas.setAlpha(alpha);
    118         return true;
    119     }
    120 
    121     public boolean drawDarkPreview(GLCanvas canvas, int x, int y, int width,
    122             int height, RawTexture review) {
    123         // Calculate the position and the size.
    124         float centerX = x + width / 2f;
    125         float centerY = y + height / 2f;
    126         float scaleRatio = 1;
    127         if (mPreviewFrameLayoutWidth != 0) {
    128             scaleRatio = (float) width / mPreviewFrameLayoutWidth;
    129         } else {
    130             Log.e(TAG, "mPreviewFrameLayoutWidth is 0.");
    131         }
    132         float reviewWidth = mReviewDrawingWidth * scaleRatio;
    133         float reviewHeight = mReviewDrawingHeight * scaleRatio;
    134         int reviewX = Math.round(centerX - reviewWidth / 2);
    135         int reviewY = Math.round(centerY - reviewHeight / 2);
    136 
    137         // Draw the review.
    138         float alpha = canvas.getAlpha();
    139         canvas.setAlpha(INITIAL_DARKEN_ALPHA);
    140         review.draw(canvas, reviewX, reviewY, Math.round(reviewWidth),
    141                 Math.round(reviewHeight));
    142         canvas.setAlpha(alpha);
    143         return true;
    144     }
    145 
    146 }
    147