1 /*
2  * Copyright (C) 2018 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 androidx.constraintlayout.motion.utils;
18 
19 import androidx.constraintlayout.core.motion.utils.SpringStopEngine;
20 import androidx.constraintlayout.core.motion.utils.StopEngine;
21 import androidx.constraintlayout.core.motion.utils.StopLogicEngine;
22 import androidx.constraintlayout.motion.widget.MotionInterpolator;
23 
24 /**
25  * This contains the class to provide the logic for an animation to come to a stop.
26  * The setup defines a series of velocity gradients that gets to the desired position
27  * ending at 0 velocity.
28  * The path is computed such that the velocities are continuous
29  *
30  *
31  */
32 public class StopLogic extends MotionInterpolator {
33     private StopLogicEngine mStopLogicEngine = new StopLogicEngine();
34     private SpringStopEngine mSpringStopEngine;
35     private StopEngine mEngine = mStopLogicEngine;
36 
37     /**
38      * Debugging logic to log the state.
39      *
40      * @param desc Description to pre append
41      * @param time Time during animation
42      * @return string useful for debugging the state of the StopLogic
43      */
44 
debug(String desc, float time)45     public String debug(String desc, float time) {
46         return mEngine.debug(desc, time);
47     }
48 
49     /**
50      * Get the velocity at a point in time
51      * @param x
52      * @return
53      */
getVelocity(float x)54     public float getVelocity(float x) {
55         return mEngine.getVelocity(x);
56     }
57 
58     /**
59      * Configure the stop logic base on the parameters
60      * @param currentPos   start position
61      * @param destination  the ending position
62      * @param currentVelocity  the starting velocity
63      * @param maxTime   The maximum time to take
64      * @param maxAcceleration the maximum acceleration to use
65      * @param maxVelocity the maximum velocity to use
66      */
config(float currentPos, float destination, float currentVelocity, float maxTime, float maxAcceleration, float maxVelocity)67     public void config(float currentPos, float destination, float currentVelocity,
68                        float maxTime, float maxAcceleration, float maxVelocity) {
69         mEngine = mStopLogicEngine;
70         mStopLogicEngine.config(currentPos, destination, currentVelocity,
71                 maxTime, maxAcceleration, maxVelocity);
72     }
73 
74     /**
75      * This configure the stop logic to be a spring.
76      * Moving from currentPosition(P0)
77      * to destination with an initial velocity of currentVelocity (V0)
78      * moving as if it has a mass (m) with spring constant stiffness(k), and friction(c)
79      * It moves with the equation acceleration a = (-k.x-c.v)/m.
80      * x = current position - destination
81      * v is velocity
82      *
83      * @param currentPos The current position
84      * @param destination The destination position
85      * @param currentVelocity the initial velocity
86      * @param mass the mass
87      * @param stiffness the stiffness or spring constant (the force by which the spring pulls)
88      * @param damping the stiffness or spring constant. (the resistance to the motion)
89      * @param stopThreshold (When the max velocity of the movement is below this it stops)
90      * @param boundaryMode This controls if it overshoots or bounces when it hits 0 and 1
91      */
springConfig(float currentPos, float destination, float currentVelocity, float mass, float stiffness, float damping, float stopThreshold, int boundaryMode)92     public void springConfig(float currentPos, float destination, float currentVelocity,
93                              float mass, float stiffness, float damping, float stopThreshold,
94                              int boundaryMode) {
95         if (mSpringStopEngine == null) {
96             mSpringStopEngine = new SpringStopEngine();
97         }
98         mEngine = mSpringStopEngine;
99         mSpringStopEngine.springConfig(currentPos, destination, currentVelocity, mass, stiffness,
100                 damping, stopThreshold, boundaryMode);
101     }
102 
103     @Override
getInterpolation(float v)104     public float getInterpolation(float v) {
105         return mEngine.getInterpolation(v);
106     }
107 
108     @Override
getVelocity()109     public float getVelocity() {
110         return mEngine.getVelocity();
111     }
112 
isStopped()113     public boolean isStopped() {
114         return mEngine.isStopped();
115     }
116 }
117