| /* |
| * 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; |
| } |
| |
| } |