1/*
2 * Copyright (C) 2013 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
17package com.android.launcher3;
18
19import android.view.animation.AccelerateInterpolator;
20import android.view.animation.AnimationUtils;
21import android.view.animation.Interpolator;
22
23/**
24 * Scroller that gradually reaches a target velocity.
25 */
26class RampUpScroller {
27    private final Interpolator mInterpolator;
28    private final long mRampUpTime;
29
30    private long mStartTime;
31    private long mDeltaTime;
32    private float mTargetVelocityX;
33    private float mTargetVelocityY;
34    private int mDeltaX;
35    private int mDeltaY;
36
37    /**
38     * Creates a new ramp-up scroller that reaches full velocity after a
39     * specified duration.
40     *
41     * @param rampUpTime Duration before the scroller reaches target velocity.
42     */
43    public RampUpScroller(long rampUpTime) {
44        mInterpolator = new AccelerateInterpolator();
45        mRampUpTime = rampUpTime;
46    }
47
48    /**
49     * Starts the scroller at the current animation time.
50     */
51    public void start() {
52        mStartTime = AnimationUtils.currentAnimationTimeMillis();
53        mDeltaTime = mStartTime;
54    }
55
56    /**
57     * Computes the current scroll deltas. This usually only be called after
58     * starting the scroller with {@link #start()}.
59     *
60     * @see #getDeltaX()
61     * @see #getDeltaY()
62     */
63    public void computeScrollDelta() {
64        final long currentTime = AnimationUtils.currentAnimationTimeMillis();
65        final long elapsedSinceStart = currentTime - mStartTime;
66        final float scale;
67        if (elapsedSinceStart < mRampUpTime) {
68            scale = mInterpolator.getInterpolation((float) elapsedSinceStart / mRampUpTime);
69        } else {
70            scale = 1f;
71        }
72
73        final long elapsedSinceDelta = currentTime - mDeltaTime;
74        mDeltaTime = currentTime;
75
76        mDeltaX = (int) (elapsedSinceDelta * scale * mTargetVelocityX);
77        mDeltaY = (int) (elapsedSinceDelta * scale * mTargetVelocityY);
78    }
79
80    /**
81     * Sets the target velocity for this scroller.
82     *
83     * @param x The target X velocity in pixels per millisecond.
84     * @param y The target Y velocity in pixels per millisecond.
85     */
86    public void setTargetVelocity(float x, float y) {
87        mTargetVelocityX = x;
88        mTargetVelocityY = y;
89    }
90
91    /**
92     * @return The target X velocity for this scroller.
93     */
94    public float getTargetVelocityX() {
95        return mTargetVelocityX;
96    }
97
98    /**
99     * @return The target Y velocity for this scroller.
100     */
101    public float getTargetVelocityY() {
102        return mTargetVelocityY;
103    }
104
105    /**
106     * The distance traveled in the X-coordinate computed by the last call to
107     * {@link #computeScrollDelta()}.
108     */
109    public int getDeltaX() {
110        return mDeltaX;
111    }
112
113    /**
114     * The distance traveled in the Y-coordinate computed by the last call to
115     * {@link #computeScrollDelta()}.
116     */
117    public int getDeltaY() {
118        return mDeltaY;
119    }
120}
121