friz
An animation control system for JUCE
Loading...
Searching...
No Matches
animatedValue.h
1/*
2 Copyright (c) 2019-2023 Brett g Porter
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21*/
22#pragma once
23
24namespace friz
25{
26
34{
35public:
41 AnimatedValue (float startVal_, float endVal_)
42 : startVal { startVal_ }
43 , endVal { endVal_ }
44 , currentVal { startVal_ } {
45
46 };
47
48 virtual ~AnimatedValue () = default;
49
59 virtual float getNextValue (int msElapsed, int msSinceLastUpdate) = 0;
60
68 float getEndValue () const { return endVal; }
69
76 virtual bool isFinished () = 0;
77
84 virtual bool updateTarget (float /*newValue*/) { return false; }
85
92 void cancel (bool moveToEndPosition)
93 {
94 if (!canceled)
95 {
96 canceled = true;
97 doCancel (moveToEndPosition);
98 }
99 }
100
101private:
105 virtual void doCancel (bool moveToEndPosition)
106 {
107 if (moveToEndPosition)
108 currentVal = endVal;
109 }
110
111protected:
112 float startVal;
113 float endVal;
114 float currentVal;
115
116 bool canceled { false };
117 bool finished { false };
118};
119
121{
122public:
123 ToleranceValue (float startVal, float endVal, float tolerance)
124 : AnimatedValue { startVal, endVal }
125 , tolerance { tolerance }
126 {
127 }
128
137 float getNextValue (int /*msElapsed*/, int msSinceLastUpdate) override
138 {
139 jassert (msSinceLastUpdate >= 0);
140 if (msSinceLastUpdate == 0)
141 return currentVal;
142
143 for (int i { 0 }; i < msSinceLastUpdate; ++i)
144 {
145 currentVal = snapToEnd (generateNextValue ());
146 if (isFinished ())
147 break;
148 }
149
150 return currentVal;
151 }
152
156 bool isFinished () override
157 {
158 // we are finished in either of these cases:
159 // 1. user/code canceled us
160 // 2. current value is within tolerance of the end value.
161 return (finished || canceled);
162 }
163
164private:
172 float snapToEnd (float val)
173 {
174 if (std::fabs (val - endVal) < tolerance)
175 {
176 finished = true;
177 return endVal;
178 }
179 return val;
180 }
181
187 virtual float generateNextValue () = 0;
188
189protected:
190 float tolerance;
191};
192
194{
195public:
196 TimedValue (float startVal, float endVal, int duration_)
197 : AnimatedValue { startVal, endVal }
198 , duration { duration_ }
199 {
200 }
201
202 float getNextValue (int msElapsed, int /* msSinceLastUpdate*/) override
203 {
204 if (msElapsed >= duration)
205 {
206 finished = true;
207 currentVal = endVal;
208 return currentVal;
209 }
210 float progress { static_cast<float> (msElapsed) / duration };
211 return generateNextValue (progress);
212 }
213
214 bool isFinished () override { return finished; }
215
216protected:
224 float scale (float curvePoint) { return startVal + curvePoint * (endVal - startVal); }
225
226private:
233 virtual float generateNextValue (float progress) = 0;
234
235protected:
238};
239
240// GCC doesn't support some functions that are specified in the standard:
241// std::sinf / cosf/ powf/ etc. (see
242// https://stackoverflow.com/questions/56417980/cosf-sinf-etc-are-not-in-std).
243// We define a few inline utility functions to narrow the return type of
244// the double-returning sin/cos/pow functions to float as we prefer here.
245// Thanks to [Sudara](https://github.com/sudara) for catching this.
246
247inline float sin_f (float v)
248{
249 return static_cast<float> (std::sin (v));
250}
251
252inline float cos_f (float v)
253{
254 return static_cast<float> (std::cos (v));
255}
256
257inline float pow_f (float v, float pow)
258{
259 return static_cast<float> (std::pow (v, pow));
260}
261
262} // namespace friz
Abstract base class for objects that can generate a useful series of values to drive UI animations.
Definition: animatedValue.h:34
virtual void doCancel(bool moveToEndPosition)
Definition: animatedValue.h:105
virtual float getNextValue(int msElapsed, int msSinceLastUpdate)=0
virtual bool isFinished()=0
void cancel(bool moveToEndPosition)
Cancel an in-progress animation.
Definition: animatedValue.h:92
virtual bool updateTarget(float)
Attempt to change the end value of an animation that's currently in process.
Definition: animatedValue.h:84
AnimatedValue(float startVal_, float endVal_)
Base class init for the animated value classes.
Definition: animatedValue.h:41
float getEndValue() const
get the ending state of this value object. When we cancel an in-progress animation,...
Definition: animatedValue.h:68
Definition: animatedValue.h:194
float getNextValue(int msElapsed, int) override
Definition: animatedValue.h:202
float scale(float curvePoint)
Given a fractional curve point (typically) in the range (0.f..1.f), interpolate this point between th...
Definition: animatedValue.h:224
bool isFinished() override
Definition: animatedValue.h:214
int duration
duration of the event in ms.
Definition: animatedValue.h:237
virtual float generateNextValue(float progress)=0
generate the value according to progress in time.
Definition: animatedValue.h:121
float snapToEnd(float val)
The underlying calculation (in floating point) may approach the desired end value asymptotically; we'...
Definition: animatedValue.h:172
virtual float generateNextValue()=0
Execute a single step of this curve's function.
bool isFinished() override
Test to see if this value has reached its end state.
Definition: animatedValue.h:156
float getNextValue(int, int msSinceLastUpdate) override
Calculate the next value in the sequence based on the delta time since last updated....
Definition: animatedValue.h:137