1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.gallery3d.anim;
18 
19 import android.view.animation.Interpolator;
20 
21 import com.android.gallery3d.common.Utils;
22 
23 // Animation calculates a value according to the current input time.
24 //
25 // 1. First we need to use setDuration(int) to set the duration of the
26 //    animation. The duration is in milliseconds.
27 // 2. Then we should call start(). The actual start time is the first value
28 //    passed to calculate(long).
29 // 3. Each time we want to get an animation value, we call
30 //    calculate(long currentTimeMillis) to ask the Animation to calculate it.
31 //    The parameter passed to calculate(long) should be nonnegative.
32 // 4. Use get() to get that value.
33 //
34 // In step 3, onCalculate(float progress) is called so subclasses can calculate
35 // the value according to progress (progress is a value in [0,1]).
36 //
37 // Before onCalculate(float) is called, There is an optional interpolator which
38 // can change the progress value. The interpolator can be set by
39 // setInterpolator(Interpolator). If the interpolator is used, the value passed
40 // to onCalculate may be (for example, the overshoot effect).
41 //
42 // The isActive() method returns true after the animation start() is called and
43 // before calculate is passed a value which reaches the duration of the
44 // animation.
45 //
46 // The start() method can be called again to restart the Animation.
47 //
48 abstract public class Animation {
49     private static final long ANIMATION_START = -1;
50     private static final long NO_ANIMATION = -2;
51 
52     private long mStartTime = NO_ANIMATION;
53     private int mDuration;
54     private Interpolator mInterpolator;
55 
setInterpolator(Interpolator interpolator)56     public void setInterpolator(Interpolator interpolator) {
57         mInterpolator = interpolator;
58     }
59 
setDuration(int duration)60     public void setDuration(int duration) {
61         mDuration = duration;
62     }
63 
start()64     public void start() {
65         mStartTime = ANIMATION_START;
66     }
67 
setStartTime(long time)68     public void setStartTime(long time) {
69         mStartTime = time;
70     }
71 
isActive()72     public boolean isActive() {
73         return mStartTime != NO_ANIMATION;
74     }
75 
forceStop()76     public void forceStop() {
77         mStartTime = NO_ANIMATION;
78     }
79 
calculate(long currentTimeMillis)80     public boolean calculate(long currentTimeMillis) {
81         if (mStartTime == NO_ANIMATION) return false;
82         if (mStartTime == ANIMATION_START) mStartTime = currentTimeMillis;
83         int elapse = (int) (currentTimeMillis - mStartTime);
84         float x = Utils.clamp((float) elapse / mDuration, 0f, 1f);
85         Interpolator i = mInterpolator;
86         onCalculate(i != null ? i.getInterpolation(x) : x);
87         if (elapse >= mDuration) mStartTime = NO_ANIMATION;
88         return mStartTime != NO_ANIMATION;
89     }
90 
onCalculate(float progress)91     abstract protected void onCalculate(float progress);
92 }
93