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