/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.camera; import android.os.SystemClock; import android.util.Log; import com.android.gallery3d.glrenderer.GLCanvas; import com.android.gallery3d.glrenderer.RawTexture; /** * Class to handle the animation when switching between back and front cameras. * An image of the previous camera zooms in and fades out. The preview of the * new camera zooms in and fades in. The image of the previous camera is called * review in this class. */ public class SwitchAnimManager { private static final String TAG = "SwitchAnimManager"; // The amount of change for zooming in and out. private static final float ZOOM_DELTA_PREVIEW = 0.2f; private static final float ZOOM_DELTA_REVIEW = 0.5f; private static final float ANIMATION_DURATION = 400; // ms public static final float INITIAL_DARKEN_ALPHA = 0.8f; private long mAnimStartTime; // milliseconds. // The drawing width and height of the review image. This is saved when the // texture is copied. private int mReviewDrawingWidth; private int mReviewDrawingHeight; // The maximum width of the camera screen nail width from onDraw. We need to // know how much the preview is scaled and scale the review the same amount. // For example, the preview is not full screen in film strip mode. private int mPreviewFrameLayoutWidth; public SwitchAnimManager() { } public void setReviewDrawingSize(int width, int height) { mReviewDrawingWidth = width; mReviewDrawingHeight = height; } // width: the width of PreviewFrameLayout view. // height: the height of PreviewFrameLayout view. Not used. Kept for // consistency. public void setPreviewFrameLayoutSize(int width, int height) { mPreviewFrameLayoutWidth = width; } // w and h: the rectangle area where the animation takes place. public void startAnimation() { mAnimStartTime = SystemClock.uptimeMillis(); } // Returns true if the animation has been drawn. // preview: camera preview view. // review: snapshot of the preview before switching the camera. public boolean drawAnimation(GLCanvas canvas, int x, int y, int width, int height, CameraScreenNail preview, RawTexture review) { long timeDiff = SystemClock.uptimeMillis() - mAnimStartTime; if (timeDiff > ANIMATION_DURATION) return false; float fraction = timeDiff / ANIMATION_DURATION; // Calculate the position and the size of the preview. float centerX = x + width / 2f; float centerY = y + height / 2f; float previewAnimScale = 1 - ZOOM_DELTA_PREVIEW * (1 - fraction); float previewWidth = width * previewAnimScale; float previewHeight = height * previewAnimScale; int previewX = Math.round(centerX - previewWidth / 2); int previewY = Math.round(centerY - previewHeight / 2); // Calculate the position and the size of the review. float reviewAnimScale = 1 + ZOOM_DELTA_REVIEW * fraction; // Calculate how much preview is scaled. // The scaling is done by PhotoView in Gallery so we don't have the // scaling information but only the width and the height passed to this // method. The inference of the scale ratio is done by matching the // current width and the original width we have at first when the camera // layout is inflated. float scaleRatio = 1; if (mPreviewFrameLayoutWidth != 0) { scaleRatio = (float) width / mPreviewFrameLayoutWidth; } else { Log.e(TAG, "mPreviewFrameLayoutWidth is 0."); } float reviewWidth = mReviewDrawingWidth * reviewAnimScale * scaleRatio; float reviewHeight = mReviewDrawingHeight * reviewAnimScale * scaleRatio; int reviewX = Math.round(centerX - reviewWidth / 2); int reviewY = Math.round(centerY - reviewHeight / 2); // Draw the preview. float alpha = canvas.getAlpha(); canvas.setAlpha(fraction); // fade in preview.directDraw(canvas, previewX, previewY, Math.round(previewWidth), Math.round(previewHeight)); // Draw the review. canvas.setAlpha((1f - fraction) * INITIAL_DARKEN_ALPHA); // fade out review.draw(canvas, reviewX, reviewY, Math.round(reviewWidth), Math.round(reviewHeight)); canvas.setAlpha(alpha); return true; } public boolean drawDarkPreview(GLCanvas canvas, int x, int y, int width, int height, RawTexture review) { // Calculate the position and the size. float centerX = x + width / 2f; float centerY = y + height / 2f; float scaleRatio = 1; if (mPreviewFrameLayoutWidth != 0) { scaleRatio = (float) width / mPreviewFrameLayoutWidth; } else { Log.e(TAG, "mPreviewFrameLayoutWidth is 0."); } float reviewWidth = mReviewDrawingWidth * scaleRatio; float reviewHeight = mReviewDrawingHeight * scaleRatio; int reviewX = Math.round(centerX - reviewWidth / 2); int reviewY = Math.round(centerY - reviewHeight / 2); // Draw the review. float alpha = canvas.getAlpha(); canvas.setAlpha(INITIAL_DARKEN_ALPHA); review.draw(canvas, reviewX, reviewY, Math.round(reviewWidth), Math.round(reviewHeight)); canvas.setAlpha(alpha); return true; } }