Tweeny  3.2.0
A Tweening library for modern C++
easing.h
1 /*
2  This file is part of the Tweeny library.
3 
4  Copyright (c) 2016-2021 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:
138  enum class enumerated {
139  def,
140  linear,
141  stepped,
142  quadraticIn,
143  quadraticOut,
144  quadraticInOut,
145  cubicIn,
146  cubicOut,
147  cubicInOut,
148  quarticIn,
149  quarticOut,
150  quarticInOut,
151  quinticIn,
152  quinticOut,
153  quinticInOut,
154  sinusoidalIn,
155  sinusoidalOut,
156  sinusoidalInOut,
157  exponentialIn,
158  exponentialOut,
159  exponentialInOut,
160  circularIn,
161  circularOut,
162  circularInOut,
163  bounceIn,
164  bounceOut,
165  bounceInOut,
166  elasticIn,
167  elasticOut,
168  elasticInOut,
169  backIn,
170  backOut,
171  backInOut
172  };
173 
178  static constexpr struct steppedEasing {
179  template<typename T>
180  static T run(float position, T start, T end) {
181  return start;
182  }
183  } stepped = steppedEasing{};
184 
189  static constexpr struct defaultEasing {
190  template<class...> struct voidify { using type = void; };
191  template<class... Ts> using void_t = typename voidify<Ts...>::type;
192 
193  template<class T, class = void>
194  struct supports_arithmetic_operations : std::false_type {};
195 
196  template<class T>
197  struct supports_arithmetic_operations<T, void_t<
198  decltype(std::declval<T>() + std::declval<T>()),
199  decltype(std::declval<T>() - std::declval<T>()),
200  decltype(std::declval<T>() * std::declval<T>()),
201  decltype(std::declval<T>() * std::declval<float>()),
202  decltype(std::declval<float>() * std::declval<T>())
203  >> : std::true_type{};
204 
205 
206  template<typename T>
207  static typename std::enable_if<std::is_integral<T>::value, T>::type run(float position, T start, T end) {
208  return static_cast<T>(roundf((end - start) * position + start));
209  }
210 
211  template<typename T>
212  static typename std::enable_if<supports_arithmetic_operations<T>::value && !std::is_integral<T>::value, T>::type run(float position, T start, T end) {
213  return static_cast<T>((end - start) * position + start);
214  }
215 
216  template<typename T>
217  static typename std::enable_if<!supports_arithmetic_operations<T>::value, T>::type run(float position, T start, T end) {
218  return start;
219  }
220  } def = defaultEasing{};
221 
226  static constexpr struct linearEasing {
227  template<typename T>
228  static typename std::enable_if<std::is_integral<T>::value, T>::type run(float position, T start, T end) {
229  return static_cast<T>(roundf((end - start) * position + start));
230  }
231 
232  template<typename T>
233  static typename std::enable_if<!std::is_integral<T>::value, T>::type run(float position, T start, T end) {
234  return static_cast<T>((end - start) * position + start);
235  }
236  } linear = linearEasing{};
237 
242  static constexpr struct quadraticInEasing {
243  template<typename T>
244  static T run(float position, T start, T end) {
245  return static_cast<T>((end - start) * position * position + start);
246  }
247  } quadraticIn = quadraticInEasing{};
248 
253  static constexpr struct quadraticOutEasing {
254  template<typename T>
255  static T run(float position, T start, T end) {
256  return static_cast<T>((-(end - start)) * position * (position - 2) + start);
257  }
258  } quadraticOut = quadraticOutEasing{};
259 
264  static constexpr struct quadraticInOutEasing {
265  template<typename T>
266  static T run(float position, T start, T end) {
267  position *= 2;
268  if (position < 1) {
269  return static_cast<T>(((end - start) / 2) * position * position + start);
270  }
271 
272  --position;
273  return static_cast<T>((-(end - start) / 2) * (position * (position - 2) - 1) + start);
274  }
275  } quadraticInOut = quadraticInOutEasing{};
276 
281  static constexpr struct cubicInEasing {
282  template<typename T>
283  static T run(float position, T start, T end) {
284  return static_cast<T>((end - start) * position * position * position + start);
285  }
286  } cubicIn = cubicInEasing{};
287 
292  static constexpr struct cubicOutEasing {
293  template<typename T>
294  static T run(float position, T start, T end) {
295  --position;
296  return static_cast<T>((end - start) * (position * position * position + 1) + start);
297  }
298  } cubicOut = cubicOutEasing{};
299 
304  static constexpr struct cubicInOutEasing {
305  template<typename T>
306  static T run(float position, T start, T end) {
307  position *= 2;
308  if (position < 1) {
309  return static_cast<T>(((end - start) / 2) * position * position * position + start);
310  }
311  position -= 2;
312  return static_cast<T>(((end - start) / 2) * (position * position * position + 2) + start);
313  }
314  } cubicInOut = cubicInOutEasing{};
315 
320  static constexpr struct quarticInEasing {
321  template<typename T>
322  static T run(float position, T start, T end) {
323  return static_cast<T>((end - start) * position * position * position * position + start);
324  }
325  } quarticIn = quarticInEasing{};
326 
331  static constexpr struct quarticOutEasing {
332  template<typename T>
333  static T run(float position, T start, T end) {
334  --position;
335  return static_cast<T>( -(end - start) * (position * position * position * position - 1) + start);
336  }
337  } quarticOut = quarticOutEasing{};
338 
343  static constexpr struct quarticInOutEasing {
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>(((end - start) / 2) * (position * position * position * position) +
349  start);
350  }
351  position -= 2;
352  return static_cast<T>((-(end - start) / 2) * (position * position * position * position - 2) +
353  start);
354  }
355  } quarticInOut = quarticInOutEasing{};
356 
361  static constexpr struct quinticInEasing {
362  template<typename T>
363  static T run(float position, T start, T end) {
364  return static_cast<T>((end - start) * position * position * position * position * position + start);
365  }
366  } quinticIn = quinticInEasing{};
367 
372  static constexpr struct quinticOutEasing {
373  template<typename T>
374  static T run(float position, T start, T end) {
375  position--;
376  return static_cast<T>((end - start) * (position * position * position * position * position + 1) +
377  start);
378  }
379  } quinticOut = quinticOutEasing{};
380 
385  static constexpr struct quinticInOutEasing {
386  template<typename T>
387  static T run(float position, T start, T end) {
388  position *= 2;
389  if (position < 1) {
390  return static_cast<T>(
391  ((end - start) / 2) * (position * position * position * position * position) +
392  start);
393  }
394  position -= 2;
395  return static_cast<T>(
396  ((end - start) / 2) * (position * position * position * position * position + 2) +
397  start);
398  }
399  } quinticInOut = quinticInOutEasing{};
400 
405  static constexpr struct sinusoidalInEasing {
406  template<typename T>
407  static T run(float position, T start, T end) {
408  return static_cast<T>(-(end - start) * cosf(position * static_cast<float>(M_PI) / 2) + (end - start) + start);
409  }
410  } sinusoidalIn = sinusoidalInEasing{};
411 
416  static constexpr struct sinusoidalOutEasing {
417  template<typename T>
418  static T run(float position, T start, T end) {
419  return static_cast<T>((end - start) * sinf(position * static_cast<float>(M_PI) / 2) + start);
420  }
421  } sinusoidalOut = sinusoidalOutEasing{};
422 
427  static constexpr struct sinusoidalInOutEasing {
428  template<typename T>
429  static T run(float position, T start, T end) {
430  return static_cast<T>((-(end - start) / 2) * (cosf(position * static_cast<float>(M_PI)) - 1) + start);
431  }
432  } sinusoidalInOut = sinusoidalInOutEasing{};
433 
438  static constexpr struct exponentialInEasing {
439  template<typename T>
440  static T run(float position, T start, T end) {
441  return static_cast<T>((end - start) * powf(2, 10 * (position - 1)) + start);
442  }
443  } exponentialIn = exponentialInEasing{};
444 
449  static constexpr struct exponentialOutEasing {
450  template<typename T>
451  static T run(float position, T start, T end) {
452  return static_cast<T>((end - start) * (-powf(2, -10 * position) + 1) + start);
453  }
454  } exponentialOut = exponentialOutEasing{};
455 
460  static constexpr struct exponentialInOutEasing {
461  template<typename T>
462  static T run(float position, T start, T end) {
463  position *= 2;
464  if (position < 1) {
465  return static_cast<T>(((end - start) / 2) * powf(2, 10 * (position - 1)) + start);
466  }
467  --position;
468  return static_cast<T>(((end - start) / 2) * (-powf(2, -10 * position) + 2) + start);
469  }
470  } exponentialInOut = exponentialInOutEasing{};
471 
476  static constexpr struct circularInEasing {
477  template<typename T>
478  static T run(float position, T start, T end) {
479  return static_cast<T>( -(end - start) * (sqrtf(1 - position * position) - 1) + start );
480  }
481  } circularIn = circularInEasing{};
482 
487  static constexpr struct circularOutEasing {
488  template<typename T>
489  static T run(float position, T start, T end) {
490  --position;
491  return static_cast<T>((end - start) * (sqrtf(1 - position * position)) + start);
492  }
493  } circularOut = circularOutEasing{};
494 
499  static constexpr struct circularInOutEasing {
500  template<typename T>
501  static T run(float position, T start, T end) {
502  position *= 2;
503  if (position < 1) {
504  return static_cast<T>((-(end - start) / 2) * (sqrtf(1 - position * position) - 1) + start);
505  }
506 
507  position -= 2;
508  return static_cast<T>(((end - start) / 2) * (sqrtf(1 - position * position) + 1) + start);
509  }
510  } circularInOut = circularInOutEasing{};
511 
516  static constexpr struct bounceInEasing {
517  template<typename T>
518  static T run(float position, T start, T end) {
519  return (end - start) - bounceOut.run((1 - position), T(), end) + start;
520  }
521  } bounceIn = bounceInEasing{};
522 
527  static constexpr struct bounceOutEasing {
528  template<typename T>
529  static T run(float position, T start, T end) {
530  T c = end - start;
531  if (position < (1 / 2.75f)) {
532  return static_cast<T>(c * (7.5625f * position * position) + start);
533  } else if (position < (2.0f / 2.75f)) {
534  float postFix = position -= (1.5f / 2.75f);
535  return static_cast<T>(c * (7.5625f * (postFix) * position + .75f) + start);
536  } else if (position < (2.5f / 2.75f)) {
537  float postFix = position -= (2.25f / 2.75f);
538  return static_cast<T>(c * (7.5625f * (postFix) * position + .9375f) + start);
539  } else {
540  float postFix = position -= (2.625f / 2.75f);
541  return static_cast<T>(c * (7.5625f * (postFix) * position + .984375f) + start);
542  }
543  }
544  } bounceOut = bounceOutEasing{};
545 
550  static constexpr struct bounceInOutEasing {
551  template<typename T>
552  static T run(float position, T start, T end) {
553  if (position < 0.5f) return static_cast<T>(bounceIn.run(position * 2, T(), end) * .5f + start);
554  else return static_cast<T>(bounceOut.run((position * 2 - 1), T(), end) * .5f + (end - start) * .5f + start);
555  }
556  } bounceInOut = bounceInOutEasing{};
557 
562  static constexpr struct elasticInEasing {
563  template<typename T>
564  static T run(float position, T start, T end) {
565  if (position <= 0.00001f) return start;
566  if (position >= 0.999f) return end;
567  float p = .3f;
568  auto a = end - start;
569  float s = p / 4;
570  float postFix =
571  a * powf(2, 10 * (position -= 1)); // this is a fix, again, with post-increment operators
572  return static_cast<T>(-(postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p)) + start);
573  }
574  } elasticIn = elasticInEasing{};
575 
580  static constexpr struct elasticOutEasing {
581  template<typename T>
582  static T run(float position, T start, T end) {
583  if (position <= 0.00001f) return start;
584  if (position >= 0.999f) return end;
585  float p = .3f;
586  auto a = end - start;
587  float s = p / 4;
588  return static_cast<T>(a * powf(2, -10 * position) * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p) + end);
589  }
590  } elasticOut = elasticOutEasing{};
591 
596  static constexpr struct elasticInOutEasing {
597  template<typename T>
598  static T run(float position, T start, T end) {
599  if (position <= 0.00001f) return start;
600  if (position >= 0.999f) return end;
601  position *= 2;
602  float p = (.3f * 1.5f);
603  auto a = end - start;
604  float s = p / 4;
605  float postFix;
606 
607  if (position < 1) {
608  postFix = a * powf(2, 10 * (position -= 1)); // postIncrement is evil
609  return static_cast<T>(-0.5f * (postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p)) + start);
610  }
611  postFix = a * powf(2, -10 * (position -= 1)); // postIncrement is evil
612  return static_cast<T>(postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p) * .5f + end);
613  }
614  } elasticInOut = elasticInOutEasing{};
615 
620  static constexpr struct backInEasing {
621  template<typename T>
622  static T run(float position, T start, T end) {
623  float s = 1.70158f;
624  float postFix = position;
625  return static_cast<T>((end - start) * (postFix) * position * ((s + 1) * position - s) + start);
626  }
627  } backIn = backInEasing{};
628 
633  static constexpr struct backOutEasing {
634  template<typename T>
635  static T run(float position, T start, T end) {
636  float s = 1.70158f;
637  position -= 1;
638  return static_cast<T>((end - start) * ((position) * position * ((s + 1) * position + s) + 1) + start);
639  }
640  } backOut = backOutEasing{};
641 
646  static constexpr struct backInOutEasing {
647  template<typename T>
648  static T run(float position, T start, T end) {
649  float s = 1.70158f;
650  float t = position;
651  auto b = start;
652  auto c = end - start;
653  float d = 1;
654  s *= (1.525f);
655  if ((t /= d / 2) < 1) return static_cast<T>(c / 2 * (t * t * (((s) + 1) * t - s)) + b);
656  float postFix = t -= 2;
657  return static_cast<T>(c / 2 * ((postFix) * t * (((s) + 1) * t + s) + 2) + b);
658  }
659  } backInOut = backInOutEasing{};
660  };
661 }
662 #endif //TWEENY_EASING_H
enumerated
Enumerates all easings to aid in runtime when adding easins to a tween using tween::via.
Definition: easing.h:138
The easing class holds all the bundled easings.
Definition: easing.h:130
The tweeny namespace contains all symbols and names for the Tweeny library.
Definition: MANUAL.dox:1
Acceelerate initial values with a "back" equation.
Definition: easing.h:620
Acceelerate initial and deaccelerate ending values with a "back" equation.
Definition: easing.h:646
Deaccelerate ending values with a "back" equation.
Definition: easing.h:633
Acceelerate initial values with a "bounce" equation.
Definition: easing.h:516
Acceelerate initial and deaccelerate ending values with a "bounce" equation.
Definition: easing.h:550
Deaccelerate ending values with a "bounce" equation.
Definition: easing.h:527
Acceelerate initial values with a circular equation.
Definition: easing.h:476
Acceelerate initial and deaccelerate ending values with a circular equation.
Definition: easing.h:499
Deaccelerate ending values with a circular equation.
Definition: easing.h:487
Aaccelerate initial values with a cubic equation.
Definition: easing.h:281
Acceelerate initial and deaccelerate ending values with a cubic equation.
Definition: easing.h:304
Deaccelerate ending values with a cubic equation.
Definition: easing.h:292
Values change with constant speed for arithmetic type only. The non-arithmetic it will be constant.
Definition: easing.h:189
Acceelerate initial values with an "elastic" equation.
Definition: easing.h:562
Acceelerate initial and deaccelerate ending values with an "elastic" equation.
Definition: easing.h:596
Deaccelerate ending values with an "elastic" equation.
Definition: easing.h:580
Acceelerate initial values with an exponential equation.
Definition: easing.h:438
Acceelerate initial and deaccelerate ending values with an exponential equation.
Definition: easing.h:460
Deaccelerate ending values with an exponential equation.
Definition: easing.h:449
Values change with constant speed.
Definition: easing.h:226
Accelerate initial values with a quadratic equation.
Definition: easing.h:242
Acceelerate initial and deaccelerate ending values with a quadratic equation.
Definition: easing.h:264
Deaccelerate ending values with a quadratic equation.
Definition: easing.h:253
Acceelerate initial values with a quartic equation.
Definition: easing.h:320
Acceelerate initial and deaccelerate ending values with a quartic equation.
Definition: easing.h:343
Deaccelerate ending values with a quartic equation.
Definition: easing.h:331
Acceelerate initial values with a quintic equation.
Definition: easing.h:361
Acceelerate initial and deaccelerate ending values with a quintic equation.
Definition: easing.h:385
Deaccelerate ending values with a quintic equation.
Definition: easing.h:372
Acceelerate initial values with a sinusoidal equation.
Definition: easing.h:405
Acceelerate initial and deaccelerate ending values with a sinusoidal equation.
Definition: easing.h:427
Deaccelerate ending values with a sinusoidal equation.
Definition: easing.h:416
Value is constant.
Definition: easing.h:178