Easings.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. // https://github.com/acron0/Easings/blob/master/Easings.cs
  2. using UnityEngine;
  3. namespace UnityUIPlayables
  4. {
  5. /// <summary>
  6. /// Easing Functions enumeration
  7. /// </summary>
  8. internal enum EaseType
  9. {
  10. Linear,
  11. QuadraticEaseIn,
  12. QuadraticEaseOut,
  13. QuadraticEaseInOut,
  14. CubicEaseIn,
  15. CubicEaseOut,
  16. CubicEaseInOut,
  17. QuarticEaseIn,
  18. QuarticEaseOut,
  19. QuarticEaseInOut,
  20. QuinticEaseIn,
  21. QuinticEaseOut,
  22. QuinticEaseInOut,
  23. SineEaseIn,
  24. SineEaseOut,
  25. SineEaseInOut,
  26. CircularEaseIn,
  27. CircularEaseOut,
  28. CircularEaseInOut,
  29. ExponentialEaseIn,
  30. ExponentialEaseOut,
  31. ExponentialEaseInOut,
  32. ElasticEaseIn,
  33. ElasticEaseOut,
  34. ElasticEaseInOut,
  35. BackEaseIn,
  36. BackEaseOut,
  37. BackEaseInOut,
  38. BounceEaseIn,
  39. BounceEaseOut,
  40. BounceEaseInOut
  41. }
  42. internal static class Easings
  43. {
  44. /// <summary>
  45. /// Constant Pi.
  46. /// </summary>
  47. private const float PI = Mathf.PI;
  48. /// <summary>
  49. /// Constant Pi / 2.
  50. /// </summary>
  51. private const float HALFPI = Mathf.PI / 2.0f;
  52. /// <summary>
  53. /// Interpolate using the specified function.
  54. /// </summary>
  55. public static float Interpolate(float p, EaseType function)
  56. {
  57. switch (function)
  58. {
  59. default:
  60. case EaseType.Linear: return Linear(p);
  61. case EaseType.QuadraticEaseOut: return QuadraticEaseOut(p);
  62. case EaseType.QuadraticEaseIn: return QuadraticEaseIn(p);
  63. case EaseType.QuadraticEaseInOut: return QuadraticEaseInOut(p);
  64. case EaseType.CubicEaseIn: return CubicEaseIn(p);
  65. case EaseType.CubicEaseOut: return CubicEaseOut(p);
  66. case EaseType.CubicEaseInOut: return CubicEaseInOut(p);
  67. case EaseType.QuarticEaseIn: return QuarticEaseIn(p);
  68. case EaseType.QuarticEaseOut: return QuarticEaseOut(p);
  69. case EaseType.QuarticEaseInOut: return QuarticEaseInOut(p);
  70. case EaseType.QuinticEaseIn: return QuinticEaseIn(p);
  71. case EaseType.QuinticEaseOut: return QuinticEaseOut(p);
  72. case EaseType.QuinticEaseInOut: return QuinticEaseInOut(p);
  73. case EaseType.SineEaseIn: return SineEaseIn(p);
  74. case EaseType.SineEaseOut: return SineEaseOut(p);
  75. case EaseType.SineEaseInOut: return SineEaseInOut(p);
  76. case EaseType.CircularEaseIn: return CircularEaseIn(p);
  77. case EaseType.CircularEaseOut: return CircularEaseOut(p);
  78. case EaseType.CircularEaseInOut: return CircularEaseInOut(p);
  79. case EaseType.ExponentialEaseIn: return ExponentialEaseIn(p);
  80. case EaseType.ExponentialEaseOut: return ExponentialEaseOut(p);
  81. case EaseType.ExponentialEaseInOut: return ExponentialEaseInOut(p);
  82. case EaseType.ElasticEaseIn: return ElasticEaseIn(p);
  83. case EaseType.ElasticEaseOut: return ElasticEaseOut(p);
  84. case EaseType.ElasticEaseInOut: return ElasticEaseInOut(p);
  85. case EaseType.BackEaseIn: return BackEaseIn(p);
  86. case EaseType.BackEaseOut: return BackEaseOut(p);
  87. case EaseType.BackEaseInOut: return BackEaseInOut(p);
  88. case EaseType.BounceEaseIn: return BounceEaseIn(p);
  89. case EaseType.BounceEaseOut: return BounceEaseOut(p);
  90. case EaseType.BounceEaseInOut: return BounceEaseInOut(p);
  91. }
  92. }
  93. /// <summary>
  94. /// Modeled after the line y = x
  95. /// </summary>
  96. public static float Linear(float p)
  97. {
  98. return p;
  99. }
  100. /// <summary>
  101. /// Modeled after the parabola y = x^2
  102. /// </summary>
  103. public static float QuadraticEaseIn(float p)
  104. {
  105. return p * p;
  106. }
  107. /// <summary>
  108. /// Modeled after the parabola y = -x^2 + 2x
  109. /// </summary>
  110. public static float QuadraticEaseOut(float p)
  111. {
  112. return -(p * (p - 2));
  113. }
  114. /// <summary>
  115. /// Modeled after the piecewise quadratic
  116. /// y = (1/2)((2x)^2) ; [0, 0.5)
  117. /// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1]
  118. /// </summary>
  119. public static float QuadraticEaseInOut(float p)
  120. {
  121. if (p < 0.5f)
  122. {
  123. return 2 * p * p;
  124. }
  125. return -2 * p * p + 4 * p - 1;
  126. }
  127. /// <summary>
  128. /// Modeled after the cubic y = x^3
  129. /// </summary>
  130. public static float CubicEaseIn(float p)
  131. {
  132. return p * p * p;
  133. }
  134. /// <summary>
  135. /// Modeled after the cubic y = (x - 1)^3 + 1
  136. /// </summary>
  137. public static float CubicEaseOut(float p)
  138. {
  139. var f = p - 1;
  140. return f * f * f + 1;
  141. }
  142. /// <summary>
  143. /// Modeled after the piecewise cubic
  144. /// y = (1/2)((2x)^3) ; [0, 0.5)
  145. /// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1]
  146. /// </summary>
  147. public static float CubicEaseInOut(float p)
  148. {
  149. if (p < 0.5f)
  150. {
  151. return 4 * p * p * p;
  152. }
  153. var f = 2 * p - 2;
  154. return 0.5f * f * f * f + 1;
  155. }
  156. /// <summary>
  157. /// Modeled after the quartic x^4
  158. /// </summary>
  159. public static float QuarticEaseIn(float p)
  160. {
  161. return p * p * p * p;
  162. }
  163. /// <summary>
  164. /// Modeled after the quartic y = 1 - (x - 1)^4
  165. /// </summary>
  166. public static float QuarticEaseOut(float p)
  167. {
  168. var f = p - 1;
  169. return f * f * f * (1 - p) + 1;
  170. }
  171. /// <summary>
  172. // Modeled after the piecewise quartic
  173. // y = (1/2)((2x)^4) ; [0, 0.5)
  174. // y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1]
  175. /// </summary>
  176. public static float QuarticEaseInOut(float p)
  177. {
  178. if (p < 0.5f)
  179. {
  180. return 8 * p * p * p * p;
  181. }
  182. var f = p - 1;
  183. return -8 * f * f * f * f + 1;
  184. }
  185. /// <summary>
  186. /// Modeled after the quintic y = x^5
  187. /// </summary>
  188. public static float QuinticEaseIn(float p)
  189. {
  190. return p * p * p * p * p;
  191. }
  192. /// <summary>
  193. /// Modeled after the quintic y = (x - 1)^5 + 1
  194. /// </summary>
  195. public static float QuinticEaseOut(float p)
  196. {
  197. var f = p - 1;
  198. return f * f * f * f * f + 1;
  199. }
  200. /// <summary>
  201. /// Modeled after the piecewise quintic
  202. /// y = (1/2)((2x)^5) ; [0, 0.5)
  203. /// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1]
  204. /// </summary>
  205. public static float QuinticEaseInOut(float p)
  206. {
  207. if (p < 0.5f)
  208. {
  209. return 16 * p * p * p * p * p;
  210. }
  211. var f = 2 * p - 2;
  212. return 0.5f * f * f * f * f * f + 1;
  213. }
  214. /// <summary>
  215. /// Modeled after quarter-cycle of sine wave
  216. /// </summary>
  217. public static float SineEaseIn(float p)
  218. {
  219. return Mathf.Sin((p - 1) * HALFPI) + 1;
  220. }
  221. /// <summary>
  222. /// Modeled after quarter-cycle of sine wave (different phase)
  223. /// </summary>
  224. public static float SineEaseOut(float p)
  225. {
  226. return Mathf.Sin(p * HALFPI);
  227. }
  228. /// <summary>
  229. /// Modeled after half sine wave
  230. /// </summary>
  231. public static float SineEaseInOut(float p)
  232. {
  233. return 0.5f * (1 - Mathf.Cos(p * PI));
  234. }
  235. /// <summary>
  236. /// Modeled after shifted quadrant IV of unit circle
  237. /// </summary>
  238. public static float CircularEaseIn(float p)
  239. {
  240. return 1 - Mathf.Sqrt(1 - p * p);
  241. }
  242. /// <summary>
  243. /// Modeled after shifted quadrant II of unit circle
  244. /// </summary>
  245. public static float CircularEaseOut(float p)
  246. {
  247. return Mathf.Sqrt((2 - p) * p);
  248. }
  249. /// <summary>
  250. /// Modeled after the piecewise circular function
  251. /// y = (1/2)(1 - Mathf.Sqrt(1 - 4x^2)) ; [0, 0.5)
  252. /// y = (1/2)(Mathf.Sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
  253. /// </summary>
  254. public static float CircularEaseInOut(float p)
  255. {
  256. if (p < 0.5f)
  257. {
  258. return 0.5f * (1 - Mathf.Sqrt(1 - 4 * (p * p)));
  259. }
  260. return 0.5f * (Mathf.Sqrt(-(2 * p - 3) * (2 * p - 1)) + 1);
  261. }
  262. /// <summary>
  263. /// Modeled after the exponential function y = 2^(10(x - 1))
  264. /// </summary>
  265. public static float ExponentialEaseIn(float p)
  266. {
  267. return p == 0.0f ? p : Mathf.Pow(2, 10 * (p - 1));
  268. }
  269. /// <summary>
  270. /// Modeled after the exponential function y = -2^(-10x) + 1
  271. /// </summary>
  272. public static float ExponentialEaseOut(float p)
  273. {
  274. return p == 1.0f ? p : 1 - Mathf.Pow(2, -10 * p);
  275. }
  276. /// <summary>
  277. /// Modeled after the piecewise exponential
  278. /// y = (1/2)2^(10(2x - 1)) ; [0,0.5)
  279. /// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1]
  280. /// </summary>
  281. public static float ExponentialEaseInOut(float p)
  282. {
  283. if (p == 0.0 || p == 1.0)
  284. {
  285. return p;
  286. }
  287. if (p < 0.5f)
  288. {
  289. return 0.5f * Mathf.Pow(2, 20 * p - 10);
  290. }
  291. return -0.5f * Mathf.Pow(2, -20 * p + 10) + 1;
  292. }
  293. /// <summary>
  294. /// Modeled after the damped sine wave y = sin(13pi/2*x)*Mathf.Pow(2, 10 * (x - 1))
  295. /// </summary>
  296. public static float ElasticEaseIn(float p)
  297. {
  298. return Mathf.Sin(13 * HALFPI * p) * Mathf.Pow(2, 10 * (p - 1));
  299. }
  300. /// <summary>
  301. /// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*Mathf.Pow(2, -10x) + 1
  302. /// </summary>
  303. public static float ElasticEaseOut(float p)
  304. {
  305. return Mathf.Sin(-13 * HALFPI * (p + 1)) * Mathf.Pow(2, -10 * p) + 1;
  306. }
  307. /// <summary>
  308. /// Modeled after the piecewise exponentially-damped sine wave:
  309. /// y = (1/2)*sin(13pi/2*(2*x))*Mathf.Pow(2, 10 * ((2*x) - 1)) ; [0,0.5)
  310. /// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*Mathf.Pow(2,-10(2*x-1)) + 2) ; [0.5, 1]
  311. /// </summary>
  312. public static float ElasticEaseInOut(float p)
  313. {
  314. if (p < 0.5f)
  315. {
  316. return 0.5f * Mathf.Sin(13 * HALFPI * (2 * p)) * Mathf.Pow(2, 10 * (2 * p - 1));
  317. }
  318. return 0.5f * (Mathf.Sin(-13 * HALFPI * (2 * p - 1 + 1)) * Mathf.Pow(2, -10 * (2 * p - 1)) + 2);
  319. }
  320. /// <summary>
  321. /// Modeled after the overshooting cubic y = x^3-x*sin(x*pi)
  322. /// </summary>
  323. public static float BackEaseIn(float p)
  324. {
  325. return p * p * p - p * Mathf.Sin(p * PI);
  326. }
  327. /// <summary>
  328. /// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi))
  329. /// </summary>
  330. public static float BackEaseOut(float p)
  331. {
  332. var f = 1 - p;
  333. return 1 - (f * f * f - f * Mathf.Sin(f * PI));
  334. }
  335. /// <summary>
  336. /// Modeled after the piecewise overshooting cubic function:
  337. /// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5)
  338. /// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1]
  339. /// </summary>
  340. public static float BackEaseInOut(float p)
  341. {
  342. if (p < 0.5f)
  343. {
  344. var f = 2 * p;
  345. return 0.5f * (f * f * f - f * Mathf.Sin(f * PI));
  346. }
  347. else
  348. {
  349. var f = 1 - (2 * p - 1);
  350. return 0.5f * (1 - (f * f * f - f * Mathf.Sin(f * PI))) + 0.5f;
  351. }
  352. }
  353. /// <summary>
  354. /// </summary>
  355. public static float BounceEaseIn(float p)
  356. {
  357. return 1 - BounceEaseOut(1 - p);
  358. }
  359. /// <summary>
  360. /// </summary>
  361. public static float BounceEaseOut(float p)
  362. {
  363. if (p < 4 / 11.0f)
  364. {
  365. return 121 * p * p / 16.0f;
  366. }
  367. if (p < 8 / 11.0f)
  368. {
  369. return 363 / 40.0f * p * p - 99 / 10.0f * p + 17 / 5.0f;
  370. }
  371. if (p < 9 / 10.0f)
  372. {
  373. return 4356 / 361.0f * p * p - 35442 / 1805.0f * p + 16061 / 1805.0f;
  374. }
  375. return 54 / 5.0f * p * p - 513 / 25.0f * p + 268 / 25.0f;
  376. }
  377. /// <summary>
  378. /// </summary>
  379. public static float BounceEaseInOut(float p)
  380. {
  381. if (p < 0.5f)
  382. {
  383. return 0.5f * BounceEaseIn(p * 2);
  384. }
  385. return 0.5f * BounceEaseOut(p * 2 - 1) + 0.5f;
  386. }
  387. }
  388. }