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