2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
11 ///////////////////////////////////////////////////////////////////////
13 // A couple of tweening classes implemented in C++.
14 // ref: http://www.robertpenner.com/easing/
16 // Author: d4rk <d4rk@xbmc.org>
17 ///////////////////////////////////////////////////////////////////////
20 ///////////////////////////////////////////////////////////////////////
21 // Current list of classes:
32 ///////////////////////////////////////////////////////////////////////
37 #define M_PI 3.14159265358979323846
51 explicit Tweener(TweenerType tweenerType
= EASE_OUT
) { m_tweenerType
= tweenerType
; }
52 virtual ~Tweener() = default;
54 void SetEasing(TweenerType type
) { m_tweenerType
= type
; }
55 virtual float Tween(float time
, float start
, float change
, float duration
)=0;
56 virtual bool HasResumePoint() const { return m_tweenerType
== EASE_INOUT
; }
58 TweenerType m_tweenerType
;
62 class LinearTweener
: public Tweener
65 float Tween(float time
, float start
, float change
, float duration
) override
67 return change
* time
/ duration
+ start
;
69 bool HasResumePoint() const override
{ return false; }
73 class QuadTweener
: public Tweener
76 explicit QuadTweener(float a
= 1.0f
) { _a
=a
; }
77 float Tween(float time
, float start
, float change
, float duration
) override
79 switch (m_tweenerType
)
83 return change
* time
* (_a
* time
+ 1 - _a
) + start
;
88 return -change
* time
* (_a
* time
- 1 - _a
) + start
;
94 return (change
) * time
* (_a
* time
+ 1 - _a
) + start
;
96 return (-change
) * time
* (_a
* time
- 1 - _a
) + start
;
99 return change
* time
* time
+ start
;
106 class CubicTweener
: public Tweener
109 float Tween(float time
, float start
, float change
, float duration
) override
111 switch (m_tweenerType
)
115 return change
* time
* time
* time
+ start
;
121 return change
* (time
* time
* time
+ 1) + start
;
127 return (change
/2) * time
* time
* time
+ start
;
129 return (change
/2) * (time
* time
* time
+ 2) + start
;
132 return change
* time
* time
+ start
;
136 class CircleTweener
: public Tweener
139 float Tween(float time
, float start
, float change
, float duration
) override
141 switch (m_tweenerType
)
145 return (-change
) * (sqrt(1 - time
* time
) - 1) + start
;
151 return change
* sqrt(1 - time
* time
) + start
;
157 return (-change
/2) * (sqrt(1 - time
* time
) - 1) + start
;
159 return change
/2 * (sqrt(1 - time
* time
) + 1) + start
;
162 return change
* sqrt(1 - time
* time
) + start
;
166 class BackTweener
: public Tweener
169 explicit BackTweener(float s
=1.70158) { _s
=s
; }
171 float Tween(float time
, float start
, float change
, float duration
) override
174 switch (m_tweenerType
)
178 return change
* time
* time
* ((s
+ 1) * time
- s
) + start
;
184 return change
* (time
* time
* ((s
+ 1) * time
+ s
) + 1) + start
;
192 return (change
/2) * (time
* time
* ((s
+ 1) * time
- s
)) + start
;
195 return (change
/2) * (time
* time
* ((s
+ 1) * time
+ s
) + 2) + start
;
198 return change
* ((time
-1) * time
* ((s
+ 1) * time
+ s
) + 1) + start
;
206 class SineTweener
: public Tweener
209 float Tween(float time
, float start
, float change
, float duration
) override
212 switch (m_tweenerType
)
215 return change
* (1 - cos(time
* static_cast<float>(M_PI
) / 2.0f
)) + start
;
219 return change
* sin(time
* static_cast<float>(M_PI
) / 2.0f
) + start
;
223 return change
/ 2 * (1 - cos(static_cast<float>(M_PI
) * time
)) + start
;
226 return (change
/ 2) * (1 - cos(static_cast<float>(M_PI
) * time
)) + start
;
231 class BounceTweener
: public Tweener
234 float Tween(float time
, float start
, float change
, float duration
) override
236 switch (m_tweenerType
)
239 return (change
- easeOut(duration
- time
, 0, change
, duration
)) + start
;
243 return easeOut(time
, start
, change
, duration
);
247 if (time
< duration
/2)
248 return (change
- easeOut (duration
- (time
* 2), 0, change
, duration
) + start
) * .5f
+ start
;
250 return (easeOut (time
* 2 - duration
, 0, change
, duration
) * .5f
+ change
* .5f
) + start
;
254 return easeOut(time
, start
, change
, duration
);
257 static float easeOut(float time
, float start
, float change
, float duration
)
260 if (time
< (1 / 2.75f
))
262 return change
* (7.5625f
* time
* time
) + start
;
264 else if (time
< (2 / 2.75f
))
266 time
-= (1.5f
/2.75f
);
267 return change
* (7.5625f
* time
* time
+ .75f
) + start
;
269 else if (time
< (2.5f
/ 2.75f
))
271 time
-= (2.25f
/2.75f
);
272 return change
* (7.5625f
* time
* time
+ .9375f
) + start
;
276 time
-= (2.625f
/2.75f
);
277 return change
* (7.5625f
* time
* time
+ .984375f
) + start
;
283 class ElasticTweener
: public Tweener
286 ElasticTweener(float a
=0.0, float p
=0.0) { _a
=a
; _p
=p
; }
288 float Tween(float time
, float start
, float change
, float duration
) override
290 switch (m_tweenerType
)
293 return easeIn(time
, start
, change
, duration
);
297 return easeOut(time
, start
, change
, duration
);
301 return easeInOut(time
, start
, change
, duration
);
304 return easeOut(time
, start
, change
, duration
);
310 float easeIn(float time
, float start
, float change
, float duration
) const
320 return start
+ change
;
323 if (!a
|| a
< fabs(change
))
330 s
= p
/ (2 * static_cast<float>(M_PI
)) * asin(change
/ a
);
333 return -(a
* pow(2.0f
, 10 * time
) *
334 sin((time
* duration
- s
) * (2 * static_cast<float>(M_PI
)) / p
)) +
338 float easeOut(float time
, float start
, float change
, float duration
) const
348 return start
+ change
;
351 if (!a
|| a
< fabs(change
))
358 s
= p
/ (2 * static_cast<float>(M_PI
)) * asin(change
/ a
);
360 return (a
* pow(2.0f
, -10 * time
) *
361 sin((time
* duration
- s
) * (2 * static_cast<float>(M_PI
)) / p
)) +
365 float easeInOut(float time
, float start
, float change
, float duration
) const
375 return start
+ change
;
378 if (!a
|| a
< fabs(change
))
385 s
= p
/ (2 * static_cast<float>(M_PI
)) * asin(change
/ a
);
391 return -.5f
* (a
* pow(2.0f
, 10 * (time
)) *
392 sin((time
* duration
- s
) * (2 * static_cast<float>(M_PI
)) / p
)) +
396 return a
* pow(2.0f
, -10 * (time
)) *
397 sin((time
* duration
- s
) * (2 * static_cast<float>(M_PI
)) / p
) * .5f
+