Tween.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * This source file is part of libRocket, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://www.librocket.com
  5. *
  6. * Copyright (c) 2018 Michael Ragazzon
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. *
  26. */
  27. #ifndef ROCKETCORETWEEN_H
  28. #define ROCKETCORETWEEN_H
  29. #include <array>
  30. namespace Rocket {
  31. namespace Core {
  32. class Tween {
  33. public:
  34. enum Type { None, Back, Bounce, Circular, Cubic, Elastic, Exponential, Linear, Quadratic, Quartic, Quintic, Sine, Callback, Count };
  35. enum Direction { In = 1, Out = 2, InOut = 3 };
  36. typedef float(*CallbackFnc)(float);
  37. Tween(Type type = Linear, Direction direction = Out) {
  38. if (direction & In) type_in = type;
  39. if (direction & Out) type_out = type;
  40. }
  41. Tween(Type type_in, Type type_out) : type_in(type_in), type_out(type_out) {}
  42. Tween(CallbackFnc callback, Direction direction = In) : callback(callback) {
  43. if (direction & In) type_in = Callback;
  44. if (direction & Out) type_out = Callback;
  45. }
  46. float operator()(float t) const
  47. {
  48. if (type_in != None && type_out == None)
  49. {
  50. return in(t);
  51. }
  52. if (type_in == None && type_out != None)
  53. {
  54. return out(t);
  55. }
  56. if (type_in != None && type_out != None)
  57. {
  58. return in_out(t);
  59. }
  60. return t;
  61. }
  62. void reverse()
  63. {
  64. std::swap(type_in, type_out);
  65. }
  66. // Tweening functions below.
  67. // Partly based on http://libclaw.sourceforge.net/tweeners.html
  68. static float back(float t)
  69. {
  70. return t * t*(2.70158f*t - 1.70158f);
  71. }
  72. static float bounce(float t)
  73. {
  74. if (t > 1.f - 1.f / 2.75f)
  75. return 1.f - 7.5625f*square(1.f - t);
  76. else if (t > 1.f - 2.f / 2.75f)
  77. return 1.0f - (7.5625f*square(1.f - t - 1.5f / 2.75f) + 0.75f);
  78. else if (t > 1.f - 2.5f / 2.75f)
  79. return 1.0f - (7.5625f*square(1.f - t - 2.25f / 2.75f) + 0.9375f);
  80. return 1.0f - (7.5625f*square(1.f - t - 2.625f / 2.75f) + 0.984375f);
  81. }
  82. static float circular(float t)
  83. {
  84. return 1.f - sqrt(1.f - t * t);
  85. }
  86. static float cubic(float t)
  87. {
  88. return t * t*t;
  89. }
  90. static float elastic(float t)
  91. {
  92. if (t == 0) return t;
  93. if (t == 1) return t;
  94. return -exp(7.24f*(t-1.f))*sin((t - 1.1f)*2.f*Math::ROCKET_PI / 0.4f);
  95. }
  96. static float exponential(float t)
  97. {
  98. if (t == 0) return t;
  99. if (t == 1) return t;
  100. return exp(7.24f*(t - 1.f));
  101. }
  102. static float linear(float t)
  103. {
  104. return t;
  105. }
  106. static float quadratic(float t)
  107. {
  108. return t * t;
  109. }
  110. static float quartic(float t)
  111. {
  112. return t*t*t*t;
  113. }
  114. static float quintic(float t)
  115. {
  116. return t*t*t*t*t;
  117. }
  118. static float sine(float t)
  119. {
  120. return 1.f - cos(t*Math::ROCKET_PI*0.5f);
  121. }
  122. bool operator==(const Tween& other) const { return type_in == other.type_in && type_out == other.type_out && callback == other.callback; }
  123. bool operator!=(const Tween& other) const { return !(*this == other); }
  124. String to_string() const
  125. {
  126. const std::array<String, size_t(Count)> type_str = { { "none", "back", "bounce", "circular", "cubic", "elastic", "exponential", "linear", "quadratic", "quartic", "quintic", "sine", "callback" } };
  127. if (size_t(type_in) < type_str.size() && size_t(type_out) < type_str.size())
  128. {
  129. if (type_in == None && type_out == None)
  130. {
  131. return "none";
  132. }
  133. else if (type_in == type_out)
  134. {
  135. return type_str[size_t(type_in)] + String("-in-out");
  136. }
  137. else if (type_in == None)
  138. {
  139. return type_str[size_t(type_out)] + String("-out");
  140. }
  141. else if (type_out == None)
  142. {
  143. return type_str[size_t(type_in)] + String("-in");
  144. }
  145. else if (type_in != type_out)
  146. {
  147. return type_str[size_t(type_in)] + String("-in-") + type_str[size_t(type_out)] + String("-out");
  148. }
  149. }
  150. return "unknown";
  151. }
  152. private:
  153. float tween(Type type, float t) const
  154. {
  155. switch (type)
  156. {
  157. case Back:
  158. return back(t);
  159. case Bounce:
  160. return bounce(t);
  161. case Circular:
  162. return circular(t);
  163. case Cubic:
  164. return cubic(t);
  165. case Elastic:
  166. return elastic(t);
  167. case Exponential:
  168. return exponential(t);
  169. case Linear:
  170. return linear(t);
  171. case Quadratic:
  172. return quadratic(t);
  173. case Quartic:
  174. return quartic(t);
  175. case Quintic:
  176. return quintic(t);
  177. case Sine:
  178. return sine(t);
  179. case Callback:
  180. if (callback)
  181. return (*callback)(t);
  182. break;
  183. default:
  184. break;
  185. }
  186. return t;
  187. }
  188. float in(float t) const
  189. {
  190. return tween(type_in, t);
  191. }
  192. float out(float t) const
  193. {
  194. return 1.0f - tween(type_out, 1.0f - t);
  195. }
  196. float in_out(float t) const
  197. {
  198. if (t < 0.5f)
  199. return tween(type_in, 2.0f*t)*0.5f;
  200. else
  201. return 0.5f + out(2.0f*t - 1.0f)*0.5f;
  202. }
  203. inline static float square(float t) { return t * t; }
  204. Type type_in = None;
  205. Type type_out = None;
  206. CallbackFnc callback = nullptr;
  207. };
  208. }
  209. }
  210. #endif