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