Home Reference Source

cables_dev/cables/src/core/anim_key.js

  1. import { CONSTANTS } from "./constants.js";
  2.  
  3. const Key = function (obj)
  4. {
  5. this.time = 0.0;
  6. this.value = 0.0;
  7. // this.ui = null;
  8. this.onChange = null;
  9. this._easing = 0;
  10. // this.bezTangIn = 0;
  11. // this.bezTangOut = 0;
  12. // this.bezTime = 0.5;
  13. // this.bezValue = 0;
  14. // this.bezTimeIn = -0.5;
  15. // this.bezValueIn = 0;
  16.  
  17. this.cb = null;
  18. this.cbTriggered = false;
  19.  
  20. // const bezierAnim = null;
  21. // this._updateBezier = false;
  22.  
  23. this.setEasing(CONSTANTS.ANIM.EASING_LINEAR);
  24. this.set(obj);
  25. };
  26.  
  27. Key.cubicSpline = function (perc, key1, key2)
  28. {
  29. let
  30. previousPoint = key1.value,
  31. previousTangent = key1.bezTangOut,
  32. nextPoint = key2.value,
  33. nextTangent = key2.bezTangIn;
  34. let t = perc;
  35. let t2 = t * t;
  36. let t3 = t2 * t;
  37.  
  38. return (2 * t3 - 3 * t2 + 1) * previousPoint + (t3 - 2 * t2 + t) * previousTangent + (-2 * t3 + 3 * t2) * nextPoint + (t3 - t2) * nextTangent;
  39. };
  40.  
  41. Key.easeCubicSpline = function (perc, key2)
  42. {
  43. return Key.cubicSpline(perc, this, key2);
  44. };
  45.  
  46.  
  47. Key.linear = function (perc, key1, key2)
  48. {
  49. return parseFloat(key1.value) + parseFloat(key2.value - key1.value) * perc;
  50. };
  51.  
  52. Key.easeLinear = function (perc, key2)
  53. {
  54. return Key.linear(perc, this, key2);
  55. };
  56.  
  57. Key.easeAbsolute = function (perc, key2)
  58. {
  59. return this.value;
  60. };
  61.  
  62. export const easeExpoIn = function (t)
  63. {
  64. return (t = 2 ** (10 * (t - 1)));
  65. };
  66.  
  67. Key.easeExpoIn = function (t, key2)
  68. {
  69. t = easeExpoIn(t);
  70. return Key.linear(t, this, key2);
  71. };
  72.  
  73. export const easeExpoOut = function (t)
  74. {
  75. t = -(2 ** (-10 * t)) + 1;
  76. return t;
  77. };
  78.  
  79. Key.easeExpoOut = function (t, key2)
  80. {
  81. t = easeExpoOut(t);
  82. return Key.linear(t, this, key2);
  83. };
  84.  
  85. export const easeExpoInOut = function (t)
  86. {
  87. t *= 2;
  88. if (t < 1)
  89. {
  90. t = 0.5 * 2 ** (10 * (t - 1));
  91. }
  92. else
  93. {
  94. t--;
  95. t = 0.5 * (-(2 ** (-10 * t)) + 2);
  96. }
  97. return t;
  98. };
  99.  
  100. Key.easeExpoInOut = function (t, key2)
  101. {
  102. t = easeExpoInOut(t);
  103. return Key.linear(t, this, key2);
  104. };
  105.  
  106. Key.easeSinIn = function (t, key2)
  107. {
  108. t = -1 * Math.cos((t * Math.PI) / 2) + 1;
  109. return Key.linear(t, this, key2);
  110. };
  111.  
  112. Key.easeSinOut = function (t, key2)
  113. {
  114. t = Math.sin((t * Math.PI) / 2);
  115. return Key.linear(t, this, key2);
  116. };
  117.  
  118. Key.easeSinInOut = function (t, key2)
  119. {
  120. t = -0.5 * (Math.cos(Math.PI * t) - 1.0);
  121. return Key.linear(t, this, key2);
  122. };
  123.  
  124. export const easeCubicIn = function (t)
  125. {
  126. t = t * t * t;
  127. return t;
  128. };
  129.  
  130. Key.easeCubicIn = function (t, key2)
  131. {
  132. t = easeCubicIn(t);
  133. return Key.linear(t, this, key2);
  134. };
  135.  
  136.  
  137. // b 0
  138. // c 1/2 or 1
  139. // d always 1
  140. // easeOutCubic: function (x, t, b, c, d) {
  141. // return c*((t=t/d-1)*t*t + 1) + b;
  142.  
  143. Key.easeInQuint = function (t, key2)
  144. {
  145. t = t * t * t * t * t;
  146. return Key.linear(t, this, key2);
  147. };
  148. Key.easeOutQuint = function (t, key2)
  149. {
  150. t = (t -= 1) * t * t * t * t + 1;
  151. return Key.linear(t, this, key2);
  152. };
  153. Key.easeInOutQuint = function (t, key2)
  154. {
  155. if ((t /= 0.5) < 1) t = 0.5 * t * t * t * t * t;
  156. else t = 0.5 * ((t -= 2) * t * t * t * t + 2);
  157. return Key.linear(t, this, key2);
  158. };
  159.  
  160. Key.easeInQuart = function (t, key2)
  161. {
  162. t = t * t * t * t;
  163. return Key.linear(t, this, key2);
  164. };
  165.  
  166. Key.easeOutQuart = function (t, key2)
  167. {
  168. // return -c * ((t=t/d-1)*t*t*t - 1) + b;
  169. t = -1 * ((t -= 1) * t * t * t - 1);
  170. return Key.linear(t, this, key2);
  171. };
  172.  
  173. Key.easeInOutQuart = function (t, key2)
  174. {
  175. if ((t /= 0.5) < 1) t = 0.5 * t * t * t * t;
  176. else t = -0.5 * ((t -= 2) * t * t * t - 2);
  177. return Key.linear(t, this, key2);
  178. };
  179.  
  180. Key.bounce = function (t)
  181. {
  182. if ((t /= 1) < 1 / 2.75) t = 7.5625 * t * t;
  183. else if (t < 2 / 2.75) t = 7.5625 * (t -= 1.5 / 2.75) * t + 0.75;
  184. else if (t < 2.5 / 2.75) t = 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375;
  185. else t = 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375;
  186. return t;
  187. };
  188.  
  189. Key.easeInBounce = function (t, key2)
  190. {
  191. return Key.linear(Key.bounce(t), this, key2);
  192. // return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d);
  193. };
  194.  
  195. Key.easeOutBounce = function (t, key2)
  196. {
  197. return Key.linear(Key.bounce(t), this, key2);
  198. };
  199.  
  200. Key.easeInElastic = function (t, key2)
  201. {
  202. let s = 1.70158;
  203. let p = 0;
  204. let a = 1;
  205.  
  206. const b = 0;
  207. const d = 1;
  208. const c = 1;
  209.  
  210. if (t === 0) t = b;
  211. else if ((t /= d) == 1) t = b + c;
  212. else
  213. {
  214. if (!p) p = d * 0.3;
  215. if (a < Math.abs(c))
  216. {
  217. a = c;
  218. s = p / 4;
  219. }
  220. else s = (p / (2 * Math.PI)) * Math.asin(c / a);
  221. t = -(a * 2 ** (10 * (t -= 1)) * Math.sin(((t * d - s) * (2 * Math.PI)) / p)) + b;
  222. }
  223.  
  224. return Key.linear(t, this, key2);
  225. };
  226.  
  227.  
  228. Key.easeOutElastic = function (t, key2)
  229. {
  230. let s = 1.70158;
  231. let p = 0;
  232. let a = 1;
  233.  
  234. const b = 0;
  235. const d = 1;
  236. const c = 1;
  237.  
  238. if (t === 0) t = b;
  239. else if ((t /= d) == 1) t = b + c;
  240. else
  241. {
  242. if (!p) p = d * 0.3;
  243. if (a < Math.abs(c))
  244. {
  245. a = c;
  246. s = p / 4;
  247. }
  248. else s = (p / (2 * Math.PI)) * Math.asin(c / a);
  249. t = a * 2 ** (-10 * t) * Math.sin(((t * d - s) * (2 * Math.PI)) / p) + c + b;
  250. }
  251.  
  252. return Key.linear(t, this, key2);
  253. };
  254.  
  255. Key.easeInBack = function (t, key2)
  256. {
  257. const s = 1.70158;
  258. t = t * t * ((s + 1) * t - s);
  259.  
  260. return Key.linear(t, this, key2);
  261. };
  262.  
  263. Key.easeOutBack = function (t, key2)
  264. {
  265. const s = 1.70158;
  266. t = (t = t / 1 - 1) * t * ((s + 1) * t + s) + 1;
  267.  
  268. return Key.linear(t, this, key2);
  269. };
  270.  
  271. Key.easeInOutBack = function (t, key2)
  272. {
  273. let s = 1.70158;
  274. const c = 1 / 2;
  275. if ((t /= 1 / 2) < 1) t = c * (t * t * (((s *= 1.525) + 1) * t - s));
  276. else t = c * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2);
  277.  
  278. return Key.linear(t, this, key2);
  279. };
  280.  
  281. export const easeCubicOut = function (t)
  282. {
  283. t--;
  284. t = t * t * t + 1;
  285. return t;
  286. };
  287.  
  288. Key.easeCubicOut = function (t, key2)
  289. {
  290. t = easeCubicOut(t);
  291. return Key.linear(t, this, key2);
  292. };
  293.  
  294. export const easeCubicInOut = function (t)
  295. {
  296. t *= 2;
  297. if (t < 1) t = 0.5 * t * t * t;
  298. else
  299. {
  300. t -= 2;
  301. t = 0.5 * (t * t * t + 2);
  302. }
  303. return t;
  304. };
  305.  
  306. Key.easeCubicInOut = function (t, key2)
  307. {
  308. t = easeCubicInOut(t);
  309. return Key.linear(t, this, key2);
  310. };
  311.  
  312. Key.easeSmoothStep = function (perc, key2)
  313. {
  314. // var x = Math.max(0, Math.min(1, (perc-0)/(1-0)));
  315. const x = Math.max(0, Math.min(1, perc));
  316. perc = x * x * (3 - 2 * x); // smoothstep
  317. return Key.linear(perc, this, key2);
  318. };
  319.  
  320. Key.easeSmootherStep = function (perc, key2)
  321. {
  322. const x = Math.max(0, Math.min(1, (perc - 0) / (1 - 0)));
  323. perc = x * x * x * (x * (x * 6 - 15) + 10); // smootherstep
  324. return Key.linear(perc, this, key2);
  325. };
  326.  
  327. Key.prototype.setEasing = function (e)
  328. {
  329. this._easing = e;
  330.  
  331. if (this._easing == CONSTANTS.ANIM.EASING_LINEAR) this.ease = Key.easeLinear;
  332. else if (this._easing == CONSTANTS.ANIM.EASING_ABSOLUTE) this.ease = Key.easeAbsolute;
  333. else if (this._easing == CONSTANTS.ANIM.EASING_SMOOTHSTEP) this.ease = Key.easeSmoothStep;
  334. else if (this._easing == CONSTANTS.ANIM.EASING_SMOOTHERSTEP) this.ease = Key.easeSmootherStep;
  335. else if (this._easing == CONSTANTS.ANIM.EASING_CUBIC_IN) this.ease = Key.easeCubicIn;
  336. else if (this._easing == CONSTANTS.ANIM.EASING_CUBIC_OUT) this.ease = Key.easeCubicOut;
  337. else if (this._easing == CONSTANTS.ANIM.EASING_CUBIC_INOUT) this.ease = Key.easeCubicInOut;
  338. else if (this._easing == CONSTANTS.ANIM.EASING_EXPO_IN) this.ease = Key.easeExpoIn;
  339. else if (this._easing == CONSTANTS.ANIM.EASING_EXPO_OUT) this.ease = Key.easeExpoOut;
  340. else if (this._easing == CONSTANTS.ANIM.EASING_EXPO_INOUT) this.ease = Key.easeExpoInOut;
  341. else if (this._easing == CONSTANTS.ANIM.EASING_SIN_IN) this.ease = Key.easeSinIn;
  342. else if (this._easing == CONSTANTS.ANIM.EASING_SIN_OUT) this.ease = Key.easeSinOut;
  343. else if (this._easing == CONSTANTS.ANIM.EASING_SIN_INOUT) this.ease = Key.easeSinInOut;
  344. else if (this._easing == CONSTANTS.ANIM.EASING_BACK_OUT) this.ease = Key.easeOutBack;
  345. else if (this._easing == CONSTANTS.ANIM.EASING_BACK_IN) this.ease = Key.easeInBack;
  346. else if (this._easing == CONSTANTS.ANIM.EASING_BACK_INOUT) this.ease = Key.easeInOutBack;
  347. else if (this._easing == CONSTANTS.ANIM.EASING_ELASTIC_IN) this.ease = Key.easeInElastic;
  348. else if (this._easing == CONSTANTS.ANIM.EASING_ELASTIC_OUT) this.ease = Key.easeOutElastic;
  349. else if (this._easing == CONSTANTS.ANIM.EASING_ELASTIC_INOUT) this.ease = Key.easeElasticInOut;
  350. else if (this._easing == CONSTANTS.ANIM.EASING_BOUNCE_IN) this.ease = Key.easeInBounce;
  351. else if (this._easing == CONSTANTS.ANIM.EASING_BOUNCE_OUT) this.ease = Key.easeOutBounce;
  352. else if (this._easing == CONSTANTS.ANIM.EASING_QUART_OUT) this.ease = Key.easeOutQuart;
  353. else if (this._easing == CONSTANTS.ANIM.EASING_QUART_IN) this.ease = Key.easeInQuart;
  354. else if (this._easing == CONSTANTS.ANIM.EASING_QUART_INOUT) this.ease = Key.easeInOutQuart;
  355. else if (this._easing == CONSTANTS.ANIM.EASING_QUINT_OUT) this.ease = Key.easeOutQuint;
  356. else if (this._easing == CONSTANTS.ANIM.EASING_QUINT_IN) this.ease = Key.easeInQuint;
  357. else if (this._easing == CONSTANTS.ANIM.EASING_QUINT_INOUT) this.ease = Key.easeInOutQuint;
  358. else if (this._easing == CONSTANTS.ANIM.EASING_CUBICSPLINE)
  359. {
  360. // this._updateBezier = true;
  361. this.ease = Key.easeCubicSpline;
  362. }
  363. else
  364. {
  365. this._easing = CONSTANTS.ANIM.EASING_LINEAR;
  366. this.ease = Key.easeLinear;
  367. }
  368. };
  369.  
  370. Key.prototype.trigger = function ()
  371. {
  372. this.cb();
  373. this.cbTriggered = true;
  374. };
  375.  
  376. Key.prototype.setValue = function (v)
  377. {
  378. this.value = v;
  379. // this._updateBezier = true;
  380. if (this.onChange !== null) this.onChange();
  381. };
  382.  
  383. Key.prototype.set = function (obj)
  384. {
  385. if (obj)
  386. {
  387. if (obj.e) this.setEasing(obj.e);
  388. if (obj.cb)
  389. {
  390. this.cb = obj.cb;
  391. this.cbTriggered = false;
  392. }
  393.  
  394. if (obj.b)
  395. {
  396. // this.bezTime = obj.b[0];
  397. // this.bezValue = obj.b[1];
  398. // this.bezTimeIn = obj.b[2];
  399. // this.bezValueIn = obj.b[3];
  400. // this._updateBezier = true;
  401. }
  402.  
  403. if (obj.hasOwnProperty("t")) this.time = obj.t;
  404. if (obj.hasOwnProperty("time")) this.time = obj.time;
  405. if (obj.hasOwnProperty("v")) this.value = obj.v;
  406. else if (obj.hasOwnProperty("value")) this.value = obj.value;
  407. }
  408. if (this.onChange !== null) this.onChange();
  409. };
  410.  
  411. Key.prototype.getSerialized = function ()
  412. {
  413. const obj = {};
  414. obj.t = this.time;
  415. obj.v = this.value;
  416. obj.e = this._easing;
  417. // if (this._easing == CONSTANTS.ANIM.EASING_CUBICSPLINE) obj.b = [this.bezTime, this.bezValue, this.bezTimeIn, this.bezValueIn];
  418.  
  419. return obj;
  420. };
  421.  
  422. Key.prototype.getEasing = function ()
  423. {
  424. return this._easing;
  425. };
  426.  
  427. export { Key };