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.ui.GLCanvas; 23 import com.android.gallery3d.ui.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 SwitchAnimManager()49 public SwitchAnimManager() { 50 } 51 setReviewDrawingSize(int width, int height)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. setPreviewFrameLayoutSize(int width, int height)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. startAnimation()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. drawAnimation(GLCanvas canvas, int x, int y, int width, int height, CameraScreenNail preview, RawTexture review)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 drawDarkPreview(GLCanvas canvas, int x, int y, int width, int height, RawTexture review)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