diff options
Diffstat (limited to 'src/com/android/camera/CaptureAnimManager.java')
-rw-r--r-- | src/com/android/camera/CaptureAnimManager.java | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/src/com/android/camera/CaptureAnimManager.java b/src/com/android/camera/CaptureAnimManager.java new file mode 100644 index 000000000..6e8092566 --- /dev/null +++ b/src/com/android/camera/CaptureAnimManager.java @@ -0,0 +1,228 @@ +/* + * 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.content.Context; +import android.content.res.Resources; +import android.graphics.Color; +import android.os.SystemClock; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; + +import com.android.gallery3d.R; +import com.android.gallery3d.glrenderer.GLCanvas; +import com.android.gallery3d.glrenderer.NinePatchTexture; +import com.android.gallery3d.glrenderer.RawTexture; + +/** + * Class to handle the capture animation. + */ +public class CaptureAnimManager { + @SuppressWarnings("unused") + private static final String TAG = "CAM_Capture"; + // times mark endpoint of animation phase + private static final int TIME_FLASH = 200; + private static final int TIME_HOLD = 400; + private static final int TIME_SLIDE = 800; + private static final int TIME_HOLD2 = 3300; + private static final int TIME_SLIDE2 = 4100; + + private static final int ANIM_BOTH = 0; + private static final int ANIM_FLASH = 1; + private static final int ANIM_SLIDE = 2; + private static final int ANIM_HOLD2 = 3; + private static final int ANIM_SLIDE2 = 4; + + private final Interpolator mSlideInterpolator = new DecelerateInterpolator(); + + private volatile int mAnimOrientation; // Could be 0, 90, 180 or 270 degrees. + private long mAnimStartTime; // milliseconds. + private float mX; // The center of the whole view including preview and review. + private float mY; + private int mDrawWidth; + private int mDrawHeight; + private int mAnimType; + + private int mHoldX; + private int mHoldY; + private int mHoldW; + private int mHoldH; + + private int mOffset; + + private int mMarginRight; + private int mMarginTop; + private int mSize; + private Resources mResources; + private NinePatchTexture mBorder; + private int mShadowSize; + + public static int getAnimationDuration() { + return TIME_SLIDE2; + } + + /* preview: camera preview view. + * review: view of picture just taken. + */ + public CaptureAnimManager(Context ctx) { + mBorder = new NinePatchTexture(ctx, R.drawable.capture_thumbnail_shadow); + mResources = ctx.getResources(); + } + + public void setOrientation(int displayRotation) { + mAnimOrientation = (360 - displayRotation) % 360; + } + + public void animateSlide() { + if (mAnimType != ANIM_FLASH) { + return; + } + mAnimType = ANIM_SLIDE; + mAnimStartTime = SystemClock.uptimeMillis(); + } + + public void animateFlash() { + mAnimType = ANIM_FLASH; + } + + public void animateFlashAndSlide() { + mAnimType = ANIM_BOTH; + } + + public void startAnimation() { + mAnimStartTime = SystemClock.uptimeMillis(); + } + + private void setAnimationGeometry(int x, int y, int w, int h) { + mMarginRight = mResources.getDimensionPixelSize(R.dimen.capture_margin_right); + mMarginTop = mResources.getDimensionPixelSize(R.dimen.capture_margin_top); + mSize = mResources.getDimensionPixelSize(R.dimen.capture_size); + mShadowSize = mResources.getDimensionPixelSize(R.dimen.capture_border); + mOffset = mMarginRight + mSize; + // Set the views to the initial positions. + mDrawWidth = w; + mDrawHeight = h; + mX = x; + mY = y; + mHoldW = mSize; + mHoldH = mSize; + switch (mAnimOrientation) { + case 0: // Preview is on the left. + mHoldX = x + w - mMarginRight - mSize; + mHoldY = y + mMarginTop; + break; + case 90: // Preview is below. + mHoldX = x + mMarginTop; + mHoldY = y + mMarginRight; + break; + case 180: // Preview on the right. + mHoldX = x + mMarginRight; + mHoldY = y + h - mMarginTop - mSize; + break; + case 270: // Preview is above. + mHoldX = x + w - mMarginTop - mSize; + mHoldY = y + h - mMarginRight - mSize; + break; + } + } + + // Returns true if the animation has been drawn. + public boolean drawAnimation(GLCanvas canvas, CameraScreenNail preview, + RawTexture review, int lx, int ly, int lw, int lh) { + setAnimationGeometry(lx, ly, lw, lh); + long timeDiff = SystemClock.uptimeMillis() - mAnimStartTime; + // Check if the animation is over + if (mAnimType == ANIM_SLIDE && timeDiff > TIME_SLIDE2 - TIME_HOLD) return false; + if (mAnimType == ANIM_BOTH && timeDiff > TIME_SLIDE2) return false; + + // determine phase and time in phase + int animStep = mAnimType; + if (mAnimType == ANIM_SLIDE) { + timeDiff += TIME_HOLD; + } + if (mAnimType == ANIM_SLIDE || mAnimType == ANIM_BOTH) { + if (timeDiff < TIME_HOLD) { + animStep = ANIM_FLASH; + } else if (timeDiff < TIME_SLIDE) { + animStep = ANIM_SLIDE; + timeDiff -= TIME_HOLD; + } else if (timeDiff < TIME_HOLD2) { + animStep = ANIM_HOLD2; + timeDiff -= TIME_SLIDE; + } else { + // SLIDE2 + animStep = ANIM_SLIDE2; + timeDiff -= TIME_HOLD2; + } + } + + if (animStep == ANIM_FLASH) { + review.draw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight); + if (timeDiff < TIME_FLASH) { + float f = 0.3f - 0.3f * timeDiff / TIME_FLASH; + int color = Color.argb((int) (255 * f), 255, 255, 255); + canvas.fillRect(mX, mY, mDrawWidth, mDrawHeight, color); + } + } else if (animStep == ANIM_SLIDE) { + float fraction = mSlideInterpolator.getInterpolation((float) (timeDiff) / (TIME_SLIDE - TIME_HOLD)); + float x = mX; + float y = mY; + float w = 0; + float h = 0; + x = interpolate(mX, mHoldX, fraction); + y = interpolate(mY, mHoldY, fraction); + w = interpolate(mDrawWidth, mHoldW, fraction); + h = interpolate(mDrawHeight, mHoldH, fraction); + preview.directDraw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight); + review.draw(canvas, (int) x, (int) y, (int) w, (int) h); + } else if (animStep == ANIM_HOLD2) { + preview.directDraw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight); + review.draw(canvas, mHoldX, mHoldY, mHoldW, mHoldH); + mBorder.draw(canvas, (int) mHoldX - mShadowSize, (int) mHoldY - mShadowSize, + (int) mHoldW + 2 * mShadowSize, (int) mHoldH + 2 * mShadowSize); + } else if (animStep == ANIM_SLIDE2) { + float fraction = (float)(timeDiff) / (TIME_SLIDE2 - TIME_HOLD2); + float x = mHoldX; + float y = mHoldY; + float d = mOffset * fraction; + switch (mAnimOrientation) { + case 0: + x = mHoldX + d; + break; + case 180: + x = mHoldX - d; + break; + case 90: + y = mHoldY - d; + break; + case 270: + y = mHoldY + d; + break; + } + preview.directDraw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight); + mBorder.draw(canvas, (int) x - mShadowSize, (int) y - mShadowSize, + (int) mHoldW + 2 * mShadowSize, (int) mHoldH + 2 * mShadowSize); + review.draw(canvas, (int) x, (int) y, mHoldW, mHoldH); + } + return true; + } + + private static float interpolate(float start, float end, float fraction) { + return start + (end - start) * fraction; + } + +} |