import { Easing } from "./Easing.js" class AsyncTween { constructor(objToTween, targetProperties, duration, easing = Easing.Linear.EaseNone) { this.id = AsyncTween.idCounter++ this.objectToTween = objToTween this.startProperties = {} this.targetProperties = JSON.parse(JSON.stringify(targetProperties)) this.saveInitialValues(this.startProperties, objToTween, targetProperties); this.startTime = new Date().getTime() this.endTime = this.startTime + duration this.easing = easing } saveInitialValues(propertiesObj, obj, targetProperties) { for(let property in targetProperties) { let startValue = obj[property]; if(typeof startValue == "object") { propertiesObj[property] = {}; this.saveInitialValues(propertiesObj[property], obj[property], targetProperties[property]); continue; } propertiesObj[property] = startValue; } } update() { let currentTime = new Date().getTime(); let runTime = currentTime - this.startTime; let duration = this.endTime - this.startTime; let percentageComplete = Math.min(1, runTime / duration); let valueToUpdate = this.easing(percentageComplete); this.updateProperties(this.objectToTween, this.startProperties, this.targetProperties, valueToUpdate); if(this.isComplete()) { this.completedCallback() } } updateProperties(obj, objStart, objTarget, valueToUpdate) { for(let property in objStart) { let startValue = objStart[property]; if(typeof startValue == "object") { this.updateProperties(obj[property], objStart[property], objTarget[property], valueToUpdate); continue; } let endValue = objTarget[property]; let delta = endValue - startValue; obj[property] = startValue + (delta * valueToUpdate); } } isComplete() { return this.endTime <= new Date().getTime() } abort() { this.updateProperties(this.objectToTween, this.startProperties, this.targetProperties, 0); AsyncTween.activeTweens.remove(this) } } AsyncTween.idCounter = 0 AsyncTween.activeTweens = [] AsyncTween.create = (objectToTween, targetProperties, duration, easing = Easing.Linear.EaseNone) => { const singleTween = new AsyncTween(objectToTween, targetProperties, duration, easing) AsyncTween.activeTweens.push(singleTween); return {promise: new Promise((resolve, reject) => { singleTween.completedCallback = () => { resolve() } }), tween: singleTween} } AsyncTween.update = () => { AsyncTween.activeTweens.forEach((tween) => { tween.update() }) AsyncTween.activeTweens = AsyncTween.activeTweens.filter((tween) => !tween.isComplete()) } AsyncTween.clear = () => { AsyncTween.activeTweens = [] AsyncTween.tweenIdIndex = 0; } export default AsyncTween