easing.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. import { BezierCurve } from "../Maths/math.path.js";
  2. /**
  3. * Base class used for every default easing function.
  4. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  5. */
  6. export class EasingFunction {
  7. constructor() {
  8. this._easingMode = EasingFunction.EASINGMODE_EASEIN;
  9. }
  10. /**
  11. * Sets the easing mode of the current function.
  12. * @param easingMode Defines the willing mode (EASINGMODE_EASEIN, EASINGMODE_EASEOUT or EASINGMODE_EASEINOUT)
  13. */
  14. setEasingMode(easingMode) {
  15. const n = Math.min(Math.max(easingMode, 0), 2);
  16. this._easingMode = n;
  17. }
  18. /**
  19. * Gets the current easing mode.
  20. * @returns the easing mode
  21. */
  22. getEasingMode() {
  23. return this._easingMode;
  24. }
  25. /**
  26. * @internal
  27. */
  28. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  29. easeInCore(gradient) {
  30. throw new Error("You must implement this method");
  31. }
  32. /**
  33. * Given an input gradient between 0 and 1, this returns the corresponding value
  34. * of the easing function.
  35. * @param gradient Defines the value between 0 and 1 we want the easing value for
  36. * @returns the corresponding value on the curve defined by the easing function
  37. */
  38. ease(gradient) {
  39. switch (this._easingMode) {
  40. case EasingFunction.EASINGMODE_EASEIN:
  41. return this.easeInCore(gradient);
  42. case EasingFunction.EASINGMODE_EASEOUT:
  43. return 1 - this.easeInCore(1 - gradient);
  44. }
  45. if (gradient >= 0.5) {
  46. return (1 - this.easeInCore((1 - gradient) * 2)) * 0.5 + 0.5;
  47. }
  48. return this.easeInCore(gradient * 2) * 0.5;
  49. }
  50. }
  51. /**
  52. * Interpolation follows the mathematical formula associated with the easing function.
  53. */
  54. EasingFunction.EASINGMODE_EASEIN = 0;
  55. /**
  56. * Interpolation follows 100% interpolation minus the output of the formula associated with the easing function.
  57. */
  58. EasingFunction.EASINGMODE_EASEOUT = 1;
  59. /**
  60. * Interpolation uses EaseIn for the first half of the animation and EaseOut for the second half.
  61. */
  62. EasingFunction.EASINGMODE_EASEINOUT = 2;
  63. /**
  64. * Easing function with a circle shape (see link below).
  65. * @see https://easings.net/#easeInCirc
  66. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  67. */
  68. export class CircleEase extends EasingFunction {
  69. /**
  70. * @internal
  71. */
  72. easeInCore(gradient) {
  73. gradient = Math.max(0, Math.min(1, gradient));
  74. return 1.0 - Math.sqrt(1.0 - gradient * gradient);
  75. }
  76. }
  77. /**
  78. * Easing function with a ease back shape (see link below).
  79. * @see https://easings.net/#easeInBack
  80. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  81. */
  82. export class BackEase extends EasingFunction {
  83. /**
  84. * Instantiates a back ease easing
  85. * @see https://easings.net/#easeInBack
  86. * @param amplitude Defines the amplitude of the function
  87. */
  88. constructor(
  89. /** Defines the amplitude of the function */
  90. amplitude = 1) {
  91. super();
  92. this.amplitude = amplitude;
  93. }
  94. /**
  95. * @internal
  96. */
  97. easeInCore(gradient) {
  98. const num = Math.max(0, this.amplitude);
  99. return Math.pow(gradient, 3.0) - gradient * num * Math.sin(3.1415926535897931 * gradient);
  100. }
  101. }
  102. /**
  103. * Easing function with a bouncing shape (see link below).
  104. * @see https://easings.net/#easeInBounce
  105. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  106. */
  107. export class BounceEase extends EasingFunction {
  108. /**
  109. * Instantiates a bounce easing
  110. * @see https://easings.net/#easeInBounce
  111. * @param bounces Defines the number of bounces
  112. * @param bounciness Defines the amplitude of the bounce
  113. */
  114. constructor(
  115. /** Defines the number of bounces */
  116. bounces = 3,
  117. /** Defines the amplitude of the bounce */
  118. bounciness = 2) {
  119. super();
  120. this.bounces = bounces;
  121. this.bounciness = bounciness;
  122. }
  123. /**
  124. * @internal
  125. */
  126. easeInCore(gradient) {
  127. const y = Math.max(0.0, this.bounces);
  128. let bounciness = this.bounciness;
  129. if (bounciness <= 1.0) {
  130. bounciness = 1.001;
  131. }
  132. const num9 = Math.pow(bounciness, y);
  133. const num5 = 1.0 - bounciness;
  134. const num4 = (1.0 - num9) / num5 + num9 * 0.5;
  135. const num15 = gradient * num4;
  136. const num65 = Math.log(-num15 * (1.0 - bounciness) + 1.0) / Math.log(bounciness);
  137. const num3 = Math.floor(num65);
  138. const num13 = num3 + 1.0;
  139. const num8 = (1.0 - Math.pow(bounciness, num3)) / (num5 * num4);
  140. const num12 = (1.0 - Math.pow(bounciness, num13)) / (num5 * num4);
  141. const num7 = (num8 + num12) * 0.5;
  142. const num6 = gradient - num7;
  143. const num2 = num7 - num8;
  144. return (-Math.pow(1.0 / bounciness, y - num3) / (num2 * num2)) * (num6 - num2) * (num6 + num2);
  145. }
  146. }
  147. /**
  148. * Easing function with a power of 3 shape (see link below).
  149. * @see https://easings.net/#easeInCubic
  150. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  151. */
  152. export class CubicEase extends EasingFunction {
  153. /**
  154. * @internal
  155. */
  156. easeInCore(gradient) {
  157. return gradient * gradient * gradient;
  158. }
  159. }
  160. /**
  161. * Easing function with an elastic shape (see link below).
  162. * @see https://easings.net/#easeInElastic
  163. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  164. */
  165. export class ElasticEase extends EasingFunction {
  166. /**
  167. * Instantiates an elastic easing function
  168. * @see https://easings.net/#easeInElastic
  169. * @param oscillations Defines the number of oscillations
  170. * @param springiness Defines the amplitude of the oscillations
  171. */
  172. constructor(
  173. /** Defines the number of oscillations*/
  174. oscillations = 3,
  175. /** Defines the amplitude of the oscillations*/
  176. springiness = 3) {
  177. super();
  178. this.oscillations = oscillations;
  179. this.springiness = springiness;
  180. }
  181. /**
  182. * @internal
  183. */
  184. easeInCore(gradient) {
  185. let num2;
  186. const num3 = Math.max(0.0, this.oscillations);
  187. const num = Math.max(0.0, this.springiness);
  188. if (num == 0) {
  189. num2 = gradient;
  190. }
  191. else {
  192. num2 = (Math.exp(num * gradient) - 1.0) / (Math.exp(num) - 1.0);
  193. }
  194. return num2 * Math.sin((6.2831853071795862 * num3 + 1.5707963267948966) * gradient);
  195. }
  196. }
  197. /**
  198. * Easing function with an exponential shape (see link below).
  199. * @see https://easings.net/#easeInExpo
  200. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  201. */
  202. export class ExponentialEase extends EasingFunction {
  203. /**
  204. * Instantiates an exponential easing function
  205. * @see https://easings.net/#easeInExpo
  206. * @param exponent Defines the exponent of the function
  207. */
  208. constructor(
  209. /** Defines the exponent of the function */
  210. exponent = 2) {
  211. super();
  212. this.exponent = exponent;
  213. }
  214. /**
  215. * @internal
  216. */
  217. easeInCore(gradient) {
  218. if (this.exponent <= 0) {
  219. return gradient;
  220. }
  221. return (Math.exp(this.exponent * gradient) - 1.0) / (Math.exp(this.exponent) - 1.0);
  222. }
  223. }
  224. /**
  225. * Easing function with a power shape (see link below).
  226. * @see https://easings.net/#easeInQuad
  227. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  228. */
  229. export class PowerEase extends EasingFunction {
  230. /**
  231. * Instantiates an power base easing function
  232. * @see https://easings.net/#easeInQuad
  233. * @param power Defines the power of the function
  234. */
  235. constructor(
  236. /** Defines the power of the function */
  237. power = 2) {
  238. super();
  239. this.power = power;
  240. }
  241. /**
  242. * @internal
  243. */
  244. easeInCore(gradient) {
  245. const y = Math.max(0.0, this.power);
  246. return Math.pow(gradient, y);
  247. }
  248. }
  249. /**
  250. * Easing function with a power of 2 shape (see link below).
  251. * @see https://easings.net/#easeInQuad
  252. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  253. */
  254. export class QuadraticEase extends EasingFunction {
  255. /**
  256. * @internal
  257. */
  258. easeInCore(gradient) {
  259. return gradient * gradient;
  260. }
  261. }
  262. /**
  263. * Easing function with a power of 4 shape (see link below).
  264. * @see https://easings.net/#easeInQuart
  265. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  266. */
  267. export class QuarticEase extends EasingFunction {
  268. /**
  269. * @internal
  270. */
  271. easeInCore(gradient) {
  272. return gradient * gradient * gradient * gradient;
  273. }
  274. }
  275. /**
  276. * Easing function with a power of 5 shape (see link below).
  277. * @see https://easings.net/#easeInQuint
  278. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  279. */
  280. export class QuinticEase extends EasingFunction {
  281. /**
  282. * @internal
  283. */
  284. easeInCore(gradient) {
  285. return gradient * gradient * gradient * gradient * gradient;
  286. }
  287. }
  288. /**
  289. * Easing function with a sin shape (see link below).
  290. * @see https://easings.net/#easeInSine
  291. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  292. */
  293. export class SineEase extends EasingFunction {
  294. /**
  295. * @internal
  296. */
  297. easeInCore(gradient) {
  298. return 1.0 - Math.sin(1.5707963267948966 * (1.0 - gradient));
  299. }
  300. }
  301. /**
  302. * Easing function with a bezier shape (see link below).
  303. * @see http://cubic-bezier.com/#.17,.67,.83,.67
  304. * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#easing-functions
  305. */
  306. export class BezierCurveEase extends EasingFunction {
  307. /**
  308. * Instantiates a bezier function
  309. * @see http://cubic-bezier.com/#.17,.67,.83,.67
  310. * @param x1 Defines the x component of the start tangent in the bezier curve
  311. * @param y1 Defines the y component of the start tangent in the bezier curve
  312. * @param x2 Defines the x component of the end tangent in the bezier curve
  313. * @param y2 Defines the y component of the end tangent in the bezier curve
  314. */
  315. constructor(
  316. /** Defines the x component of the start tangent in the bezier curve */
  317. x1 = 0,
  318. /** Defines the y component of the start tangent in the bezier curve */
  319. y1 = 0,
  320. /** Defines the x component of the end tangent in the bezier curve */
  321. x2 = 1,
  322. /** Defines the y component of the end tangent in the bezier curve */
  323. y2 = 1) {
  324. super();
  325. this.x1 = x1;
  326. this.y1 = y1;
  327. this.x2 = x2;
  328. this.y2 = y2;
  329. }
  330. /**
  331. * @internal
  332. */
  333. easeInCore(gradient) {
  334. return BezierCurve.Interpolate(gradient, this.x1, this.y1, this.x2, this.y2);
  335. }
  336. }
  337. //# sourceMappingURL=easing.js.map