@hypernym/frame
Version:
Universal Frame Manager.
2 lines (1 loc) • 1.41 kB
JavaScript
function A(M={}){let{scheduler:h=typeof window<"u"?requestAnimationFrame:()=>{},loop:R=!0,fps:w=!1}=M;const d=new Map;let g=[],l=new WeakSet,S=0,o=!1,n=!1;const k=40;let c=1e3/(w||60),u=0,p=0,E=0;const F=()=>({delta:0,timestamp:0,isRunning:!1});let a=F();const y=()=>{let e=new Set,s=new Set,r=!1,i=!1;const f=t=>{l.has(t)&&m.schedule(t),t(a)},m={schedule(t,{loop:W,schedule:q=!0}={}){const v=r&&!q?e:s;return W&&!l.has(t)&&(l.add(t),S++),v.add(t),t},add(t){if(r){i=!0;return}r=!0,[e,s]=[s,e],e.forEach(f),e.clear(),r=!1,i&&(i=!1,m.add(t))},delete(t){s.delete(t),l.has(t)&&S--,l.delete(t)}};return m},x=()=>{if(n)return;const e=performance.now()-E;if(o=S>0,w){const s=e-u;if(s<c){n||h(x);return}u=e-s%c,a.delta=c}else a.delta=a.timestamp===0?c:Math.min(Math.max(e-a.timestamp,1),k),u=e;a.timestamp=e,a.isRunning=!0,g.forEach(s=>d.get(s)?.add(a)),a.isRunning=!1,o&&R&&!n&&h(x)};return{add(e,{loop:s,phase:r=0,schedule:i=!0}={}){let f=d.get(r);return f||(g.push(r),g.sort((m,t)=>m-t),f=y(),d.set(r,f)),o||(o=!0,u=performance.now(),h(x)),f.schedule(e,{loop:s,phase:r,schedule:i})},delete(e){if(!e){a=F(),d.clear(),g=[],l=new WeakSet,S=u=p=E=0,o=n=!1;return}d.forEach(s=>s.delete(e))},start(){if(n&&o){n=!1;const e=performance.now();p&&(E+=e-p,p=0),a.timestamp=u=e-E,h(x)}},stop(){n||(n=!0,p=performance.now())},get state(){return a},get fps(){return w},set fps(e){c=1e3/(e||60),w=e}}}export{A as createFrame};