EaseManager.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // Author: Daniele Giardini - http://www.demigiant.com
  2. // Created: 2014/07/19 14:11
  3. //
  4. // License Copyright (c) Daniele Giardini.
  5. // This work is subject to the terms at http://dotween.demigiant.com/license.php
  6. //
  7. // =============================================================
  8. // Contains Daniele Giardini's C# port of the easing equations created by Robert Penner
  9. // (all easing equations except for Flash, InFlash, OutFlash, InOutFlash,
  10. // which use some parts of Robert Penner's equations but were created by Daniele Giardini)
  11. // http://robertpenner.com/easing, see license below:
  12. // =============================================================
  13. //
  14. // TERMS OF USE - EASING EQUATIONS
  15. //
  16. // Open source under the BSD License.
  17. //
  18. // Copyright ? 2001 Robert Penner
  19. // All rights reserved.
  20. //
  21. // Redistribution and use in source and binary forms, with or without modification,
  22. // are permitted provided that the following conditions are met:
  23. //
  24. // - Redistributions of source code must retain the above copyright notice,
  25. // this list of conditions and the following disclaimer.
  26. // - Redistributions in binary form must reproduce the above copyright notice,
  27. // this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  28. // - Neither the name of the author nor the names of contributors may be used to endorse
  29. // or promote products derived from this software without specific prior written permission.
  30. // - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  31. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  32. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  33. // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  34. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  36. // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  37. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. using System;
  39. using UnityEngine;
  40. #pragma warning disable 1591
  41. namespace FairyGUI
  42. {
  43. public static class EaseManager
  44. {
  45. const float _PiOver2 = Mathf.PI * 0.5f;
  46. const float _TwoPi = Mathf.PI * 2;
  47. /// <summary>
  48. /// Returns a value between 0 and 1 (inclusive) based on the elapsed time and ease selected
  49. /// </summary>
  50. public static float Evaluate(EaseType easeType, float time, float duration,
  51. float overshootOrAmplitude = 1.70158f,
  52. float period = 0,
  53. CustomEase customEase = null)
  54. {
  55. if (duration <= 0)
  56. return 1;
  57. switch (easeType)
  58. {
  59. case EaseType.Linear:
  60. return time / duration;
  61. case EaseType.SineIn:
  62. return -(float)Math.Cos(time / duration * _PiOver2) + 1;
  63. case EaseType.SineOut:
  64. return (float)Math.Sin(time / duration * _PiOver2);
  65. case EaseType.SineInOut:
  66. return -0.5f * ((float)Math.Cos(Mathf.PI * time / duration) - 1);
  67. case EaseType.QuadIn:
  68. return (time /= duration) * time;
  69. case EaseType.QuadOut:
  70. return -(time /= duration) * (time - 2);
  71. case EaseType.QuadInOut:
  72. if ((time /= duration * 0.5f) < 1) return 0.5f * time * time;
  73. return -0.5f * ((--time) * (time - 2) - 1);
  74. case EaseType.CubicIn:
  75. return (time /= duration) * time * time;
  76. case EaseType.CubicOut:
  77. return ((time = time / duration - 1) * time * time + 1);
  78. case EaseType.CubicInOut:
  79. if ((time /= duration * 0.5f) < 1) return 0.5f * time * time * time;
  80. return 0.5f * ((time -= 2) * time * time + 2);
  81. case EaseType.QuartIn:
  82. return (time /= duration) * time * time * time;
  83. case EaseType.QuartOut:
  84. return -((time = time / duration - 1) * time * time * time - 1);
  85. case EaseType.QuartInOut:
  86. if ((time /= duration * 0.5f) < 1) return 0.5f * time * time * time * time;
  87. return -0.5f * ((time -= 2) * time * time * time - 2);
  88. case EaseType.QuintIn:
  89. return (time /= duration) * time * time * time * time;
  90. case EaseType.QuintOut:
  91. return ((time = time / duration - 1) * time * time * time * time + 1);
  92. case EaseType.QuintInOut:
  93. if ((time /= duration * 0.5f) < 1) return 0.5f * time * time * time * time * time;
  94. return 0.5f * ((time -= 2) * time * time * time * time + 2);
  95. case EaseType.ExpoIn:
  96. return (time == 0) ? 0 : (float)Math.Pow(2, 10 * (time / duration - 1));
  97. case EaseType.ExpoOut:
  98. if (time == duration) return 1;
  99. return (-(float)Math.Pow(2, -10 * time / duration) + 1);
  100. case EaseType.ExpoInOut:
  101. if (time == 0) return 0;
  102. if (time == duration) return 1;
  103. if ((time /= duration * 0.5f) < 1) return 0.5f * (float)Math.Pow(2, 10 * (time - 1));
  104. return 0.5f * (-(float)Math.Pow(2, -10 * --time) + 2);
  105. case EaseType.CircIn:
  106. return -((float)Math.Sqrt(1 - (time /= duration) * time) - 1);
  107. case EaseType.CircOut:
  108. return (float)Math.Sqrt(1 - (time = time / duration - 1) * time);
  109. case EaseType.CircInOut:
  110. if ((time /= duration * 0.5f) < 1) return -0.5f * ((float)Math.Sqrt(1 - time * time) - 1);
  111. return 0.5f * ((float)Math.Sqrt(1 - (time -= 2) * time) + 1);
  112. case EaseType.ElasticIn:
  113. float s0;
  114. if (time == 0) return 0;
  115. if ((time /= duration) == 1) return 1;
  116. if (period == 0) period = duration * 0.3f;
  117. if (overshootOrAmplitude < 1)
  118. {
  119. overshootOrAmplitude = 1;
  120. s0 = period / 4;
  121. }
  122. else s0 = period / _TwoPi * (float)Math.Asin(1 / overshootOrAmplitude);
  123. return -(overshootOrAmplitude * (float)Math.Pow(2, 10 * (time -= 1)) * (float)Math.Sin((time * duration - s0) * _TwoPi / period));
  124. case EaseType.ElasticOut:
  125. float s1;
  126. if (time == 0) return 0;
  127. if ((time /= duration) == 1) return 1;
  128. if (period == 0) period = duration * 0.3f;
  129. if (overshootOrAmplitude < 1)
  130. {
  131. overshootOrAmplitude = 1;
  132. s1 = period / 4;
  133. }
  134. else s1 = period / _TwoPi * (float)Math.Asin(1 / overshootOrAmplitude);
  135. return (overshootOrAmplitude * (float)Math.Pow(2, -10 * time) * (float)Math.Sin((time * duration - s1) * _TwoPi / period) + 1);
  136. case EaseType.ElasticInOut:
  137. float s;
  138. if (time == 0) return 0;
  139. if ((time /= duration * 0.5f) == 2) return 1;
  140. if (period == 0) period = duration * (0.3f * 1.5f);
  141. if (overshootOrAmplitude < 1)
  142. {
  143. overshootOrAmplitude = 1;
  144. s = period / 4;
  145. }
  146. else s = period / _TwoPi * (float)Math.Asin(1 / overshootOrAmplitude);
  147. if (time < 1) return -0.5f * (overshootOrAmplitude * (float)Math.Pow(2, 10 * (time -= 1)) * (float)Math.Sin((time * duration - s) * _TwoPi / period));
  148. return overshootOrAmplitude * (float)Math.Pow(2, -10 * (time -= 1)) * (float)Math.Sin((time * duration - s) * _TwoPi / period) * 0.5f + 1;
  149. case EaseType.BackIn:
  150. return (time /= duration) * time * ((overshootOrAmplitude + 1) * time - overshootOrAmplitude);
  151. case EaseType.BackOut:
  152. return ((time = time / duration - 1) * time * ((overshootOrAmplitude + 1) * time + overshootOrAmplitude) + 1);
  153. case EaseType.BackInOut:
  154. if ((time /= duration * 0.5f) < 1) return 0.5f * (time * time * (((overshootOrAmplitude *= (1.525f)) + 1) * time - overshootOrAmplitude));
  155. return 0.5f * ((time -= 2) * time * (((overshootOrAmplitude *= (1.525f)) + 1) * time + overshootOrAmplitude) + 2);
  156. case EaseType.BounceIn:
  157. return Bounce.EaseIn(time, duration);
  158. case EaseType.BounceOut:
  159. return Bounce.EaseOut(time, duration);
  160. case EaseType.BounceInOut:
  161. return Bounce.EaseInOut(time, duration);
  162. case EaseType.Custom:
  163. return customEase != null ? customEase.Evaluate(time / duration) : (time / duration);
  164. default:
  165. return -(time /= duration) * (time - 2);
  166. }
  167. }
  168. /// <summary>
  169. /// This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing).
  170. /// </summary>
  171. static class Bounce
  172. {
  173. /// <summary>
  174. /// Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in: accelerating from zero velocity.
  175. /// </summary>
  176. /// <param name="time">
  177. /// Current time (in frames or seconds).
  178. /// </param>
  179. /// <param name="duration">
  180. /// Expected easing duration (in frames or seconds).
  181. /// </param>
  182. /// <returns>
  183. /// The eased value.
  184. /// </returns>
  185. public static float EaseIn(float time, float duration)
  186. {
  187. return 1 - EaseOut(duration - time, duration);
  188. }
  189. /// <summary>
  190. /// Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating from zero velocity.
  191. /// </summary>
  192. /// <param name="time">
  193. /// Current time (in frames or seconds).
  194. /// </param>
  195. /// <param name="duration">
  196. /// Expected easing duration (in frames or seconds).
  197. /// </param>
  198. /// <returns>
  199. /// The eased value.
  200. /// </returns>
  201. public static float EaseOut(float time, float duration)
  202. {
  203. if ((time /= duration) < (1 / 2.75f))
  204. {
  205. return (7.5625f * time * time);
  206. }
  207. if (time < (2 / 2.75f))
  208. {
  209. return (7.5625f * (time -= (1.5f / 2.75f)) * time + 0.75f);
  210. }
  211. if (time < (2.5f / 2.75f))
  212. {
  213. return (7.5625f * (time -= (2.25f / 2.75f)) * time + 0.9375f);
  214. }
  215. return (7.5625f * (time -= (2.625f / 2.75f)) * time + 0.984375f);
  216. }
  217. /// <summary>
  218. /// Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out: acceleration until halfway, then deceleration.
  219. /// </summary>
  220. /// <param name="time">
  221. /// Current time (in frames or seconds).
  222. /// </param>
  223. /// <param name="duration">
  224. /// Expected easing duration (in frames or seconds).
  225. /// </param>
  226. /// <returns>
  227. /// The eased value.
  228. /// </returns>
  229. public static float EaseInOut(float time, float duration)
  230. {
  231. if (time < duration * 0.5f)
  232. {
  233. return EaseIn(time * 2, duration) * 0.5f;
  234. }
  235. return EaseOut(time * 2 - duration, duration) * 0.5f + 0.5f;
  236. }
  237. }
  238. }
  239. }