Tweeny  3.1.1
A Tweening library for modern C++
easing.h
1 /*
2  This file is part of the Tweeny library.
3 
4  Copyright (c) 2016-2020 Leonardo Guilherme Lucena de Freitas
5  Copyright (c) 2016 Guilherme R. Costa
6 
7  Permission is hereby granted, free of charge, to any person obtaining a copy of
8  this software and associated documentation files (the "Software"), to deal in
9  the Software without restriction, including without limitation the rights to
10  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  the Software, and to permit persons to whom the Software is furnished to do so,
12  subject to the following conditions:
13 
14  The above copyright notice and this permission notice shall be included in all
15  copies or substantial portions of the Software.
16 
17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24 
31 #ifndef TWEENY_EASING_H
32 #define TWEENY_EASING_H
33 
34 #include <cmath>
35 #include <type_traits>
36 
37 #ifndef M_PI
38 #define M_PI 3.14159265358979323846
39 #endif
40 
117 namespace tweeny {
130  class easing {
131  public:
136  static constexpr struct steppedEasing {
137  template<typename T>
138  static T run(float position, T start, T end) {
139  return start;
140  }
141  } stepped = steppedEasing{};
142 
147  static constexpr struct defaultEasing {
148  template<class...> struct voidify { using type = void; };
149  template<class... Ts> using void_t = typename voidify<Ts...>::type;
150 
151  template<class T, class = void>
152  struct supports_arithmetic_operations : std::false_type {};
153 
154  template<class T>
155  struct supports_arithmetic_operations<T, void_t<
156  decltype(std::declval<T>() + std::declval<T>()),
157  decltype(std::declval<T>() - std::declval<T>()),
158  decltype(std::declval<T>() * std::declval<T>()),
159  decltype(std::declval<T>() * std::declval<float>()),
160  decltype(std::declval<float>() * std::declval<T>())
161  >> : std::true_type{};
162 
163 
164  template<typename T>
165  static typename std::enable_if<std::is_integral<T>::value, T>::type run(float position, T start, T end) {
166  return static_cast<T>(roundf((end - start) * position + start));
167  }
168 
169  template<typename T>
170  static typename std::enable_if<supports_arithmetic_operations<T>::value && !std::is_integral<T>::value, T>::type run(float position, T start, T end) {
171  return static_cast<T>((end - start) * position + start);
172  }
173 
174  template<typename T>
175  static typename std::enable_if<!supports_arithmetic_operations<T>::value, T>::type run(float position, T start, T end) {
176  return start;
177  }
178  } def = defaultEasing{};
179 
184  static constexpr struct linearEasing {
185  template<typename T>
186  static typename std::enable_if<std::is_integral<T>::value, T>::type run(float position, T start, T end) {
187  return static_cast<T>(roundf((end - start) * position + start));
188  }
189 
190  template<typename T>
191  static typename std::enable_if<!std::is_integral<T>::value, T>::type run(float position, T start, T end) {
192  return static_cast<T>((end - start) * position + start);
193  }
194  } linear = linearEasing{};
195 
200  static constexpr struct quadraticInEasing {
201  template<typename T>
202  static T run(float position, T start, T end) {
203  return static_cast<T>((end - start) * position * position + start);
204  }
205  } quadraticIn = quadraticInEasing{};
206 
211  static constexpr struct quadraticOutEasing {
212  template<typename T>
213  static T run(float position, T start, T end) {
214  return static_cast<T>((-(end - start)) * position * (position - 2) + start);
215  }
216  } quadraticOut = quadraticOutEasing{};
217 
222  static constexpr struct quadraticInOutEasing {
223  template<typename T>
224  static T run(float position, T start, T end) {
225  position *= 2;
226  if (position < 1) {
227  return static_cast<T>(((end - start) / 2) * position * position + start);
228  }
229 
230  --position;
231  return static_cast<T>((-(end - start) / 2) * (position * (position - 2) - 1) + start);
232  }
233  } quadraticInOut = quadraticInOutEasing{};
234 
239  static constexpr struct cubicInEasing {
240  template<typename T>
241  static T run(float position, T start, T end) {
242  return static_cast<T>((end - start) * position * position * position + start);
243  }
244  } cubicIn = cubicInEasing{};
245 
250  static constexpr struct cubicOutEasing {
251  template<typename T>
252  static T run(float position, T start, T end) {
253  --position;
254  return static_cast<T>((end - start) * (position * position * position + 1) + start);
255  }
256  } cubicOut = cubicOutEasing{};
257 
262  static constexpr struct cubicInOutEasing {
263  template<typename T>
264  static T run(float position, T start, T end) {
265  position *= 2;
266  if (position < 1) {
267  return static_cast<T>(((end - start) / 2) * position * position * position + start);
268  }
269  position -= 2;
270  return static_cast<T>(((end - start) / 2) * (position * position * position + 2) + start);
271  }
272  } cubicInOut = cubicInOutEasing{};
273 
278  static constexpr struct quarticInEasing {
279  template<typename T>
280  static T run(float position, T start, T end) {
281  return static_cast<T>((end - start) * position * position * position * position + start);
282  }
283  } quarticIn = quarticInEasing{};
284 
289  static constexpr struct quarticOutEasing {
290  template<typename T>
291  static T run(float position, T start, T end) {
292  --position;
293  return static_cast<T>( -(end - start) * (position * position * position * position - 1) + start);
294  }
295  } quarticOut = quarticOutEasing{};
296 
301  static constexpr struct quarticInOutEasing {
302  template<typename T>
303  static T run(float position, T start, T end) {
304  position *= 2;
305  if (position < 1) {
306  return static_cast<T>(((end - start) / 2) * (position * position * position * position) +
307  start);
308  }
309  position -= 2;
310  return static_cast<T>((-(end - start) / 2) * (position * position * position * position - 2) +
311  start);
312  }
313  } quarticInOut = quarticInOutEasing{};
314 
319  static constexpr struct quinticInEasing {
320  template<typename T>
321  static T run(float position, T start, T end) {
322  return static_cast<T>((end - start) * position * position * position * position * position + start);
323  }
324  } quinticIn = quinticInEasing{};
325 
330  static constexpr struct quinticOutEasing {
331  template<typename T>
332  static T run(float position, T start, T end) {
333  position--;
334  return static_cast<T>((end - start) * (position * position * position * position * position + 1) +
335  start);
336  }
337  } quinticOut = quinticOutEasing{};
338 
343  static constexpr struct quinticInOutEasing {
344  template<typename T>
345  static T run(float position, T start, T end) {
346  position *= 2;
347  if (position < 1) {
348  return static_cast<T>(
349  ((end - start) / 2) * (position * position * position * position * position) +
350  start);
351  }
352  position -= 2;
353  return static_cast<T>(
354  ((end - start) / 2) * (position * position * position * position * position + 2) +
355  start);
356  }
357  } quinticInOut = quinticInOutEasing{};
358 
363  static constexpr struct sinusoidalInEasing {
364  template<typename T>
365  static T run(float position, T start, T end) {
366  return static_cast<T>(-(end - start) * cosf(position * static_cast<float>(M_PI) / 2) + (end - start) + start);
367  }
368  } sinusoidalIn = sinusoidalInEasing{};
369 
374  static constexpr struct sinusoidalOutEasing {
375  template<typename T>
376  static T run(float position, T start, T end) {
377  return static_cast<T>((end - start) * sinf(position * static_cast<float>(M_PI) / 2) + start);
378  }
379  } sinusoidalOut = sinusoidalOutEasing{};
380 
385  static constexpr struct sinusoidalInOutEasing {
386  template<typename T>
387  static T run(float position, T start, T end) {
388  return static_cast<T>((-(end - start) / 2) * (cosf(position * static_cast<float>(M_PI)) - 1) + start);
389  }
390  } sinusoidalInOut = sinusoidalInOutEasing{};
391 
396  static constexpr struct exponentialInEasing {
397  template<typename T>
398  static T run(float position, T start, T end) {
399  return static_cast<T>((end - start) * powf(2, 10 * (position - 1)) + start);
400  }
401  } exponentialIn = exponentialInEasing{};
402 
407  static constexpr struct exponentialOutEasing {
408  template<typename T>
409  static T run(float position, T start, T end) {
410  return static_cast<T>((end - start) * (-powf(2, -10 * position) + 1) + start);
411  }
412  } exponentialOut = exponentialOutEasing{};
413 
418  static constexpr struct exponentialInOutEasing {
419  template<typename T>
420  static T run(float position, T start, T end) {
421  position *= 2;
422  if (position < 1) {
423  return static_cast<T>(((end - start) / 2) * powf(2, 10 * (position - 1)) + start);
424  }
425  --position;
426  return static_cast<T>(((end - start) / 2) * (-powf(2, -10 * position) + 2) + start);
427  }
428  } exponentialInOut = exponentialInOutEasing{};
429 
434  static constexpr struct circularInEasing {
435  template<typename T>
436  static T run(float position, T start, T end) {
437  return static_cast<T>( -(end - start) * (sqrtf(1 - position * position) - 1) + start );
438  }
439  } circularIn = circularInEasing{};
440 
445  static constexpr struct circularOutEasing {
446  template<typename T>
447  static T run(float position, T start, T end) {
448  --position;
449  return static_cast<T>((end - start) * (sqrtf(1 - position * position)) + start);
450  }
451  } circularOut = circularOutEasing{};
452 
457  static constexpr struct circularInOutEasing {
458  template<typename T>
459  static T run(float position, T start, T end) {
460  position *= 2;
461  if (position < 1) {
462  return static_cast<T>((-(end - start) / 2) * (sqrtf(1 - position * position) - 1) + start);
463  }
464 
465  position -= 2;
466  return static_cast<T>(((end - start) / 2) * (sqrtf(1 - position * position) + 1) + start);
467  }
468  } circularInOut = circularInOutEasing{};
469 
474  static constexpr struct bounceInEasing {
475  template<typename T>
476  static T run(float position, T start, T end) {
477  return (end - start) - bounceOut.run((1 - position), T(), end) + start;
478  }
479  } bounceIn = bounceInEasing{};
480 
485  static constexpr struct bounceOutEasing {
486  template<typename T>
487  static T run(float position, T start, T end) {
488  T c = end - start;
489  if (position < (1 / 2.75f)) {
490  return static_cast<T>(c * (7.5625f * position * position) + start);
491  } else if (position < (2.0f / 2.75f)) {
492  float postFix = position -= (1.5f / 2.75f);
493  return static_cast<T>(c * (7.5625f * (postFix) * position + .75f) + start);
494  } else if (position < (2.5f / 2.75f)) {
495  float postFix = position -= (2.25f / 2.75f);
496  return static_cast<T>(c * (7.5625f * (postFix) * position + .9375f) + start);
497  } else {
498  float postFix = position -= (2.625f / 2.75f);
499  return static_cast<T>(c * (7.5625f * (postFix) * position + .984375f) + start);
500  }
501  }
502  } bounceOut = bounceOutEasing{};
503 
508  static constexpr struct bounceInOutEasing {
509  template<typename T>
510  static T run(float position, T start, T end) {
511  if (position < 0.5f) return static_cast<T>(bounceIn.run(position * 2, T(), end) * .5f + start);
512  else return static_cast<T>(bounceOut.run((position * 2 - 1), T(), end) * .5f + (end - start) * .5f + start);
513  }
514  } bounceInOut = bounceInOutEasing{};
515 
520  static constexpr struct elasticInEasing {
521  template<typename T>
522  static T run(float position, T start, T end) {
523  if (position <= 0.00001f) return start;
524  if (position >= 0.999f) return end;
525  float p = .3f;
526  auto a = end - start;
527  float s = p / 4;
528  float postFix =
529  a * powf(2, 10 * (position -= 1)); // this is a fix, again, with post-increment operators
530  return static_cast<T>(-(postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p)) + start);
531  }
532  } elasticIn = elasticInEasing{};
533 
538  static constexpr struct elasticOutEasing {
539  template<typename T>
540  static T run(float position, T start, T end) {
541  if (position <= 0.00001f) return start;
542  if (position >= 0.999f) return end;
543  float p = .3f;
544  auto a = end - start;
545  float s = p / 4;
546  return static_cast<T>(a * powf(2, -10 * position) * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p) + end);
547  }
548  } elasticOut = elasticOutEasing{};
549 
554  static constexpr struct elasticInOutEasing {
555  template<typename T>
556  static T run(float position, T start, T end) {
557  if (position <= 0.00001f) return start;
558  if (position >= 0.999f) return end;
559  position *= 2;
560  float p = (.3f * 1.5f);
561  auto a = end - start;
562  float s = p / 4;
563  float postFix;
564 
565  if (position < 1) {
566  postFix = a * powf(2, 10 * (position -= 1)); // postIncrement is evil
567  return static_cast<T>(-0.5f * (postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p)) + start);
568  }
569  postFix = a * powf(2, -10 * (position -= 1)); // postIncrement is evil
570  return static_cast<T>(postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p) * .5f + end);
571  }
572  } elasticInOut = elasticInOutEasing{};
573 
578  static constexpr struct backInEasing {
579  template<typename T>
580  static T run(float position, T start, T end) {
581  float s = 1.70158f;
582  float postFix = position;
583  return static_cast<T>((end - start) * (postFix) * position * ((s + 1) * position - s) + start);
584  }
585  } backIn = backInEasing{};
586 
591  static constexpr struct backOutEasing {
592  template<typename T>
593  static T run(float position, T start, T end) {
594  float s = 1.70158f;
595  position -= 1;
596  return static_cast<T>((end - start) * ((position) * position * ((s + 1) * position + s) + 1) + start);
597  }
598  } backOut = backOutEasing{};
599 
604  static constexpr struct backInOutEasing {
605  template<typename T>
606  static T run(float position, T start, T end) {
607  float s = 1.70158f;
608  float t = position;
609  auto b = start;
610  auto c = end - start;
611  float d = 1;
612  s *= (1.525f);
613  if ((t /= d / 2) < 1) return static_cast<T>(c / 2 * (t * t * (((s) + 1) * t - s)) + b);
614  float postFix = t -= 2;
615  return static_cast<T>(c / 2 * ((postFix) * t * (((s) + 1) * t + s) + 2) + b);
616  }
617  } backInOut = backInOutEasing{};
618  };
619 }
620 #endif //TWEENY_EASING_H
tweeny::easing::elasticInOutEasing
Acceelerate initial and deaccelerate ending values with an "elastic" equation.
Definition: easing.h:554
tweeny
The tweeny namespace contains all symbols and names for the Tweeny library.
Definition: MANUAL.dox:1
tweeny::easing::elasticInEasing
Acceelerate initial values with an "elastic" equation.
Definition: easing.h:520
tweeny::easing::quadraticInEasing
Accelerate initial values with a quadratic equation.
Definition: easing.h:200
tweeny::easing::quadraticInOutEasing
Acceelerate initial and deaccelerate ending values with a quadratic equation.
Definition: easing.h:222
tweeny::easing::backOutEasing
Deaccelerate ending values with a "back" equation.
Definition: easing.h:591
tweeny::easing::circularInEasing
Acceelerate initial values with a circular equation.
Definition: easing.h:434
tweeny::easing::quinticOutEasing
Deaccelerate ending values with a quintic equation.
Definition: easing.h:330
tweeny::easing::quarticInEasing
Acceelerate initial values with a quartic equation.
Definition: easing.h:278
tweeny::easing::defaultEasing
Values change with constant speed for arithmetic type only. The non-arithmetic it will be constant.
Definition: easing.h:147
tweeny::easing::quarticOutEasing
Deaccelerate ending values with a quartic equation.
Definition: easing.h:289
tweeny::easing::bounceOutEasing
Deaccelerate ending values with a "bounce" equation.
Definition: easing.h:485
tweeny::easing::circularOutEasing
Deaccelerate ending values with a circular equation.
Definition: easing.h:445
tweeny::easing::bounceInOutEasing
Acceelerate initial and deaccelerate ending values with a "bounce" equation.
Definition: easing.h:508
tweeny::easing::circularInOutEasing
Acceelerate initial and deaccelerate ending values with a circular equation.
Definition: easing.h:457
tweeny::easing::sinusoidalOutEasing
Deaccelerate ending values with a sinusoidal equation.
Definition: easing.h:374
tweeny::easing::sinusoidalInOutEasing
Acceelerate initial and deaccelerate ending values with a sinusoidal equation.
Definition: easing.h:385
tweeny::easing::cubicInEasing
Aaccelerate initial values with a cubic equation.
Definition: easing.h:239
tweeny::easing::backInOutEasing
Acceelerate initial and deaccelerate ending values with a "back" equation.
Definition: easing.h:604
tweeny::easing::quadraticOutEasing
Deaccelerate ending values with a quadratic equation.
Definition: easing.h:211
tweeny::easing
The easing class holds all the bundled easings.
Definition: easing.h:130
tweeny::easing::sinusoidalInEasing
Acceelerate initial values with a sinusoidal equation.
Definition: easing.h:363
tweeny::easing::exponentialInOutEasing
Acceelerate initial and deaccelerate ending values with an exponential equation.
Definition: easing.h:418
tweeny::easing::quinticInEasing
Acceelerate initial values with a quintic equation.
Definition: easing.h:319
tweeny::easing::exponentialInEasing
Acceelerate initial values with an exponential equation.
Definition: easing.h:396
tweeny::easing::exponentialOutEasing
Deaccelerate ending values with an exponential equation.
Definition: easing.h:407
tweeny::easing::cubicInOutEasing
Acceelerate initial and deaccelerate ending values with a cubic equation.
Definition: easing.h:262
tweeny::easing::quinticInOutEasing
Acceelerate initial and deaccelerate ending values with a quintic equation.
Definition: easing.h:343
tweeny::easing::linearEasing
Values change with constant speed.
Definition: easing.h:184
tweeny::easing::elasticOutEasing
Deaccelerate ending values with an "elastic" equation.
Definition: easing.h:538
tweeny::easing::quarticInOutEasing
Acceelerate initial and deaccelerate ending values with a quartic equation.
Definition: easing.h:301
tweeny::easing::cubicOutEasing
Deaccelerate ending values with a cubic equation.
Definition: easing.h:250
tweeny::easing::steppedEasing
Value is constant.
Definition: easing.h:136
tweeny::easing::backInEasing
Acceelerate initial values with a "back" equation.
Definition: easing.h:578
tweeny::easing::bounceInEasing
Acceelerate initial values with a "bounce" equation.
Definition: easing.h:474