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