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