Easing.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. using System;
  2. public class Easing {
  3. /*
  4. Disclaimer for Robert Penner's Easing Equations license:
  5. TERMS OF USE - EASING EQUATIONS
  6. Open source under the BSD License.
  7. Copyright © 2001 Robert Penner
  8. All rights reserved.
  9. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  10. * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  11. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  12. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  13. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. */
  15. // Constants
  16. private const float HALF_PI = (float)(Math.PI / 2.0);
  17. private const float TWO_PI = (float)(Math.PI * 2.0);
  18. /**
  19. * Easing equation function for a simple linear tweening, with no easing.
  20. *
  21. * @param t Current time/phase (0-1).
  22. * @return The new value/phase (0-1).
  23. */
  24. public static float none(float t) {
  25. return t;
  26. }
  27. /**
  28. * Easing equation function for a quadratic (t^2) easing in: accelerating from zero velocity.
  29. *
  30. * @param t Current time/phase (0-1).
  31. * @return The new value/phase (0-1).
  32. */
  33. public static float quadIn(float t) {
  34. return t*t;
  35. }
  36. /**
  37. * Easing equation function for a quadratic (t^2) easing out: decelerating to zero velocity.
  38. *
  39. * @param t Current time/phase (0-1).
  40. * @return The new value/phase (0-1).
  41. */
  42. public static float quadOut(float t) {
  43. return -t * (t-2);
  44. }
  45. /**
  46. * Easing equation function for a quadratic (t^2) easing in and then out: accelerating from zero velocity, then decelerating.
  47. *
  48. * @param t Current time/phase (0-1).
  49. * @return The new value/phase (0-1).
  50. */
  51. public static float quadInOut(float t) {
  52. return ((t *= 2f) < 1f) ? t * t * 0.5f : -0.5f * (--t * (t-2f) - 1f);
  53. }
  54. /**
  55. * Easing equation function for a cubic (t^3) easing in: accelerating from zero velocity.
  56. *
  57. * @param t Current time/phase (0-1).
  58. * @return The new value/phase (0-1).
  59. */
  60. public static float cubicIn(float t) {
  61. return t*t*t;
  62. }
  63. /**
  64. * Easing equation function for a cubic (t^3) easing out: decelerating from zero velocity.
  65. *
  66. * @param t Current time/phase (0-1).
  67. * @return The new value/phase (0-1).
  68. */
  69. public static float cubicOut(float t) {
  70. return (t = t-1.0f) * t * t + 1.0f;
  71. }
  72. public static float cubicInOut(float t) {
  73. return (t *= 2.0f) < 1.0f ? cubicIn(t)/2.0f : cubicOut(t-1.0f)/.0f+0.5f; // TODO: redo with in-line calculation
  74. }
  75. /**
  76. * Easing equation function for a quartic (t^4) easing in: accelerating from zero velocity.
  77. *
  78. * @param t Current time/phase (0-1).
  79. * @return The new value/phase (0-1).
  80. */
  81. public static float quartIn(float t) {
  82. return t*t*t*t;
  83. }
  84. /**
  85. * Easing equation function for a quartic (t^4) easing out: decelerating from zero velocity.
  86. *
  87. * @param t Current time/phase (0-1).
  88. * @return The new value/phase (0-1).
  89. */
  90. public static float quartOut(float t) {
  91. t--;
  92. return -1.0f * (t * t * t * t - 1.0f);
  93. }
  94. public static float quartInOut(float t) {
  95. return (t *= 2.0f) < 1.0f ? quartIn(t)/2.0f : quartOut(t-1.0f)/2.0f+0.5f; // TODO: redo with in-line calculation
  96. }
  97. /**
  98. * Easing equation function for a quintic (t^5) easing in: accelerating from zero velocity.
  99. *
  100. * @param t Current time/phase (0-1).
  101. * @return The new value/phase (0-1).
  102. */
  103. public static float quintIn(float t) {
  104. return t*t*t*t*t;
  105. }
  106. /**
  107. * Easing equation function for a quintic (t^5) easing out: decelerating from zero velocity.
  108. *
  109. * @param t Current time/phase (0-1).
  110. * @return The new value/phase (0-1).
  111. */
  112. public static float quintOut(float t) {
  113. t--;
  114. return t*t*t*t*t + 1.0f;
  115. }
  116. public static float quintInOut(float t) {
  117. return (t *= 2.0f) < 1.0f ? quintIn(t)/2.0f : quintOut(t-1.0f)/2.0f+0.5f; // TODO: redo with in-line calculation
  118. }
  119. /**
  120. * Easing equation function for a sinusoidal (sin(t)) easing in: accelerating from zero velocity.
  121. *
  122. * @param t Current time/phase (0-1).
  123. * @return The new value/phase (0-1).
  124. */
  125. public static float sineIn(float t) {
  126. return -1.0f * (float)Math.Cos(t * HALF_PI) + 1.0f;
  127. }
  128. /**
  129. * Easing equation function for a sinusoidal (sin(t)) easing out: decelerating from zero velocity.
  130. *
  131. * @param t Current time/phase (0-1).
  132. * @return The new value/phase (0-1).
  133. */
  134. public static float sineOut(float t) {
  135. return (float)Math.Sin(t * HALF_PI);
  136. }
  137. public static float sineInOut(float t) {
  138. return (t *= 2.0f) < 1.0f ? sineIn(t)/2.0f : sineOut(t-1.0f)/2.0f+0.5f; // TODO: redo with in-line calculation
  139. }
  140. /**
  141. * Easing equation function for an exponential (2^t) easing in: accelerating from zero velocity.
  142. *
  143. * @param t Current time/phase (0-1).
  144. * @return The new value/phase (0-1).
  145. */
  146. public static float expoIn(float t) {
  147. // return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; // original
  148. // return (t==0) ? 0 : Math.pow(2, 10 * (t - 1)); // ztween
  149. // return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b - c * 0.001; // tweener fixed
  150. return (t==0) ? 0 : (float)Math.Pow(2, 10.0f * (t - 1.0f)) - 0.001f; // ztween fixed
  151. }
  152. /**
  153. * Easing equation function for an exponential (2^t) easing out: decelerating from zero velocity.
  154. *
  155. * @param t Current time/phase (0-1).
  156. * @return The new value/phase (0-1).
  157. */
  158. public static float expoOut(float t) {
  159. // return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; // original
  160. // return (t==1) ? 1 : (-Math.pow(2, -10 * t) + 1); // ztween
  161. // return (t == d) ? b + c : c * 1.001 * (-Math.pow(2, -10 * t / d) + 1) + b; // tweener fixed
  162. //log(">", t, (t==1) ? 1 : 1.001 * (-Math.pow(2, -10 * t) + 1))
  163. //return (t==1) ? 1 : 1.001 * (-Math.pow(2, -10 * t) + 1); // ztween fixed
  164. return (t>=0.999f) ? 1.0f : 1.001f * (-(float)Math.Pow(2, -10.0f * t) + 1.0f); // ztween fixed 2
  165. }
  166. public static float expoInOut(float t) {
  167. return (t *= 2.0f) < 1.0f ? expoIn(t)/2.0f : expoOut(t-1.0f)/2.0f+0.5f; // TODO: redo with in-line calculation
  168. }
  169. /**
  170. * Easing equation function for a circular (sqrt(1-t^2)) easing in: accelerating from zero velocity.
  171. *
  172. * @param t Current time/phase (0-1).
  173. * @return The new value/phase (0-1).
  174. */
  175. public static float circIn(float t) {
  176. return -1.0f * ((float)Math.Sqrt(1.0f - t*t) - 1.0f);
  177. }
  178. /**
  179. * Easing equation function for a circular (sqrt(1-t^2)) easing out: decelerating from zero velocity.
  180. *
  181. * @param t Current time/phase (0-1).
  182. * @return The new value/phase (0-1).
  183. */
  184. public static float circOut(float t) {
  185. t--;
  186. return (float)Math.Sqrt(1.0f - t*t);
  187. }
  188. public static float circInOut(float t) {
  189. return (t *= 2.0f) < 1.0f ? circIn(t)/2.0f : circOut(t-1.0f)/2.0f+0.5f; // TODO: redo with in-line calculation
  190. }
  191. /**
  192. * Easing equation function for an elastic (exponentially decaying sine wave) easing in: accelerating from zero velocity.
  193. *
  194. * @param t Current time/phase (0-1).
  195. * @param a Amplitude.
  196. * @param p Period.
  197. * @return The new value/phase (0-1).
  198. */
  199. public static float elasticIn(float t, float a, float p) {
  200. if (t==0) return 0;
  201. if (t==1) return 1;
  202. float s;
  203. if (a < 1.0f) {
  204. a = 1.0f;
  205. s = p/4.0f;
  206. } else {
  207. s = p/TWO_PI * (float)Math.Asin(1.0f/a);
  208. }
  209. return -(a*(float)Math.Pow(2,10.0f*(t-=1)) * (float)Math.Sin((t-s)*TWO_PI/p));
  210. }
  211. /**
  212. * Overloads are used instead of optional arguments just so the function call works as a valid Func<float> type
  213. */
  214. public static float elasticIn(float t) {
  215. return elasticIn(t, 0, 0.3f);
  216. }
  217. /**
  218. * Easing equation function for an elastic (exponentially decaying sine wave) easing out: decelerating from zero velocity.
  219. *
  220. * @param t Current time/phase (0-1).
  221. * @param a Amplitude.
  222. * @param p Period.
  223. */
  224. public static float elasticOut(float t, float a, float p) {
  225. if (t==0) return 0;
  226. if (t==1) return 1;
  227. float s;
  228. if (a < 1.0f) {
  229. a = 1.0f;
  230. s = p/4.0f;
  231. } else {
  232. s = p/TWO_PI * (float)Math.Asin(1.0f/a);
  233. }
  234. return (a*(float)Math.Pow(2,-10.0f*t) * (float)Math.Sin((t-s)*TWO_PI/p) + 1.0f);
  235. }
  236. /**
  237. * Overloads are used instead of optional arguments just so the function call works as a valid Func<float> type
  238. */
  239. public static float elasticOut(float t) {
  240. return elasticOut(t, 0, 0.3f);
  241. }
  242. /**
  243. * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity.
  244. *
  245. * @param t Current time/phase (0-1).
  246. * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent).
  247. * @param p Period.
  248. */
  249. public static float backIn(float t, float s) {
  250. return t*t*((s+1.0f)*t - s);
  251. }
  252. /**
  253. * Overloads are used instead of optional arguments just so the function call works as a valid Func<float> type
  254. */
  255. public static float backIn(float t) {
  256. return backIn(t, 1.70158f);
  257. }
  258. /**
  259. * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out: decelerating from zero velocity.
  260. *
  261. * @param t Current time/phase (0-1).
  262. * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent).
  263. * @param p Period.
  264. */
  265. public static float backOut(float t, float s) {
  266. t--;
  267. return t*t*((s+1.0f)*t + s) + 1.0f;
  268. }
  269. /**
  270. * Overloads are used instead of optional arguments just so the function call works as a valid Func<float> type
  271. */
  272. public static float backOut(float t) {
  273. return backOut(t, 1.70158f);
  274. }
  275. public static float backInOut(float t) {
  276. return (t *= 2.0f) < 1.0f ? backIn(t)/2.0f : backOut(t-1.0f)/2.0f+0.5f;
  277. }
  278. /**
  279. * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in: accelerating from zero velocity.
  280. *
  281. * @param t Current time/phase (0-1).
  282. * @param p Period.
  283. */
  284. public static float bounceIn(float t) {
  285. return 1.0f - bounceOut(1.0f-t);
  286. }
  287. /**
  288. * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating from zero velocity.
  289. *
  290. * @param t Current time/phase (0-1).
  291. * @param p Period.
  292. */
  293. public static float bounceOut(float t) {
  294. if (t < (1.0f/2.75f)) {
  295. return 7.5625f*t*t;
  296. } else if (t < (2.0f/2.75f)) {
  297. return 7.5625f*(t-=(1.5f/2.75f))*t + 0.75f;
  298. } else if (t < (2.5f/2.75f)) {
  299. return 7.5625f*(t-=(2.25f/2.75f))*t + 0.9375f;
  300. } else {
  301. return 7.5625f*(t-=(2.625f/2.75f))*t + 0.984375f;
  302. }
  303. }
  304. }