137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling/* 237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * Copyright (C) 2013 The Android Open Source Project 337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * 437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * Licensed under the Apache License, Version 2.0 (the "License"); 537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * you may not use this file except in compliance with the License. 637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * You may obtain a copy of the License at 737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * 837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * http://www.apache.org/licenses/LICENSE-2.0 937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * 1037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * Unless required by applicable law or agreed to in writing, software 1137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * distributed under the License is distributed on an "AS IS" BASIS, 1237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * See the License for the specific language governing permissions and 1437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * limitations under the License. 1537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling */ 1637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 1737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingpackage com.android.camera; 1837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 1937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.animation.Animator; 2037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.animation.AnimatorSet; 2137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.animation.ObjectAnimator; 2237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.view.View; 2337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 2437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling/** 2537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * Class to handle animations. 2637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling */ 2737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 2837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingpublic class AnimationManager { 2937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 3037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public static final float FLASH_ALPHA_START = 0.3f; 3137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public static final float FLASH_ALPHA_END = 0f; 3237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public static final int FLASH_DURATION = 300; 3337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 3437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public static final int SHRINK_DURATION = 400; 3537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public static final int HOLD_DURATION = 2500; 3637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public static final int SLIDE_DURATION = 1100; 3737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 3837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling private ObjectAnimator mFlashAnim; 3937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling private AnimatorSet mCaptureAnimator; 4037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 4137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling /** 4237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * Starts capture animation. 4337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * @param view a thumbnail view that shows a picture captured and gets animated 4437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling */ 4537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void startCaptureAnimation(final View view) { 4637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling if (mCaptureAnimator != null && mCaptureAnimator.isStarted()) { 4737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mCaptureAnimator.cancel(); 4837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 4937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling View parentView = (View) view.getParent(); 5037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling float slideDistance = (float) (parentView.getWidth() - view.getLeft()); 5137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 5237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling float scaleX = ((float) parentView.getWidth()) / ((float) view.getWidth()); 5337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling float scaleY = ((float) parentView.getHeight()) / ((float) view.getHeight()); 5437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling float scale = scaleX > scaleY ? scaleX : scaleY; 5537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 5637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling int centerX = view.getLeft() + view.getWidth() / 2; 5737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling int centerY = view.getTop() + view.getHeight() / 2; 5837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 5937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling ObjectAnimator slide = ObjectAnimator.ofFloat(view, "translationX", 0f, slideDistance) 6037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling .setDuration(AnimationManager.SLIDE_DURATION); 6137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling slide.setStartDelay(AnimationManager.SHRINK_DURATION + AnimationManager.HOLD_DURATION); 6293a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong 6393a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong ObjectAnimator translateY = ObjectAnimator.ofFloat(view, "translationY", 6493a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong parentView.getHeight() / 2 - centerY, 0f) 6593a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong .setDuration(AnimationManager.SHRINK_DURATION); 6693a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong translateY.addListener(new Animator.AnimatorListener() { 6793a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong @Override 6893a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong public void onAnimationStart(Animator animator) { 6993a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong // Do nothing. 7093a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong } 7193a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong 7293a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong @Override 7393a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong public void onAnimationEnd(Animator animator) { 7493a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong view.setClickable(true); 7593a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong } 7693a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong 7793a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong @Override 7893a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong public void onAnimationCancel(Animator animator) { 7993a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong // Do nothing. 8093a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong } 8193a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong 8293a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong @Override 8393a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong public void onAnimationRepeat(Animator animator) { 8493a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong // Do nothing. 8593a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong } 8693a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong }); 8793a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong 8837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mCaptureAnimator = new AnimatorSet(); 8937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mCaptureAnimator.playTogether( 9037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling ObjectAnimator.ofFloat(view, "scaleX", scale, 1f) 9137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling .setDuration(AnimationManager.SHRINK_DURATION), 9237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling ObjectAnimator.ofFloat(view, "scaleY", scale, 1f) 9337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling .setDuration(AnimationManager.SHRINK_DURATION), 9437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling ObjectAnimator.ofFloat(view, "translationX", 9537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling parentView.getWidth() / 2 - centerX, 0f) 9637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling .setDuration(AnimationManager.SHRINK_DURATION), 9793a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong translateY, 9837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling slide); 9937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mCaptureAnimator.addListener(new Animator.AnimatorListener() { 10037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling @Override 10137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void onAnimationStart(Animator animator) { 10293a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong view.setClickable(false); 10337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling view.setVisibility(View.VISIBLE); 10437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 10537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 10637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling @Override 10737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void onAnimationEnd(Animator animator) { 10837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling view.setScaleX(1f); 10937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling view.setScaleX(1f); 11037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling view.setTranslationX(0f); 11137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling view.setTranslationY(0f); 11237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling view.setVisibility(View.INVISIBLE); 11337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mCaptureAnimator.removeAllListeners(); 11437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mCaptureAnimator = null; 11537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 11637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 11737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling @Override 11837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void onAnimationCancel(Animator animator) { 11937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling view.setVisibility(View.INVISIBLE); 12037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 12137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 12237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling @Override 12337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void onAnimationRepeat(Animator animator) { 12437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling // Do nothing. 12537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 12637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling }); 12737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mCaptureAnimator.start(); 12837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 12937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 13037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling /** 13137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * Starts flash animation. 13237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * @params flashOverlay the overlay that will animate on alpha to make the flash impression 13337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling */ 13437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void startFlashAnimation(final View flashOverlay) { 13537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling // End the previous animation if the previous one is still running 13637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling if (mFlashAnim != null && mFlashAnim.isRunning()) { 13737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mFlashAnim.cancel(); 13837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 13937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling // Start new flash animation. 14037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mFlashAnim = ObjectAnimator.ofFloat(flashOverlay, "alpha", 14137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling AnimationManager.FLASH_ALPHA_START, AnimationManager.FLASH_ALPHA_END); 14237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mFlashAnim.setDuration(AnimationManager.FLASH_DURATION); 14337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mFlashAnim.addListener(new Animator.AnimatorListener() { 14437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling @Override 14537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void onAnimationStart(Animator animator) { 14637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling flashOverlay.setVisibility(View.VISIBLE); 14737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 14837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 14937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling @Override 15037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void onAnimationEnd(Animator animator) { 15137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling flashOverlay.setAlpha(0f); 15237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling flashOverlay.setVisibility(View.GONE); 15337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mFlashAnim.removeAllListeners(); 15437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mFlashAnim = null; 15537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 15637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 15737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling @Override 15837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void onAnimationCancel(Animator animator) { 15937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling // Do nothing. 16037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 16137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 16237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling @Override 16337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void onAnimationRepeat(Animator animator) { 16437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling // Do nothing. 16537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 16637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling }); 16737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mFlashAnim.start(); 16837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 16937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling 17037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling /** 17137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling * Cancels on-going flash animation and capture animation, if any. 17237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling */ 17337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling public void cancelAnimations() { 17437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling // End the previous animation if the previous one is still running 17537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling if (mFlashAnim != null && mFlashAnim.isRunning()) { 17637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mFlashAnim.cancel(); 17737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 17837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling if (mCaptureAnimator != null && mCaptureAnimator.isStarted()) { 17937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mCaptureAnimator.cancel(); 18037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 18137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 18293a38d80b202a95cc0336e5cc04dbad92e43253dAngus Kong} 183