1 #include "Animation.hpp"
2 #include "Color.hpp"
3 #include "src/DistrhoDefines.h"
4 #include "Mathf.hpp"
5 #include "Geometry.hpp"
6 #include "Widget.hpp"
7
8 #include <chrono>
9
10 START_NAMESPACE_DISTRHO
11
Animation(float duration,EasingFunction easingFunction)12 Animation::Animation(float duration, EasingFunction easingFunction) : fDuration(duration),
13 fCurrentTime(0.0f),
14 fSpeed(1.0f),
15 fTimeLastRun(std::chrono::steady_clock::now()),
16 fPlaybackDirection(Forward),
17 fRepeatMode(NoRepeat),
18 fEasingFunction(easingFunction),
19 fIsPlaying(false)
20
21 {
22 }
23
~Animation()24 Animation::~Animation()
25 {
26 }
27
play(PlaybackDirection playbackDirection,RepeatMode repeatMode)28 void Animation::play(PlaybackDirection playbackDirection, RepeatMode repeatMode)
29 {
30 fIsPlaying = true;
31
32 fPlaybackDirection = playbackDirection;
33 fRepeatMode = repeatMode;
34
35 fTimeLastRun = std::chrono::steady_clock::now();
36
37 onPlay();
38 }
39
onPlay()40 void Animation::onPlay()
41 {
42 }
43
onSeek()44 void Animation::onSeek()
45 {
46 }
47
onDurationChange()48 void Animation::onDurationChange()
49 {
50 }
51
onSpeedChange()52 void Animation::onSpeedChange()
53 {
54 }
55
pause()56 void Animation::pause()
57 {
58 fIsPlaying = false;
59 }
60
seek(float time)61 void Animation::seek(float time)
62 {
63 fCurrentTime = wolf::clamp(time, 0.0f, fDuration);
64 fTimeLastRun = std::chrono::steady_clock::now();
65
66 onSeek();
67 }
68
rewind()69 void Animation::rewind()
70 {
71 seek(0);
72 }
73
getCurrentTime()74 float Animation::getCurrentTime()
75 {
76 return fCurrentTime;
77 }
78
getDuration()79 float Animation::getDuration()
80 {
81 return fDuration;
82 }
83
setDuration(float duration)84 void Animation::setDuration(float duration)
85 {
86 fDuration = duration;
87
88 onDurationChange();
89 }
90
isPlaying()91 bool Animation::isPlaying()
92 {
93 return fIsPlaying;
94 }
95
applyEasing()96 void Animation::applyEasing()
97 {
98 //TODO
99 }
100
setSpeed(float speed)101 void Animation::setSpeed(float speed)
102 {
103 fSpeed = speed;
104
105 onSpeedChange();
106 }
107
synchronize()108 void Animation::synchronize()
109 {
110 using namespace std::chrono;
111 steady_clock::time_point now = steady_clock::now();
112
113 float deltaTime = duration_cast<duration<float>>((now - fTimeLastRun) * fSpeed).count();
114
115 if (fPlaybackDirection == Forward)
116 fCurrentTime = std::min(fDuration, fCurrentTime + deltaTime);
117 else
118 fCurrentTime = std::max(0.0f, fCurrentTime - deltaTime);
119
120 fTimeLastRun = now;
121 }
122
pauseIfDone()123 void Animation::pauseIfDone()
124 {
125 if ((fPlaybackDirection == Forward && fCurrentTime >= fDuration) || (fPlaybackDirection == Backward && fCurrentTime <= 0.0f))
126 {
127 this->pause();
128 }
129 }
130
FloatTransition()131 FloatTransition::FloatTransition() : Animation(0.0f, noEasing)
132 {
133 }
134
FloatTransition(float duration,float * initialValue,float targetValue,EasingFunction easingFunction)135 FloatTransition::FloatTransition(float duration, float *initialValue, float targetValue, EasingFunction easingFunction) : Animation(duration, easingFunction),
136 fInitialValue(*initialValue),
137 fCurrentValue(initialValue),
138 fTargetValue(targetValue)
139 {
140 }
141
~FloatTransition()142 FloatTransition::~FloatTransition()
143 {
144 }
145
applyEasing()146 void FloatTransition::applyEasing()
147 {
148 }
149
run()150 void FloatTransition::run()
151 {
152 synchronize();
153
154 //Just some cheap lerp for now
155 *fCurrentValue = wolf::lerp(fInitialValue, fTargetValue, fCurrentTime / fDuration);
156
157 pauseIfDone();
158 }
159
AnimationContainer(float duration,EasingFunction easingFunction)160 AnimationContainer::AnimationContainer(float duration, EasingFunction easingFunction) : Animation(duration, easingFunction)
161 {
162 }
163
~AnimationContainer()164 AnimationContainer::~AnimationContainer()
165 {
166 }
167
applyEasing()168 void AnimationContainer::applyEasing()
169 {
170 }
171
onPlay()172 void AnimationContainer::onPlay()
173 {
174 for (size_t i = 0; i < fAnimations.size(); ++i)
175 {
176 fAnimations[i]->play(fPlaybackDirection, fRepeatMode);
177 }
178 }
179
onSeek()180 void AnimationContainer::onSeek()
181 {
182 for (size_t i = 0; i < fAnimations.size(); ++i)
183 {
184 fAnimations[i]->seek(fCurrentTime);
185 }
186 }
187
onDurationChange()188 void AnimationContainer::onDurationChange()
189 {
190 for (size_t i = 0; i < fAnimations.size(); ++i)
191 {
192 fAnimations[i]->setDuration(fDuration);
193 }
194 }
195
onSpeedChange()196 void AnimationContainer::onSpeedChange()
197 {
198 for (size_t i = 0; i < fAnimations.size(); ++i)
199 {
200 fAnimations[i]->setSpeed(fSpeed);
201 }
202 }
203
run()204 void AnimationContainer::run()
205 {
206 synchronize();
207
208 for (size_t i = 0; i < fAnimations.size(); ++i)
209 {
210 fAnimations[i]->run();
211 }
212
213 pauseIfDone();
214 }
215
ColorTransition(float duration,Color * initialColor,Color targetColor,EasingFunction easingFunction)216 ColorTransition::ColorTransition(float duration, Color *initialColor, Color targetColor, EasingFunction easingFunction) : AnimationContainer(duration, easingFunction)
217 {
218 fAnimations = std::vector<std::shared_ptr<Animation>>(4);
219
220 fAnimations[0] = std::make_shared<FloatTransition>(duration, &initialColor->red, targetColor.red, easingFunction);
221 fAnimations[1] = std::make_shared<FloatTransition>(duration, &initialColor->green, targetColor.green, easingFunction);
222 fAnimations[2] = std::make_shared<FloatTransition>(duration, &initialColor->blue, targetColor.blue, easingFunction);
223 fAnimations[3] = std::make_shared<FloatTransition>(duration, &initialColor->alpha, targetColor.alpha, easingFunction);
224 }
225
~ColorTransition()226 ColorTransition::~ColorTransition()
227 {
228 }
229
GradientTransition()230 GradientTransition::GradientTransition() : AnimationContainer(0)
231 {
232 }
233
GradientTransition(float duration,NanoVG::Paint * initialGradient,NanoVG::Paint targetGradient,EasingFunction easingFunction)234 GradientTransition::GradientTransition(float duration, NanoVG::Paint *initialGradient, NanoVG::Paint targetGradient, EasingFunction easingFunction) : AnimationContainer(duration, easingFunction)
235 {
236 fAnimations = std::vector<std::shared_ptr<Animation>>(2);
237
238 fAnimations[0] = std::make_shared<ColorTransition>(duration, &initialGradient->innerColor, targetGradient.innerColor, easingFunction);
239 fAnimations[1] = std::make_shared<ColorTransition>(duration, &initialGradient->outerColor, targetGradient.outerColor, easingFunction);
240 }
241
~GradientTransition()242 GradientTransition::~GradientTransition()
243 {
244 }
245
246 END_NAMESPACE_DISTRHO