Tweeny  3
A Tweening library for modern C++
easing.h
1 /*
2  This file is part of the Tweeny library.
3 
4  Copyright (c) 2016-2018 Leonardo G. 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 
107 namespace tweeny {
120  class easing {
121  public:
126  static constexpr struct linearEasing {
127  template<typename T>
128  static typename std::enable_if<std::is_integral<T>::value, T>::type run(float position, T start, T end) {
129  return static_cast<T>(roundf((end - start) * position + start));
130  }
131 
132  template<typename T>
133  static typename std::enable_if<!std::is_integral<T>::value, T>::type run(float position, T start, T end) {
134  return static_cast<T>((end - start) * position + start);
135  }
136  } linear = linearEasing{};
137 
142  static constexpr struct quadraticInEasing {
143  template<typename T>
144  static T run(float position, T start, T end) {
145  return static_cast<T>((end - start) * position * position + start);
146  }
147  } quadraticIn = quadraticInEasing{};
148 
153  static constexpr struct quadraticOutEasing {
154  template<typename T>
155  static T run(float position, T start, T end) {
156  return static_cast<T>((-(end - start)) * position * (position - 2) + start);
157  }
158  } quadraticOut = quadraticOutEasing{};
159 
164  static constexpr struct quadraticInOutEasing {
165  template<typename T>
166  static T run(float position, T start, T end) {
167  position *= 2;
168  if (position < 1) {
169  return static_cast<T>(((end - start) / 2) * position * position + start);
170  }
171 
172  --position;
173  return static_cast<T>((-(end - start) / 2) * (position * (position - 2) - 1) + start);
174  }
175  } quadraticInOut = quadraticInOutEasing{};
176 
181  static constexpr struct cubicInEasing {
182  template<typename T>
183  static T run(float position, T start, T end) {
184  return static_cast<T>((end - start) * position * position * position + start);
185  }
186  } cubicIn = cubicInEasing{};
187 
192  static constexpr struct cubicOutEasing {
193  template<typename T>
194  static T run(float position, T start, T end) {
195  --position;
196  return static_cast<T>((end - start) * (position * position * position + 1) + start);
197  }
198  } cubicOut = cubicOutEasing{};
199 
204  static constexpr struct cubicInOutEasing {
205  template<typename T>
206  static T run(float position, T start, T end) {
207  position *= 2;
208  if (position < 1) {
209  return static_cast<T>(((end - start) / 2) * position * position * position + start);
210  }
211  position -= 2;
212  return static_cast<T>(((end - start) / 2) * (position * position * position + 2) + start);
213  }
214  } cubicInOut = cubicInOutEasing{};
215 
220  static constexpr struct quarticInEasing {
221  template<typename T>
222  static T run(float position, T start, T end) {
223  return static_cast<T>((end - start) * position * position * position * position + start);
224  }
225  } quarticIn = quarticInEasing{};
226 
231  static constexpr struct quarticOutEasing {
232  template<typename T>
233  static T run(float position, T start, T end) {
234  --position;
235  return static_cast<T>( -(end - start) * (position * position * position * position - 1) + start);
236  }
237  } quarticOut = quarticOutEasing{};
238 
243  static constexpr struct quarticInOutEasing {
244  template<typename T>
245  static T run(float position, T start, T end) {
246  position *= 2;
247  if (position < 1) {
248  return static_cast<T>(((end - start) / 2) * (position * position * position * position) +
249  start);
250  }
251  position -= 2;
252  return static_cast<T>((-(end - start) / 2) * (position * position * position * position - 2) +
253  start);
254  }
255  } quarticInOut = quarticInOutEasing{};
256 
261  static constexpr struct quinticInEasing {
262  template<typename T>
263  static T run(float position, T start, T end) {
264  return static_cast<T>((end - start) * position * position * position * position * position + start);
265  }
266  } quinticIn = quinticInEasing{};
267 
272  static constexpr struct quinticOutEasing {
273  template<typename T>
274  static T run(float position, T start, T end) {
275  position--;
276  return static_cast<T>((end - start) * (position * position * position * position * position + 1) +
277  start);
278  }
279  } quinticOut = quinticOutEasing{};
280 
285  static constexpr struct quinticInOutEasing {
286  template<typename T>
287  static T run(float position, T start, T end) {
288  position *= 2;
289  if (position < 1) {
290  return static_cast<T>(
291  ((end - start) / 2) * (position * position * position * position * position) +
292  start);
293  }
294  position -= 2;
295  return static_cast<T>(
296  ((end - start) / 2) * (position * position * position * position * position + 2) +
297  start);
298  }
299  } quinticInOut = quinticInOutEasing{};
300 
305  static constexpr struct sinusoidalInEasing {
306  template<typename T>
307  static T run(float position, T start, T end) {
308  return static_cast<T>(-(end - start) * cosf(position * static_cast<float>(M_PI) / 2) + (end - start) + start);
309  }
310  } sinusoidalIn = sinusoidalInEasing{};
311 
316  static constexpr struct sinusoidalOutEasing {
317  template<typename T>
318  static T run(float position, T start, T end) {
319  return static_cast<T>((end - start) * sinf(position * static_cast<float>(M_PI) / 2) + start);
320  }
321  } sinusoidalOut = sinusoidalOutEasing{};
322 
327  static constexpr struct sinusoidalInOutEasing {
328  template<typename T>
329  static T run(float position, T start, T end) {
330  return static_cast<T>((-(end - start) / 2) * (cosf(position * static_cast<float>(M_PI)) - 1) + start);
331  }
332  } sinusoidalInOut = sinusoidalInOutEasing{};
333 
338  static constexpr struct exponentialInEasing {
339  template<typename T>
340  static T run(float position, T start, T end) {
341  return static_cast<T>((end - start) * powf(2, 10 * (position - 1)) + start);
342  }
343  } exponentialIn = exponentialInEasing{};
344 
349  static constexpr struct exponentialOutEasing {
350  template<typename T>
351  static T run(float position, T start, T end) {
352  return static_cast<T>((end - start) * (-powf(2, -10 * position) + 1) + start);
353  }
354  } exponentialOut = exponentialOutEasing{};
355 
360  static constexpr struct exponentialInOutEasing {
361  template<typename T>
362  static T run(float position, T start, T end) {
363  position *= 2;
364  if (position < 1) {
365  return static_cast<T>(((end - start) / 2) * powf(2, 10 * (position - 1)) + start);
366  }
367  --position;
368  return static_cast<T>(((end - start) / 2) * (-powf(2, -10 * position) + 2) + start);
369  }
370  } exponentialInOut = exponentialInOutEasing{};
371 
376  static constexpr struct circularInEasing {
377  template<typename T>
378  static T run(float position, T start, T end) {
379  return static_cast<T>( -(end - start) * (sqrtf(1 - position * position) - 1) + start );
380  }
381  } circularIn = circularInEasing{};
382 
387  static constexpr struct circularOutEasing {
388  template<typename T>
389  static T run(float position, T start, T end) {
390  --position;
391  return static_cast<T>((end - start) * (sqrtf(1 - position * position)) + start);
392  }
393  } circularOut = circularOutEasing{};
394 
399  static constexpr struct circularInOutEasing {
400  template<typename T>
401  static T run(float position, T start, T end) {
402  position *= 2;
403  if (position < 1) {
404  return static_cast<T>((-(end - start) / 2) * (sqrtf(1 - position * position) - 1) + start);
405  }
406 
407  position -= 2;
408  return static_cast<T>(((end - start) / 2) * (sqrtf(1 - position * position) + 1) + start);
409  }
410  } circularInOut = circularInOutEasing{};
411 
416  static constexpr struct bounceInEasing {
417  template<typename T>
418  static T run(float position, T start, T end) {
419  return (end - start) - bounceOut.run((1 - position), T(), end) + start;
420  }
421  } bounceIn = bounceInEasing{};
422 
427  static constexpr struct bounceOutEasing {
428  template<typename T>
429  static T run(float position, T start, T end) {
430  T c = end - start;
431  if (position < (1 / 2.75f)) {
432  return static_cast<T>(c * (7.5625f * position * position) + start);
433  } else if (position < (2.0f / 2.75f)) {
434  float postFix = position -= (1.5f / 2.75f);
435  return static_cast<T>(c * (7.5625f * (postFix) * position + .75f) + start);
436  } else if (position < (2.5f / 2.75f)) {
437  float postFix = position -= (2.25f / 2.75f);
438  return static_cast<T>(c * (7.5625f * (postFix) * position + .9375f) + start);
439  } else {
440  float postFix = position -= (2.625f / 2.75f);
441  return static_cast<T>(c * (7.5625f * (postFix) * position + .984375f) + start);
442  }
443  }
444  } bounceOut = bounceOutEasing{};
445 
450  static constexpr struct bounceInOutEasing {
451  template<typename T>
452  static T run(float position, T start, T end) {
453  if (position < 0.5f) return static_cast<T>(bounceIn.run(position * 2, T(), end) * .5f + start);
454  else return static_cast<T>(bounceOut.run((position * 2 - 1), T(), end) * .5f + (end - start) * .5f + start);
455  }
456  } bounceInOut = bounceInOutEasing{};
457 
462  static constexpr struct elasticInEasing {
463  template<typename T>
464  static T run(float position, T start, T end) {
465  if (position <= 0.00001f) return start;
466  if (position >= 0.999f) return end;
467  float p = .3f;
468  float a = end - start;
469  float s = p / 4;
470  float postFix =
471  a * powf(2, 10 * (position -= 1)); // this is a fix, again, with post-increment operators
472  return static_cast<T>(-(postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p)) + start);
473  }
474  } elasticIn = elasticInEasing{};
475 
480  static constexpr struct elasticOutEasing {
481  template<typename T>
482  static T run(float position, T start, T end) {
483  if (position <= 0.00001f) return start;
484  if (position >= 0.999f) return end;
485  float p = .3f;
486  float a = end - start;
487  float s = p / 4;
488  return static_cast<T>(a * powf(2, -10 * position) * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p) + end);
489  }
490  } elasticOut = elasticOutEasing{};
491 
496  static constexpr struct elasticInOutEasing {
497  template<typename T>
498  static T run(float position, T start, T end) {
499  if (position <= 0.00001f) return start;
500  if (position >= 0.999f) return end;
501  position *= 2;
502  float p = (.3f * 1.5f);
503  float a = end - start;
504  float s = p / 4;
505  float postFix;
506 
507  if (position < 1) {
508  postFix = a * powf(2, 10 * (position -= 1)); // postIncrement is evil
509  return static_cast<T>(-0.5f * (postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p)) + start);
510  }
511  postFix = a * powf(2, -10 * (position -= 1)); // postIncrement is evil
512  return static_cast<T>(postFix * sinf((position - s) * (2 * static_cast<float>(M_PI)) / p) * .5f + end);
513  }
514  } elasticInOut = elasticInOutEasing{};
515 
520  static constexpr struct backInEasing {
521  template<typename T>
522  static T run(float position, T start, T end) {
523  float s = 1.70158f;
524  float postFix = position;
525  return static_cast<T>((end - start) * (postFix) * position * ((s + 1) * position - s) + start);
526  }
527  } backIn = backInEasing{};
528 
533  static constexpr struct backOutEasing {
534  template<typename T>
535  static T run(float position, T start, T end) {
536  float s = 1.70158f;
537  position -= 1;
538  return static_cast<T>((end - start) * ((position) * position * ((s + 1) * position + s) + 1) + start);
539  }
540  } backOut = backOutEasing{};
541 
546  static constexpr struct backInOutEasing {
547  template<typename T>
548  static T run(float position, T start, T end) {
549  float s = 1.70158f;
550  float t = position;
551  T b = start;
552  T c = end - start;
553  float d = 1;
554  s *= (1.525f);
555  if ((t /= d / 2) < 1) return static_cast<T>(c / 2 * (t * t * (((s) + 1) * t - s)) + b);
556  float postFix = t -= 2;
557  return static_cast<T>(c / 2 * ((postFix) * t * (((s) + 1) * t + s) + 2) + b);
558  }
559  } backInOut = backInOutEasing{};
560  };
561 }
562 #endif //TWEENY_EASING_H
Acceelerate initial values with a "back" equation.
Definition: easing.h:520
Acceelerate initial and deaccelerate ending values with a quartic equation.
Definition: easing.h:243
Deaccelerate ending values with a "bounce" equation.
Definition: easing.h:427
Acceelerate initial and deaccelerate ending values with a cubic equation.
Definition: easing.h:204
Acceelerate initial values with an "elastic" equation.
Definition: easing.h:462
The tweeny namespace contains all symbols and names for the Tweeny library.
Definition: MANUAL.dox:1
Acceelerate initial and deaccelerate ending values with an "elastic" equation.
Definition: easing.h:496
Acceelerate initial and deaccelerate ending values with a "back" equation.
Definition: easing.h:546
Acceelerate initial values with a quintic equation.
Definition: easing.h:261
Deaccelerate ending values with an exponential equation.
Definition: easing.h:349
Acceelerate initial values with a quartic equation.
Definition: easing.h:220
Accelerate initial values with a quadratic equation.
Definition: easing.h:142
Acceelerate initial and deaccelerate ending values with a circular equation.
Definition: easing.h:399
Deaccelerate ending values with a circular equation.
Definition: easing.h:387
Deaccelerate ending values with a cubic equation.
Definition: easing.h:192
Deaccelerate ending values with an "elastic" equation.
Definition: easing.h:480
Acceelerate initial and deaccelerate ending values with a "bounce" equation.
Definition: easing.h:450
Deaccelerate ending values with a sinusoidal equation.
Definition: easing.h:316
Acceelerate initial values with a "bounce" equation.
Definition: easing.h:416
Acceelerate initial and deaccelerate ending values with a quadratic equation.
Definition: easing.h:164
Deaccelerate ending values with a "back" equation.
Definition: easing.h:533
Deaccelerate ending values with a quartic equation.
Definition: easing.h:231
Values change with constant speed.
Definition: easing.h:126
Deaccelerate ending values with a quadratic equation.
Definition: easing.h:153
Acceelerate initial values with an exponential equation.
Definition: easing.h:338
Acceelerate initial and deaccelerate ending values with an exponential equation.
Definition: easing.h:360
The easing class holds all the bundled easings.
Definition: easing.h:120
Acceelerate initial values with a sinusoidal equation.
Definition: easing.h:305
Acceelerate initial and deaccelerate ending values with a sinusoidal equation.
Definition: easing.h:327
Deaccelerate ending values with a quintic equation.
Definition: easing.h:272
Aaccelerate initial values with a cubic equation.
Definition: easing.h:181
Acceelerate initial values with a circular equation.
Definition: easing.h:376
Acceelerate initial and deaccelerate ending values with a quintic equation.
Definition: easing.h:285