UNPKG

@xzdarcy/timeline-engine

Version:

Timeline engine for react-timeline-editor

3 lines (2 loc) 5.08 kB
class t{constructor(t){this.events={},this.events=t.handlers}on(t,e){return(t instanceof Array?t:t.split(" ")).forEach(t=>{if(!this.events[t])throw new Error(`The event ${t} does not exist`);this.events[t].push(e)}),this}trigger(t,e){if(!(t in this.events))throw new Error(`The event ${String(t)} cannot be triggered`);return this.events[t].reduce((t,i)=>!1!==i(e)&&t,!0)}bind(t){if(this.events[t])throw new Error(`The event ${t} is already bound`);this.events[t]=[]}exist(t){return Array.isArray(this.events[t])}off(t,e){if(this.events[t]){const i=this.events[t];if(e){const t=i.indexOf(e);-1!==t&&i.splice(t,1)}else this.events[t]=[]}}offAll(){this.events=Object.fromEntries(Object.keys(this.events).map(t=>[t,[]]))}}class e{constructor(t={}){this.handlers={},this.handlers={beforeSetTime:[],afterSetTime:[],setTimeByTick:[],beforeSetPlayRate:[],afterSetPlayRate:[],setActiveActionIds:[],play:[],paused:[],ended:[],...t}}}class i extends t{constructor(){super(new e),this._playRate=1,this._currentTime=0,this._playState="paused",this._prev=0,this._effectMap={},this._actionMap={},this._actionSortIds=[],this._next=0,this._activeActionIds=[]}get isPlaying(){return"playing"===this._playState}get isPaused(){return"paused"===this._playState}set effects(t){this._effectMap=t}set data(t){this.isPlaying&&this.pause(),this._dealData(t),this._dealClear(),this._dealEnter(this._currentTime)}setPlayRate(t){if(t<=0)return!1;return!!this.trigger("beforeSetPlayRate",{rate:t,engine:this})&&(this._playRate=t,this.trigger("afterSetPlayRate",{rate:t,engine:this}),!0)}getPlayRate(){return this._playRate}reRender(){this.isPlaying||this._tickAction(this._currentTime)}setTime(t,e){return!(!e&&!this.trigger("beforeSetTime",{time:t,engine:this}))&&(this._currentTime=t,this._next=0,this._dealLeave(t),this._dealEnter(t),e?this.trigger("setTimeByTick",{time:t,engine:this}):this.trigger("afterSetTime",{time:t,engine:this}),!0)}getTime(){return this._currentTime}play(t){const{toTime:e,autoEnd:i}=t,s=this.getTime();return!(this.isPlaying||e&&e<=s)&&(this._playState="playing",this._startOrStop("start"),this.trigger("play",{engine:this}),this._timerId=requestAnimationFrame(t=>{this._prev=t,this._tick({now:t,autoEnd:i,to:e})}),!0)}pause(){this.isPlaying&&(this._playState="paused",this._startOrStop("stop"),this.trigger("paused",{engine:this})),this._timerId&&cancelAnimationFrame(this._timerId)}_end(){this.pause(),this.trigger("ended",{engine:this})}_startOrStop(t){var e,i;for(let s=0;s<this._activeActionIds.length;s++){const n=this._activeActionIds[s],a=this._actionMap[n],r=this._effectMap[null==a?void 0:a.effectId];"start"===t?(null===(e=null==r?void 0:r.source)||void 0===e?void 0:e.start)&&r.source.start({action:a,effect:r,engine:this,isPlaying:this.isPlaying,time:this.getTime()}):"stop"===t&&(null===(i=null==r?void 0:r.source)||void 0===i?void 0:i.stop)&&r.source.stop({action:a,effect:r,engine:this,isPlaying:this.isPlaying,time:this.getTime()})}}_tick(t){if(this.isPaused)return;const{now:e,autoEnd:i,to:s}=t;let n=this.getTime()+Math.min(1e3,e-this._prev)/1e3*this._playRate;this._prev=e,s&&s<=n&&(n=s),this.setTime(n,!0),this._tickAction(n),!s&&i&&this._next>=this._actionSortIds.length&&0===this._activeActionIds.length?this._end():(s&&s<=n&&this._end(),this.isPaused||(this._timerId=requestAnimationFrame(t=>{this._tick({now:t,autoEnd:i,to:s})})))}_tickAction(t){var e;this._dealEnter(t),this._dealLeave(t);const i=this._activeActionIds.length;for(let s=0;s<i;s++){const i=this._activeActionIds[s],n=this._actionMap[i],a=this._effectMap[n.effectId];a&&(null===(e=a.source)||void 0===e?void 0:e.update)&&a.source.update({time:t,action:n,isPlaying:this.isPlaying,effect:a,engine:this})}}_dealClear(){for(var t;this._activeActionIds.length;){const e=this._activeActionIds.shift(),i=this._actionMap[e],s=this._effectMap[null==i?void 0:i.effectId];(null===(t=null==s?void 0:s.source)||void 0===t?void 0:t.leave)&&s.source.leave({action:i,effect:s,engine:this,isPlaying:this.isPlaying,time:this.getTime()})}this._next=0}_dealEnter(t){for(var e;this._actionSortIds[this._next];){const i=this._actionSortIds[this._next],s=this._actionMap[i];if(!s.disable){if(s.start>t)break;if(s.end>t&&!this._activeActionIds.includes(i)){const n=this._effectMap[s.effectId];n&&(null===(e=n.source)||void 0===e?void 0:e.enter)&&n.source.enter({action:s,effect:n,isPlaying:this.isPlaying,time:t,engine:this}),this._activeActionIds.push(i)}}this._next++}}_dealLeave(t){var e;let i=0;for(;this._activeActionIds[i];){const s=this._activeActionIds[i],n=this._actionMap[s];if(n.start>t||n.end<t){const s=this._effectMap[n.effectId];s&&(null===(e=s.source)||void 0===e?void 0:e.leave)&&s.source.leave({action:n,effect:s,isPlaying:this.isPlaying,time:t,engine:this}),this._activeActionIds.splice(i,1);continue}i++}}_dealData(t){const e=[];t.map(t=>{e.push(...t.actions)});const i=e.sort((t,e)=>t.start-e.start),s={},n=[];i.forEach(t=>{n.push(t.id),s[t.id]={...t}}),this._actionMap=s,this._actionSortIds=n}}export{t as Emitter,e as Events,i as TimelineEngine}; //# sourceMappingURL=index.esm.js.map