AsyncTween.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { Easing } from "./Easing.js"
  2. class AsyncTween {
  3. constructor(objToTween, targetProperties, duration, easing = Easing.Linear.EaseNone) {
  4. this.id = AsyncTween.idCounter++
  5. this.objectToTween = objToTween
  6. this.startProperties = {}
  7. this.targetProperties = JSON.parse(JSON.stringify(targetProperties))
  8. this.saveInitialValues(this.startProperties, objToTween, targetProperties);
  9. this.startTime = new Date().getTime()
  10. this.endTime = this.startTime + duration
  11. this.easing = easing
  12. }
  13. saveInitialValues(propertiesObj, obj, targetProperties) {
  14. for(let property in targetProperties) {
  15. let startValue = obj[property];
  16. if(typeof startValue == "object") {
  17. propertiesObj[property] = {};
  18. this.saveInitialValues(propertiesObj[property], obj[property], targetProperties[property]);
  19. continue;
  20. }
  21. propertiesObj[property] = startValue;
  22. }
  23. }
  24. update() {
  25. let currentTime = new Date().getTime();
  26. let runTime = currentTime - this.startTime;
  27. let duration = this.endTime - this.startTime;
  28. let percentageComplete = Math.min(1, runTime / duration);
  29. let valueToUpdate = this.easing(percentageComplete);
  30. this.updateProperties(this.objectToTween, this.startProperties, this.targetProperties, valueToUpdate);
  31. if(this.isComplete()) {
  32. this.completedCallback()
  33. }
  34. }
  35. updateProperties(obj, objStart, objTarget, valueToUpdate) {
  36. for(let property in objStart) {
  37. let startValue = objStart[property];
  38. if(typeof startValue == "object") {
  39. this.updateProperties(obj[property], objStart[property], objTarget[property], valueToUpdate);
  40. continue;
  41. }
  42. let endValue = objTarget[property];
  43. let delta = endValue - startValue;
  44. obj[property] = startValue + (delta * valueToUpdate);
  45. }
  46. }
  47. isComplete() {
  48. return this.endTime <= new Date().getTime()
  49. }
  50. abort() {
  51. this.updateProperties(this.objectToTween, this.startProperties, this.targetProperties, 0);
  52. AsyncTween.activeTweens.remove(this)
  53. }
  54. }
  55. AsyncTween.idCounter = 0
  56. AsyncTween.activeTweens = []
  57. AsyncTween.create = (objectToTween, targetProperties, duration, easing = Easing.Linear.EaseNone) => {
  58. const singleTween = new AsyncTween(objectToTween, targetProperties, duration, easing)
  59. AsyncTween.activeTweens.push(singleTween);
  60. return {promise: new Promise((resolve, reject) => {
  61. singleTween.completedCallback = () => {
  62. resolve()
  63. }
  64. }), tween: singleTween}
  65. }
  66. AsyncTween.update = () => {
  67. AsyncTween.activeTweens.forEach((tween) => {
  68. tween.update()
  69. })
  70. AsyncTween.activeTweens = AsyncTween.activeTweens.filter((tween) => !tween.isComplete())
  71. }
  72. AsyncTween.clear = () => {
  73. AsyncTween.activeTweens = []
  74. AsyncTween.tweenIdIndex = 0;
  75. }
  76. export default AsyncTween