Tween.ts 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import EASINGS from './Easings'
  2. export default class Tween {
  3. static activeTweens: Tween[] = []
  4. static idCounter: number = 0
  5. id: number
  6. obj: any
  7. objStart: any
  8. objTarget: any
  9. startTime: number
  10. endTime: number
  11. easing: Function
  12. completedCallback: Function
  13. static create(obj, targetProperties, duration, easing = EASINGS.Linear.EaseNone, completedCallback = () => { }) {
  14. let singleTween = new Tween();
  15. singleTween.id = ++Tween.idCounter;
  16. singleTween.obj = obj;
  17. singleTween.objStart = {};
  18. singleTween.objTarget = targetProperties;
  19. Tween.saveProperties(singleTween.objStart, obj, targetProperties);
  20. singleTween.startTime = new Date().getTime();
  21. singleTween.endTime = singleTween.startTime + duration;
  22. singleTween.easing = easing;
  23. singleTween.completedCallback = completedCallback;
  24. Tween.activeTweens.push(singleTween);
  25. return singleTween.id;
  26. }
  27. static cancel(tweenId): Tween | undefined {
  28. let tween = Tween.activeTweens.find(tween => tweenId == tween.id);
  29. if (tween) {
  30. let index = Tween.activeTweens.indexOf(tween);
  31. Tween.activeTweens.splice(index, 1);
  32. return tween;
  33. }
  34. return
  35. };
  36. static stop(tweenId) {
  37. let tween = Tween.cancel(tweenId);
  38. tween?.completedCallback();
  39. return tween;
  40. };
  41. static saveProperties(singleTweenStart, obj, targetProperties) {
  42. for (let property in targetProperties) {
  43. let startValue = obj[property];
  44. if (typeof startValue == "object") {
  45. singleTweenStart[property] = {};
  46. Tween.saveProperties(singleTweenStart[property], obj[property], targetProperties[property]);
  47. continue;
  48. }
  49. singleTweenStart[property] = startValue;
  50. }
  51. }
  52. static update() {
  53. let completed: Tween[] = [];
  54. for (let i = 0; i < Tween.activeTweens.length; i++) {
  55. let singleTween = Tween.activeTweens[i];
  56. if (Tween.updateSingleTween(singleTween) == 1) {
  57. completed.push(singleTween);
  58. }
  59. }
  60. for (let i = 0; i < completed.length; i++) {
  61. let singleTween = completed[i];
  62. singleTween.completedCallback();
  63. let foundIndex = Tween.activeTweens.indexOf(singleTween);
  64. if (foundIndex != -1) {
  65. Tween.activeTweens.splice(foundIndex, 1);
  66. }
  67. }
  68. };
  69. static updateSingleTween(singleTween) {
  70. let currentTime = new Date().getTime();
  71. let runTime = currentTime - singleTween.startTime;
  72. let duration = singleTween.endTime - singleTween.startTime;
  73. let percentageComplete = Math.min(1, runTime / duration);
  74. let valueToUpdate = singleTween.easing(percentageComplete);
  75. Tween.updateProperties(singleTween.obj, singleTween.objStart, singleTween.objTarget, valueToUpdate);
  76. return percentageComplete;
  77. }
  78. static updateProperties(obj, objStart, objTarget, valueToUpdate) {
  79. for (let property in objStart) {
  80. let startValue = objStart[property];
  81. if (typeof startValue == "object") {
  82. Tween.updateProperties(obj[property], objStart[property], objTarget[property], valueToUpdate);
  83. continue;
  84. }
  85. let endValue = objTarget[property];
  86. let delta = endValue - startValue;
  87. obj[property] = startValue + (delta * valueToUpdate);
  88. }
  89. };
  90. };