18e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong/* 28e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * Copyright (C) 2012 The Android Open Source Project 38e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * 48e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * Licensed under the Apache License, Version 2.0 (the "License"); 58e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * you may not use this file except in compliance with the License. 68e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * You may obtain a copy of the License at 78e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * 88e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * http://www.apache.org/licenses/LICENSE-2.0 98e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * 108e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * Unless required by applicable law or agreed to in writing, software 118e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * distributed under the License is distributed on an "AS IS" BASIS, 128e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * See the License for the specific language governing permissions and 148e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * limitations under the License. 158e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong */ 168e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong 178e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kongpackage com.android.camera; 188e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong 198433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolbimport android.graphics.Color; 20e5a7c7c22c1d8eced943a745c68f80a9e6d44eb4Owen Linimport android.os.SystemClock; 218e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kongimport android.view.animation.DecelerateInterpolator; 228e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kongimport android.view.animation.Interpolator; 23351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong 24bd1fa33e0f0f9b600f286bea8aa041373518b73cJohn Reckimport com.android.gallery3d.glrenderer.GLCanvas; 25bd1fa33e0f0f9b600f286bea8aa041373518b73cJohn Reckimport com.android.gallery3d.glrenderer.RawTexture; 268e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong 278e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong/** 288e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * Class to handle the capture animation. 298e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong */ 30351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kongpublic class CaptureAnimManager { 31dac1bb32531f7f4d49622bd38c82dde9333c38acAhbong Chang @SuppressWarnings("unused") 328433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb private static final String TAG = "CAM_Capture"; 336f51b6d8ac0bf871c1268f742cf004f9c2477d03Michael Kolb private static final int TIME_FLASH = 200; 34d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck private static final int TIME_HOLD = 400; 356f51b6d8ac0bf871c1268f742cf004f9c2477d03Michael Kolb private static final int TIME_SLIDE = 400; // milliseconds. 36351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong 37d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck private static final int ANIM_BOTH = 0; 38d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck private static final int ANIM_FLASH = 1; 39d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck private static final int ANIM_SLIDE = 2; 40d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck 418433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb private final Interpolator mSlideInterpolator = new DecelerateInterpolator(); 42351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong 43351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong private int mAnimOrientation; // Could be 0, 90, 180 or 270 degrees. 44351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong private long mAnimStartTime; // milliseconds. 458433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb private float mX; // The center of the whole view including preview and review. 468433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb private float mY; 478433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb private float mDelta; 48351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong private int mDrawWidth; 49351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong private int mDrawHeight; 5070d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck private int mAnimType; 518e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong 528e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong /* preview: camera preview view. 538e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong * review: view of picture just taken. 548e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong */ 55351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong public CaptureAnimManager() { 56351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong } 578e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong 58d0d0e26a7de012a19420fe1640d82b9430f0a4f7John Reck public void setOrientation(int displayRotation) { 59d0d0e26a7de012a19420fe1640d82b9430f0a4f7John Reck mAnimOrientation = (360 - displayRotation) % 360; 603a5b0163009c43a2e2969568baa5fe0efbaf07f5Wu-cheng Li } 618e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong 6270d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck public void animateSlide() { 6370d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck if (mAnimType != ANIM_FLASH) { 6470d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck return; 6570d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck } 6670d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck mAnimType = ANIM_SLIDE; 6770d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck mAnimStartTime = SystemClock.uptimeMillis(); 6870d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck } 6970d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck 70d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck public void animateFlash() { 71d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck mAnimType = ANIM_FLASH; 72d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck } 73d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck 74d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck public void animateFlashAndSlide() { 75d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck mAnimType = ANIM_BOTH; 76d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck } 77d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck 78a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li // x, y, w and h: the rectangle area where the animation takes place. 79e5a7c7c22c1d8eced943a745c68f80a9e6d44eb4Owen Lin public void startAnimation(int x, int y, int w, int h) { 80351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong mAnimStartTime = SystemClock.uptimeMillis(); 81351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong // Set the views to the initial positions. 82351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong mDrawWidth = w; 83351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong mDrawHeight = h; 848433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb mX = x; 858433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb mY = y; 86351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong switch (mAnimOrientation) { 87351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong case 0: // Preview is on the left. 888433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb mDelta = w; 89351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong break; 90351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong case 90: // Preview is below. 918433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb mDelta = -h; 92351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong break; 93351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong case 180: // Preview on the right. 948433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb mDelta = -w; 95351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong break; 96351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong case 270: // Preview is above. 978433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb mDelta = h; 98351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong break; 99351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong } 1008e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong } 1018e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong 102351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong // Returns true if the animation has been drawn. 103351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong public boolean drawAnimation(GLCanvas canvas, CameraScreenNail preview, 104e5a7c7c22c1d8eced943a745c68f80a9e6d44eb4Owen Lin RawTexture review) { 105e5a7c7c22c1d8eced943a745c68f80a9e6d44eb4Owen Lin long timeDiff = SystemClock.uptimeMillis() - mAnimStartTime; 10670d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck // Check if the animation is over 10770d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck if (mAnimType == ANIM_SLIDE && timeDiff > TIME_SLIDE) return false; 108d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck if (mAnimType == ANIM_BOTH && timeDiff > TIME_HOLD + TIME_SLIDE) return false; 109d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck 110d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck int animStep = mAnimType; 111d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck if (mAnimType == ANIM_BOTH) { 112d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck animStep = (timeDiff < TIME_HOLD) ? ANIM_FLASH : ANIM_SLIDE; 113d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck if (animStep == ANIM_SLIDE) { 114d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck timeDiff -= TIME_HOLD; 115d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck } 116d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck } 11770d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck 118d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck if (animStep == ANIM_FLASH) { 1198433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb review.draw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight); 1208433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb if (timeDiff < TIME_FLASH) { 1216f51b6d8ac0bf871c1268f742cf004f9c2477d03Michael Kolb float f = 0.3f - 0.3f * timeDiff / TIME_FLASH; 1226f51b6d8ac0bf871c1268f742cf004f9c2477d03Michael Kolb int color = Color.argb((int) (255 * f), 255, 255, 255); 1236f51b6d8ac0bf871c1268f742cf004f9c2477d03Michael Kolb canvas.fillRect(mX, mY, mDrawWidth, mDrawHeight, color); 1248433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb } 125d1dccd2ec153a8aaa66e82b387cb42bb784c5a3aJohn Reck } else if (animStep == ANIM_SLIDE) { 12670d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck float fraction = (float) (timeDiff) / TIME_SLIDE; 1278433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb float x = mX; 1288433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb float y = mY; 1298433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb if (mAnimOrientation == 0 || mAnimOrientation == 180) { 1308433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb x = x + mDelta * mSlideInterpolator.getInterpolation(fraction); 1318433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb } else { 1328433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb y = y + mDelta * mSlideInterpolator.getInterpolation(fraction); 1338433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb } 1348433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb // float alpha = canvas.getAlpha(); 1358433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb // canvas.setAlpha(fraction); 1368433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb preview.directDraw(canvas, (int) mX, (int) mY, 1378433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb mDrawWidth, mDrawHeight); 1388433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb // canvas.setAlpha(alpha); 139351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong 1408433d827e91a5e62ecdea8b4c31d10f9599cd431Michael Kolb review.draw(canvas, (int) x, (int) y, mDrawWidth, mDrawHeight); 14170d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck } else { 14270d41293e9dad8be7a1f2c556ff7c7334a60c8f5John Reck return false; 1438e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong } 144351b7a85f40c6a2bcb5fb0e7eeb61002c376bb29Angus Kong return true; 1458e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong } 1468e0d8358b0ad36774cdbc0f0322ce7bdf5028458Angus Kong} 147