diff --git a/src/lib/exportPlayer.ts b/src/lib/exportPlayer.ts index 984cb54..d9405fe 100644 --- a/src/lib/exportPlayer.ts +++ b/src/lib/exportPlayer.ts @@ -1,6 +1,6 @@ import type { Scene } from '@/types/scene' -const RUNTIME_VERSION = '2' +const RUNTIME_VERSION = '3' const ENGINE_SOURCE = `(function(){ if (window.AnimatrPlayer && window.AnimatrPlayer.__v === '${RUNTIME_VERSION}') return; @@ -189,16 +189,80 @@ const ENGINE_SOURCE = `(function(){ } } var rangeLen=Math.max(0, rangeOut-rangeIn); + var runtime={ + fps: scene.fps||60, + rangeIn: rangeIn, + duration: scene.duration, + markers: {}, + jumpTo: null, + forcePause: false, + forcePlay: false, + buttonStates: {}, + buttonDisabled: {}, + warn: function(m){ if(window.console)window.console.warn('[animatr]',m); } + }; + (scene.markers||[]).forEach(function(mk){ runtime.markers[mk.name]=mk.time; }); + function evalAction(act){ + switch(act.type){ + case 'play': runtime.forcePlay=true; runtime.forcePause=false; return; + case 'pause': runtime.forcePause=true; runtime.forcePlay=false; return; + case 'rewindToLoop': runtime.jumpTo=runtime.rangeIn; return; + case 'jumpTo': runtime.jumpTo=Math.max(0,Math.min(runtime.duration,act.time)); return; + case 'jumpToFrame': runtime.jumpTo=Math.max(0,Math.min(runtime.duration,act.frame/runtime.fps)); return; + case 'jumpToMarker': { + var mt=runtime.markers[act.name]; + if(mt==null){ runtime.warn('Unknown marker: '+act.name); return; } + runtime.jumpTo=Math.max(0,Math.min(runtime.duration,mt)); + return; + } + case 'setButtonState': runtime.buttonStates[act.instanceId]=act.state; return; + case 'setButtonDisabled': runtime.buttonDisabled[act.instanceId]=act.disabled; return; + case 'script': runtime.warn('Script DSL not implemented'); return; + } + } + function fireFrames(prev, next){ + if(next<=prev) return; + var frames=scene.scriptFrames||[]; + var toFire=[]; + for(var ffi=0; ffiprev && fr.time<=next) toFire.push(fr); + } + toFire.sort(function(a,b){return a.time-b.time;}); + for(var ffj=0; ffj=rangeLen) t=rangeOut; - else t=rangeIn+elapsed; - draw(t); - syncBgVideo(t); + if(rangeLen<=0){ + draw(currentT); + syncBgVideo(currentT); + requestAnimationFrame(frame); + return; + } + if(!lastNow) lastNow=now; + var dt=(now-lastNow)/1000; + lastNow=now; + if(!paused){ + var prev=currentT; + var nextT=currentT+dt; + if(nextT>=rangeOut){ + fireFrames(prev, rangeOut); + currentT = loop ? rangeIn : rangeOut; + } else { + currentT=nextT; + fireFrames(prev, currentT); + } + if(runtime.jumpTo!=null){ currentT=runtime.jumpTo; runtime.jumpTo=null; } + if(runtime.forcePause){ paused=true; runtime.forcePause=false; } + if(runtime.forcePlay){ paused=false; runtime.forcePlay=false; } + } + draw(currentT); + syncBgVideo(currentT); requestAnimationFrame(frame); } function tracePolyPath(tctx,sp,ap,offX,offY,closed){