@jucie.io/engine-painter 1.0.68 → 1.0.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +1 -1
- package/dist/main.js.map +2 -2
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var f={"2D":"2d",WEBGL:"webgl",WEBGL2:"webgl2",BITMAPRENDERER:"bitmaprenderer"};var g=class{#e=new Map;register(t,e){if(!t)throw new Error("Hit area must have an id");return this.#e.set(t,{id:t,...e}),()=>this.unregister(t)}unregister(t){this.#e.delete(t)}get(t){return this.#e.get(t)}has(t){return this.#e.has(t)}get areas(){return Array.from(this.#e.values())}clear(){this.#e.clear()}};import{ServiceProvider as E}from"@jucie.io/engine";var m=class extends E{#e=null;#c=null;#r=null;#n=null;#w=new Set;#g=new Set;#d=null;#f=null;#y=!1;#i=new Set;#t={isPressed:!1,button:null,dragStartX:null,dragStartY:null,isDragging:!1,dragThreshold:5,prevX:null,prevY:null,lastClickTime:null,lastClickX:null,lastClickY:null,lastClickIsOverCanvas:null,doubleClickThreshold:300,doubleClickDistanceThreshold:5,isExternalDragOver:!1,externalDragData:null};static manifest={name:"CanvasEvents",namespace:"canvasEvents",version:"1.0.0"};actions(){return{setCanvas:t=>this.setCanvas(t),subscribe:t=>this.subscribe(t),onResize:t=>this.onResize(t),transferControlToOffscreen:()=>this.transferControlToOffscreen(),onFileDrop:t=>this.#x(t)}}setCanvas(t){this.#e&&this.#b(),this.#e=t,this.#a(),this.#m()}subscribe(t){return this.#w.add(t),()=>this.#w.delete(t)}onResize(t){return this.#g.add(t),()=>this.#g.delete(t)}transferControlToOffscreen(){if(!this.#e)throw new Error("Canvas must be set before transferring control to offscreen");if(this.#y)throw new Error("Control has already been transferred to offscreen");return this.#c=this.#e.transferControlToOffscreen(),this.#y=!0,this.#c.width=this.#r.width,this.#c.height=this.#r.height,this.#Y({width:this.#e.width,height:this.#e.height}),this.#c}#x(t){return this.#i.add(t),()=>this.#i.delete(t)}#D(...t){for(let e of this.#i)e(...t)}#a(){this.#e&&(this.#r=this.#e.getBoundingClientRect())}#m(){this.#e&&(this.#a(),this.#n=new ResizeObserver(t=>{for(let e of t){if(e.target!==this.#e)continue;let{width:s,height:i}=e.contentRect;this.#Y({width:s,height:i})}this.#a()}),this.#n.observe(this.#e),this.#e.addEventListener("wheel",this.#u,{passive:!1}),this.#e.addEventListener("pointerdown",this.#R),this.#e.addEventListener("dragenter",this.#P),this.#e.addEventListener("dragover",this.#O),this.#e.addEventListener("dragleave",this.#k),this.#e.addEventListener("drop",this.#T),document.addEventListener("pointermove",this.#p),document.addEventListener("pointerup",this.#C),document.addEventListener("pointercancel",this.#E))}#b(){this.#n&&(this.#n.disconnect(),this.#n=null),this.#e&&(this.#e.removeEventListener("wheel",this.#u),this.#e.removeEventListener("pointerdown",this.#R),this.#e.removeEventListener("dragenter",this.#P),this.#e.removeEventListener("dragover",this.#O),this.#e.removeEventListener("dragleave",this.#k),this.#e.removeEventListener("drop",this.#T)),document.removeEventListener("pointermove",this.#p),document.removeEventListener("pointerup",this.#C),document.removeEventListener("pointercancel",this.#E)}#u=t=>{if(t.preventDefault(),t.stopPropagation(),t.ctrlKey){let e=this.#h(t,"zoom");this.#o(e)}else{let e=this.#h(t,"scroll");this.#o(e)}};#p=t=>{this.#d=t,!this.#f&&(this.#f=requestAnimationFrame(()=>{if(this.#d){let e=this.#d;this.#d=null;let s="move",i=this.#v(e);if(this.#t.isPressed&&!this.#t.isDragging){let r=i.x-this.#t.dragStartX,a=i.y-this.#t.dragStartY;Math.sqrt(r*r+a*a)>this.#t.dragThreshold&&(this.#t.isDragging=!0,s="dragstart")}else this.#t.isDragging&&(s="drag");let n=this.#h(e,s);this.#o(n)}this.#f=null}))};#R=t=>{let e=this.#v(t);this.#t.isPressed=!0,this.#t.button=t.button??null,this.#t.dragStartX=e.x,this.#t.dragStartY=e.y,this.#t.isDragging=!1;try{this.#e.setPointerCapture(t.pointerId)}catch(i){console.warn("Failed to capture pointer:",i)}let s=this.#h(t,"down");this.#o(s)};#C=t=>{if(this.#e&&this.#t.isPressed)try{this.#e.releasePointerCapture(t.pointerId)}catch{}if(this.#t.isDragging){let s=this.#h(t,"dragend");this.#o(s)}if(!this.#t.isDragging){let s=this.#v(t),i=Date.now();if(this.#t.lastClickTime!==null){let n=i-this.#t.lastClickTime,r=s.x-this.#t.lastClickX,a=s.y-this.#t.lastClickY,o=Math.sqrt(r*r+a*a);if(n<this.#t.doubleClickThreshold&&o<this.#t.doubleClickDistanceThreshold&&s.isOverCanvas&&this.#t.lastClickIsOverCanvas){let h=this.#h(t,"dblclick");this.#o(h),this.#t.lastClickTime=null,this.#t.lastClickX=null,this.#t.lastClickY=null,this.#t.lastClickIsOverCanvas=null}else s.isOverCanvas?(this.#t.lastClickTime=i,this.#t.lastClickX=s.x,this.#t.lastClickY=s.y,this.#t.lastClickIsOverCanvas=!0):(this.#t.lastClickTime=null,this.#t.lastClickX=null,this.#t.lastClickY=null,this.#t.lastClickIsOverCanvas=null)}else s.isOverCanvas&&(this.#t.lastClickTime=i,this.#t.lastClickX=s.x,this.#t.lastClickY=s.y,this.#t.lastClickIsOverCanvas=!0)}let e=this.#h(t,"up");this.#o(e),this.#t.isPressed=!1,this.#t.isDragging=!1,this.#t.dragStartX=null,this.#t.dragStartY=null};#E=t=>{if(this.#e&&this.#t.isPressed)try{this.#e.releasePointerCapture(t.pointerId)}catch{}if(this.#t.isDragging){let s=this.#h(t,"dragend");this.#o(s)}let e=this.#h(t,"cancel");this.#o(e),this.#t.isPressed=!1,this.#t.isDragging=!1,this.#t.dragStartX=null,this.#t.dragStartY=null};#P=t=>{t.preventDefault(),this.#t.isExternalDragOver=!0,this.#t.externalDragData=this.#L(t.dataTransfer);let e=this.#h(t,"dragenter");this.#o(e)};#O=t=>{t.preventDefault(),t.dataTransfer.dropEffect=this.#t.externalDragData?.hasFiles?"copy":"move";let e=this.#h(t,"dragover");this.#o(e)};#k=t=>{t.preventDefault();let e=this.#e.getBoundingClientRect();if(t.clientX<e.left||t.clientX>=e.right||t.clientY<e.top||t.clientY>=e.bottom){this.#t.isExternalDragOver=!1,this.#t.externalDragData=null;let i=this.#h(t,"dragleave");this.#o(i)}};#T=t=>{t.preventDefault(),this.#t.isExternalDragOver=!1,this.#t.externalDragData=this.#L(t.dataTransfer);let e=this.#h(t,"drop"),s=this.#A(t.dataTransfer);this.#D(s,e),this.#o(e),this.#t.externalDragData=null};#A(t){let e=[];if(t?.items){console.log("\u{1F4E6} Processing",t.items.length,"items");for(let s of t.items)if(s.kind==="file"){let i=s.getAsFile();i&&e.push(i)}}if(e.length===0&&t?.files){console.log("\u{1F4E6} Fallback to DataTransfer.files:",t.files.length,"files");for(let s=0;s<t.files.length;s++){let i=t.files[s];i&&e.push(i)}}return e}#L(t){return t?{types:Array.from(t.types),hasFiles:t.types.includes("Files"),fileCount:t.items?.length||0,effectAllowed:t.effectAllowed}:null}#o(t){for(let e of this.#w)e(t)}#Y(t){for(let e of this.#g)e(t)}#v(t){let e=t.target===this.#e,s,i;return e?(s=t.offsetX,i=t.offsetY):this.#r?(s=t.clientX-this.#r.left,i=t.clientY-this.#r.top):(s=t.clientX,i=t.clientY),{x:s,y:i,isOverCanvas:e}}#h(t,e){let{x:s,y:i,isOverCanvas:n}=this.#v(t),r=n||this.#r&&s>=0&&s<=this.#r.width&&i>=0&&i<=this.#r.height,a=0,o=0,h=0,l=0;e==="scroll"?(a=t.deltaX,o=t.deltaY,h=t.deltaZ,l=t.deltaMode):e==="zoom"?(a=0,o=t.deltaY,h=0):(e==="move"||e==="drag"||e==="dragstart")&&this.#t.prevX!==null&&this.#t.prevY!==null&&(a=s-this.#t.prevX,o=i-this.#t.prevY);let S=0;if(this.#t.isDragging&&this.#t.dragStartX!==null&&this.#t.dragStartY!==null){let u=s-this.#t.dragStartX,x=i-this.#t.dragStartY;S=Math.sqrt(u*u+x*x)}let w={x:s,y:i,clientX:t.clientX,clientY:t.clientY,prevX:this.#t.prevX,prevY:this.#t.prevY,type:e,timestamp:Date.now(),isOverCanvas:n,isWithinBounds:r,deltaX:a,deltaY:o,deltaZ:h,deltaMode:l,button:t.button??this.#t.button,buttons:t.buttons??0,isPressed:this.#t.isPressed,isDragging:this.#t.isDragging,dragStartX:this.#t.dragStartX,dragStartY:this.#t.dragStartY,dragDistance:S,shiftKey:t.shiftKey||!1,ctrlKey:t.ctrlKey||!1,altKey:t.altKey||!1,metaKey:t.metaKey||!1,isExternalDragOver:this.#t.isExternalDragOver,externalDragData:this.#t.externalDragData};return e==="drop"&&t.dataTransfer&&(w.dataTransfer={items:Array.from(t.dataTransfer.items).map(u=>({kind:u.kind,type:u.type})),types:Array.from(t.dataTransfer.types)}),this.#t.prevX=s,this.#t.prevY=i,w}destroy(){this.#f&&(cancelAnimationFrame(this.#f),this.#f=null),this.#b(),this.#e=null,this.#c=null,this.#r=null,this.#w.clear(),this.#g.clear(),this.#y=!1,this.#t.isPressed=!1,this.#t.button=null,this.#t.dragStartX=null,this.#t.dragStartY=null,this.#t.isDragging=!1,this.#t.prevX=null,this.#t.prevY=null,this.#t.lastClickTime=null,this.#t.lastClickX=null,this.#t.lastClickY=null,this.#t.lastClickIsOverCanvas=null,this.#t.isExternalDragOver=!1,this.#t.externalDragData=null}};import{defineSurface as k}from"@jucie.io/reactive";var v=k(c=>{let t=c.signal(null),e=c.signal(null),s=c.signal(null),i=c.action((o,h)=>{t(h)}),n=c.action((o,h)=>{e(h)}),r=c.action((o,h)=>{s(h)}),a=c.action(()=>{t(null),e(null),s(null)});return{event:t,hoveredArea:e,activeArea:s,handleEvent:i,setHoveredArea:n,setActiveArea:r,reset:a}});import{ServiceProvider as T}from"@jucie.io/engine";import{createComputed as P,destroyComputed as y,addEffect as O}from"@jucie.io/reactive";import{createDefinition as b,definitionType as p}from"@jucie.io/engine";var d={BRUSH:"BRUSH",LAYER:"LAYER",SUBSCRIPTION:"SUBSCRIPTION",SUBSCRIPTIONS:"SUBSCRIPTIONS"},D="GLOBAL_LAYER",A=b(d.BRUSH,[Object]),R=b(d.LAYER,[Object]),L=b(d.SUBSCRIPTION,[Function]),Y=b(d.SUBSCRIPTIONS,[Object]),C=class extends T{#e=new Map;#c=new Map;#r=null;#n=new Map;#w=new Map;#g=!1;#d=null;#f=!1;#y=!1;#i={targetFPS:60,fixedTimeStep:1e3/60,timeScale:1,debug:{enabled:!1,showFPS:!0,showBounds:!0,showLayerTiming:!0}};#t={lastFrameTime:0,deltaTime:0,elapsedTime:0,frameCount:0};#x={fps:0,frameTime:0,layerTimes:new Map,brushTimes:new Map,skippedFrames:0};#D=new g;#a=v();#m=null;#b=null;#u=null;#p=new Map;#R=!1;static manifest={name:"Painter",namespace:"painter",version:"1.0.0",defaults:{targetFPS:60,fixedTimeStep:1e3/60,timeScale:1,debug:{enabled:!1,showFPS:!0,showBounds:!0,showLayerTiming:!0}}};getters(){return{pointer:()=>this.#a}}initialize(){this.#C(R(D,()=>({context:f["2D"]})))}actions(){return this.config&&Object.assign(this.#i,this.config),{addLayer:t=>this.#C(t),addLayers:(...t)=>{for(let e of t)this.#C(e)},use:(...t)=>this.use(t),updateCanvas:t=>this.updateCanvas(t),setCanvas:t=>this.setCanvas(t),setOffscreenCanvas:t=>this.setOffscreenCanvas(t),setAssets:t=>this.setAssets(t),removeLayer:t=>this.#k(t),start:()=>this.start(),stop:()=>this.stop(),forceRender:()=>this.#A(),setTargetFPS:t=>this.setTargetFPS(t),setTimeScale:t=>this.setTimeScale(t),setFixedTimeStep:t=>this.setFixedTimeStep(t),setDebug:t=>this.setDebug(t),getMetrics:()=>this.getMetrics(),handleResize:(t,e)=>this.handleResize(t,e),subscribe:(t,e)=>this.subscribe(t,e),handlePointerEvent:t=>this.handlePointerEvent(t),subscribeToPointer:t=>this.#a.$subscribe(t),bindPointer:t=>this.#a.$bind(t),_testEmitPointerEvent:t=>this._testEmitPointerEvent(t),_testClearHitRegistry:()=>this.#D.clear()}}use(t){for(let e of t){let s=p(e);switch(s){case d.BRUSH:this.#E(D,e);break;case d.LAYER:this.#C(e);break;case d.SUBSCRIPTION:this.#P(e);break;case d.SUBSCRIPTIONS:this.#O(e);break;default:throw new Error(`Invalid factory type: ${s}`)}}return this}setCanvas(t){let e=t,s=t.transferControlToOffscreen();s.width=e.width,s.height=e.height,this.#r=s,Object.values(f).forEach(i=>{try{let n=s.getContext(i);n&&this.#n.set(i,n)}catch{console.warn(`Context type ${i} not supported`)}}),this.#m||(this.#m=new m),this.#m.setCanvas(e),this.#u&&this.#u.disconnect(),this.#u=new ResizeObserver(i=>{let n=i[0];n&&n.target===e&&(s.width=e.width,s.height=e.height,this.handleResize(e.width,e.height))}),this.#u.observe(e),this.#b&&this.#b(),this.#b=this.#m.subscribe(i=>{this.handlePointerEvent(i)})}setOffscreenCanvas(t){this.#r=t,Object.values(f).forEach(e=>{try{let s=t.getContext(e);s&&this.#n.set(e,s)}catch{console.warn(`Context type ${e} not supported`)}})}updateCanvas(t){let e=t(this.#r);e&&(this.#r=e)}setAssets(t){this.#w=t}start(){this.#g||(this.#g=!0,this.#T())}stop(){this.#g&&(this.#g=!1,this.#d&&(cancelAnimationFrame(this.#d),this.#d=null),this.#y=!1)}#C(t){if(p(t)!=="LAYER")throw new Error("Invalid layer definition");let e=t._name,s=t(this.inject,this.#D),i={...s,name:e,context:this.#n.get(s.context||"2d")};if(s.data&&(i.dataReactor=this.#v(s.data,()=>this.#a)),s.when&&(i.whenReactor=this.#v(s.when,()=>i?.dataReactor?.computed()||void 0)),s.children&&s.children.length>0)for(let n of s.children)p(n)==="BRUSH"&&this.#E(e,n),p(n)==="LAYER"&&this.#C(n);if(this.#e.set(e,i),i.lifecycle?.onMount)try{i.lifecycle.onMount(i.context)}catch(n){console.error(`Error in layer "${e}" onMount:`,n)}return i}#E(t,e){let s=e._name,i=e(this.inject,this.#D),n={name:s,...i};if(i.data&&(n.dataReactor=this.#v(i.data,()=>this.#a)),i.when&&(n.whenReactor=this.#v(i.when,()=>n?.dataReactor?.computed()||void 0)),n.lifecycle?.onMount)try{n.lifecycle.onMount(this.#n.get(n.context||this.#e.get(t)?.context))}catch(r){console.error(`Error in brush "${n.name}" onMount:`,r)}return this.#c.has(t)||this.#c.set(t,[]),this.#c.get(t).push(n),n}#P(t){let e=t._name,s=t(this.inject);this.subscribe(e,s)}#O(t){let e=t._name,s=t(this.inject);for(let[i,n]of Object.entries(s)){let r=e?`${e}:${i}`:i;this.subscribe(r,n)}}#k(t){let e=this.#e.get(t);if(!e)return;if(e.lifecycle?.onUnmount)try{e.lifecycle.onUnmount(e.context)}catch(i){console.error(`Error in layer "${t}" onUnmount:`,i)}let s=this.#c.get(t)||[];this.#c.delete(t);for(let i of s){if(i.lifecycle?.onUnmount)try{i.lifecycle.onUnmount(this.#n.get(i.context||e.context))}catch(n){console.error(`Error in brush "${i.name}" onUnmount:`,n)}i.whenReactor&&y(i.whenReactor),i.dataReactor&&(i.dataReactor?.unsubscribe(),i.dataReactor?.computed&&y(i.dataReactor.computed))}e.whenReactor&&(e.whenReactor?.unsubscribe(),e.whenReactor?.computed&&y(e.whenReactor.computed)),this.#e.delete(t)}#T(){this.#y||this.#f||(this.#y=!0,this.#d=requestAnimationFrame(()=>{this.#y=!1,this.#d=null,this.#A()}))}async#A(){if(this.#r){this.#f=!0;try{this.#D.clear();let t=this.#i.debug?.enabled?performance.now():0;this.#n.forEach(e=>{e.clearRect(0,0,this.#r.width,this.#r.height)});for(let e of this.#e.values()){let s=this.#i.debug?.enabled?performance.now():0;if(e.whenReactor&&!e.whenReactor.computed())continue;let i=e.context;if(!i)continue;if(e.lifecycle?.beforeRender)try{e.lifecycle.beforeRender(i,this.#t)}catch(r){console.error(`Error in layer "${e.name}" beforeRender:`,r),e.lifecycle?.onError&&e.lifecycle.onError(r)}i.save(),e.settings&&Object.entries(e.settings).forEach(([r,a])=>{typeof i[r]=="function"?i[r](...Array.isArray(a)?a:[a]):i[r]=a});let n=this.#c.get(e.name)||[];for(let r of n){let a=this.#i.debug?.enabled?performance.now():0;if(r.whenReactor&&!r.whenReactor.computed())continue;let o=r.context?this.#n.get(r.context):i;if(o){if(r.lifecycle?.beforeRender)try{r.lifecycle.beforeRender(o,this.#t)}catch(h){console.error(`Error in brush "${r.name}" beforeRender:`,h),r.lifecycle?.onError&&r.lifecycle.onError(h);continue}o.save(),r.settings&&Object.entries(r.settings).forEach(([h,l])=>{typeof o[h]=="function"?o[h](...Array.isArray(l)?l:[l]):o[h]=l});try{let h={};if(r.assets)for(let l of r.assets)h[l]=this.#w.get(l);if(r.render(o,r.dataReactor?r.dataReactor.computed():void 0,h,this.#t),r.lifecycle?.afterRender&&r.lifecycle.afterRender(o,this.#t),this.#i.debug?.enabled){let l=performance.now()-a;this.#x.brushTimes.set(r.name,l),this.#i.debug?.showBounds&&this.#L(o,r)}}catch(h){console.error(`Error in brush "${r.name}":`,h),r.lifecycle?.onError&&r.lifecycle.onError(h)}finally{o.restore()}}}if(i.restore(),e.lifecycle?.afterRender)try{e.lifecycle.afterRender(i,this.#t)}catch(r){console.error(`Error in layer "${e.name}" afterRender:`,r),e.lifecycle?.onError&&e.lifecycle.onError(r)}if(this.#i.debug?.enabled){let r=performance.now()-s;this.#x.layerTimes.set(e.name,r),this.#i.debug?.showBounds&&this.#o(i,e)}}this.#i.debug?.enabled&&this.#Y()}finally{this.#f=!1}}}#L(t,e){t.save(),t.strokeStyle="rgba(0, 255, 0, 0.5)",t.lineWidth=1,t.strokeRect(0,0,t.canvas.width,t.canvas.height),t.restore()}#o(t,e){t.save(),t.strokeStyle="rgba(255, 0, 0, 0.5)",t.lineWidth=2,t.strokeRect(0,0,t.canvas.width,t.canvas.height),t.restore()}#Y(){let t=this.#n.get(f["2D"]);if(!t)return;t.save(),t.resetTransform(),t.font="12px monospace",t.fillStyle="white",t.strokeStyle="black",t.lineWidth=3;let e=20,s=15;if(this.#i.debug?.showFPS){let i=`FPS: ${Math.round(this.#x.fps)} (${this.#t.deltaTime.toFixed(2)}ms)`;t.strokeText(i,10,e),t.fillText(i,10,e),e+=s}if(this.#i.debug?.showLayerTiming){t.fillText("Layer Times:",10,e),e+=s;for(let[i,n]of this.#x.layerTimes){let r=` ${i}: ${n.toFixed(2)}ms`;t.strokeText(r,10,e),t.fillText(r,10,e),e+=s}t.fillText(this.state.get(["_transitions","pointer","currentState"]),10,e)}t.restore()}handleResize(t,e){for(let s of this.#e.values())if(s.lifecycle?.onResize)try{s.lifecycle.onResize(t,e,s.context)}catch(i){console.error(`Error in layer "${s.name}" onResize:`,i),s.lifecycle?.onError&&s.lifecycle.onError(i)}}#v(t,e=()=>{}){if(!t)return null;let s=P(t,{immediate:!0,context:e}),i=O(s,()=>this.#T());return{computed:s,unsubscribe:i}}destroy(){this.stop(),this.#b&&(this.#b(),this.#b=null),this.#m&&(this.#m.destroy(),this.#m=null),this.#u&&(this.#u.disconnect(),this.#u=null),this.#a&&this.#a.$destroy();for(let t of this.#e.keys())this.#k(t)}setTargetFPS(t){this.#i.targetFPS=t,this.#i.fixedTimeStep=1e3/t}setTimeScale(t){this.#i.timeScale=Math.max(0,t)}setFixedTimeStep(t){this.#i.fixedTimeStep=t}setDebug(t={}){this.#i.debug||(this.#i.debug={}),Object.assign(this.#i.debug,t)}getMetrics(){return{...this.#x,deltaTime:this.#t.deltaTime,elapsedTime:this.#t.elapsedTime,frameCount:this.#t.frameCount}}handlePointerEvent(t){this.#a.handleEvent(t),this.#I(t),this.#h(t)}#h(t){let{type:e}=t,s=this.#a,i=s.event;switch(e){case"down":this.#s("pointer:down",s);break;case"up":this.#s("pointer:up",s),i&&!i.isDragging&&this.#s("pointer:click",s);break;case"move":this.#s("pointer:move",s);break;case"dragstart":this.#s("pointer:drag:start",s);break;case"drag":this.#s("pointer:drag:move",s);break;case"dragend":this.#s("pointer:drag:end",s);break;case"scroll":this.#s("pointer:scroll",s);break;case"zoom":this.#s("pointer:zoom",s);break;case"dblclick":this.#s("pointer:dblclick",s);break;case"drop":this.#s("pointer:drop",s);break;case"dragenter":this.#s("pointer:dragenter",s);break;case"dragover":this.#s("pointer:dragover",s);break}let n=this.#R,r=i?.isOverCanvas||!1;r&&!n?this.#s("pointer:enter",s):!r&&n&&this.#s("pointer:leave",s),this.#R=r}#I(t){let{type:e,x:s,y:i}=t,n=this.#a;switch(e){case"down":{let r=this.#S(s,i);if(n.setActiveArea(r),r?.onPointerDown?.handler){let a=this.#l(r);r.onPointerDown.handler({event:t,ctx:a,emit:this.#s.bind(this)})}break}case"up":{let r=n.activeArea;if(r?.onPointerUp?.handler){let a=this.#l(r);r.onPointerUp.handler({event:t,ctx:a,emit:this.#s.bind(this)})}break}case"move":{let r=this.#S(s,i),a=n.hoveredArea;if(r?.onPointerMove?.handler&&!t.isDragging){let o=this.#l(r);r.onPointerMove.handler({event:t,ctx:o,emit:this.#s.bind(this)})}if(r?.id!==a?.id){if(a?.onPointerLeave?.handler){let o=this.#l(a);a.onPointerLeave.handler({event:t,ctx:o,emit:this.#s.bind(this)})}if(r?.onPointerEnter?.handler){let o=this.#l(r);r.onPointerEnter.handler({event:t,ctx:o,emit:this.#s.bind(this)})}n.setHoveredArea(r)}break}case"dragstart":{let r=this.#S(s,i);if(r?.onDragStart?.handler){let a=this.#l(r);r.onDragStart.handler({event:t,ctx:a,emit:this.#s.bind(this)})}break}case"drag":{let r=this.#S(s,i),a=n.hoveredArea;if(r?.id!==a?.id){if(a?.onPointerLeave?.handler){let o=this.#l(a);a.onPointerLeave.handler({event:t,ctx:o,emit:this.#s.bind(this)})}if(r?.onPointerEnter?.handler){let o=this.#l(r);r.onPointerEnter.handler({event:t,ctx:o,emit:this.#s.bind(this)})}n.setHoveredArea(r)}if(r?.onDragMove?.handler){let o=this.#l(r);r.onDragMove.handler({event:t,ctx:o,emit:this.#s.bind(this)})}break}case"dragend":{let r=this.#S(s,i);if(r?.onDragEnd?.handler){let a=this.#l(r);r.onDragEnd.handler({event:t,ctx:a,emit:this.#s.bind(this)})}break}case"dragenter":{let r=this.#S(s,i);if(r?.onDragEnter?.handler){let a=this.#l(r);r.onDragEnter.handler({event:t,ctx:a,emit:this.#s.bind(this)})}}case"dragover":{let r=this.#S(s,i),a=n.hoveredArea;if(r?.id!==a?.id){if(a?.onPointerLeave?.handler){let o=this.#l(a);a.onPointerLeave.handler({event:t,ctx:o,emit:this.#s.bind(this)})}if(r?.onPointerEnter?.handler){let o=this.#l(r);r.onPointerEnter.handler({event:t,ctx:o,emit:this.#s.bind(this)})}n.setHoveredArea(r)}if(r?.onDragOver?.handler){let o=this.#l(r);r.onDragOver.handler({event:t,ctx:o,emit:this.#s.bind(this)})}break}case"dblclick":{if(!t.isOverCanvas)break;let r=this.#S(s,i)??n.activeArea;if(r?.onPointerDblClick?.handler){let a=this.#l(r);r.onPointerDblClick.handler({event:t,ctx:a,emit:this.#s.bind(this)})}break}}}#l(t){return t?t.context?this.#n.get(t.context):this.#n.get(f["2D"]):null}subscribe(t,e){return this.#p.has(t)||this.#p.set(t,new Set),this.#p.get(t).add(e),()=>{let s=this.#p.get(t);s&&(s.delete(e),s.size===0&&this.#p.delete(t))}}#S(t,e){let s=this.#D.areas.sort((i,n)=>(n.priority||0)-(i.priority||0));for(let i of s)if(this.#X(t,e,i.bounds))return i;return null}#X(t,e,s){return t>=s.x&&t<=s.x+s.width&&e>=s.y&&e<=s.y+s.height}#s(t,e){let s=this.#p.get(t);if(s)for(let i of s)i(e)}_testEmitPointerEvent(t){this.#a.handleEvent(t),this.#I(t)}};export{m as CanvasEvents,g as HitRegistry,C as Painter,A as defineBrush,R as defineLayer,L as defineSubscription,Y as defineSubscriptions,v as usePointerSurface};
|
|
1
|
+
var f={"2D":"2d",WEBGL:"webgl",WEBGL2:"webgl2",BITMAPRENDERER:"bitmaprenderer"};var g=class{#e=new Map;register(t,e){if(!t)throw new Error("Hit area must have an id");return this.#e.set(t,{id:t,...e}),()=>this.unregister(t)}unregister(t){this.#e.delete(t)}get(t){return this.#e.get(t)}has(t){return this.#e.has(t)}get areas(){return Array.from(this.#e.values())}clear(){this.#e.clear()}};import{ServiceProvider as R}from"@jucie.io/engine";var m=class extends R{#e=null;#c=null;#r=null;#n=null;#w=new Set;#g=new Set;#d=null;#f=null;#y=!1;#i=new Set;#t={isPressed:!1,button:null,dragStartX:null,dragStartY:null,isDragging:!1,dragThreshold:5,prevX:null,prevY:null,lastClickTime:null,lastClickX:null,lastClickY:null,doubleClickThreshold:300,doubleClickDistanceThreshold:5,isExternalDragOver:!1,externalDragData:null};static manifest={name:"CanvasEvents",namespace:"canvasEvents",version:"1.0.0"};actions(){return{setCanvas:t=>this.setCanvas(t),subscribe:t=>this.subscribe(t),onResize:t=>this.onResize(t),transferControlToOffscreen:()=>this.transferControlToOffscreen(),onFileDrop:t=>this.#x(t)}}setCanvas(t){this.#e&&this.#b(),this.#e=t,this.#a(),this.#m()}subscribe(t){return this.#w.add(t),()=>this.#w.delete(t)}onResize(t){return this.#g.add(t),()=>this.#g.delete(t)}transferControlToOffscreen(){if(!this.#e)throw new Error("Canvas must be set before transferring control to offscreen");if(this.#y)throw new Error("Control has already been transferred to offscreen");return this.#c=this.#e.transferControlToOffscreen(),this.#y=!0,this.#c.width=this.#r.width,this.#c.height=this.#r.height,this.#Y({width:this.#e.width,height:this.#e.height}),this.#c}#x(t){return this.#i.add(t),()=>this.#i.delete(t)}#D(...t){for(let e of this.#i)e(...t)}#a(){this.#e&&(this.#r=this.#e.getBoundingClientRect())}#m(){this.#e&&(this.#a(),this.#n=new ResizeObserver(t=>{for(let e of t){if(e.target!==this.#e)continue;let{width:s,height:i}=e.contentRect;this.#Y({width:s,height:i})}this.#a()}),this.#n.observe(this.#e),this.#e.addEventListener("wheel",this.#u,{passive:!1}),this.#e.addEventListener("pointerdown",this.#E),this.#e.addEventListener("dragenter",this.#k),this.#e.addEventListener("dragover",this.#A),this.#e.addEventListener("dragleave",this.#P),this.#e.addEventListener("drop",this.#T),document.addEventListener("pointermove",this.#p),document.addEventListener("pointerup",this.#S),document.addEventListener("pointercancel",this.#R))}#b(){this.#n&&(this.#n.disconnect(),this.#n=null),this.#e&&(this.#e.removeEventListener("wheel",this.#u),this.#e.removeEventListener("pointerdown",this.#E),this.#e.removeEventListener("dragenter",this.#k),this.#e.removeEventListener("dragover",this.#A),this.#e.removeEventListener("dragleave",this.#P),this.#e.removeEventListener("drop",this.#T)),document.removeEventListener("pointermove",this.#p),document.removeEventListener("pointerup",this.#S),document.removeEventListener("pointercancel",this.#R)}#u=t=>{if(t.preventDefault(),t.stopPropagation(),t.ctrlKey){let e=this.#h(t,"zoom");this.#o(e)}else{let e=this.#h(t,"scroll");this.#o(e)}};#p=t=>{this.#d=t,!this.#f&&(this.#f=requestAnimationFrame(()=>{if(this.#d){let e=this.#d;this.#d=null;let s="move",i=this.#v(e);if(this.#t.isPressed&&!this.#t.isDragging){let n=i.x-this.#t.dragStartX,r=i.y-this.#t.dragStartY;Math.sqrt(n*n+r*r)>this.#t.dragThreshold&&(this.#t.isDragging=!0,s="dragstart")}else this.#t.isDragging&&(s="drag");let a=this.#h(e,s);this.#o(a)}this.#f=null}))};#E=t=>{let e=this.#v(t);this.#t.isPressed=!0,this.#t.button=t.button??null,this.#t.dragStartX=e.x,this.#t.dragStartY=e.y,this.#t.isDragging=!1;try{this.#e.setPointerCapture(t.pointerId)}catch(i){console.warn("Failed to capture pointer:",i)}let s=this.#h(t,"down");this.#o(s)};#S=t=>{if(this.#e&&this.#t.isPressed)try{this.#e.releasePointerCapture(t.pointerId)}catch{}if(this.#t.isDragging){let s=this.#h(t,"dragend");this.#o(s)}if(!this.#t.isDragging){let s=this.#v(t),i=Date.now();if(this.#t.lastClickTime!==null){let a=i-this.#t.lastClickTime,n=s.x-this.#t.lastClickX,r=s.y-this.#t.lastClickY,o=Math.sqrt(n*n+r*r);if(a<this.#t.doubleClickThreshold&&o<this.#t.doubleClickDistanceThreshold){let h=this.#h(t,"dblclick");this.#o(h),this.#t.lastClickTime=null,this.#t.lastClickX=null,this.#t.lastClickY=null}else this.#t.lastClickTime=i,this.#t.lastClickX=s.x,this.#t.lastClickY=s.y}else this.#t.lastClickTime=i,this.#t.lastClickX=s.x,this.#t.lastClickY=s.y}let e=this.#h(t,"up");this.#o(e),this.#t.isPressed=!1,this.#t.isDragging=!1,this.#t.dragStartX=null,this.#t.dragStartY=null};#R=t=>{if(this.#e&&this.#t.isPressed)try{this.#e.releasePointerCapture(t.pointerId)}catch{}if(this.#t.isDragging){let s=this.#h(t,"dragend");this.#o(s)}let e=this.#h(t,"cancel");this.#o(e),this.#t.isPressed=!1,this.#t.isDragging=!1,this.#t.dragStartX=null,this.#t.dragStartY=null};#k=t=>{t.preventDefault(),this.#t.isExternalDragOver=!0,this.#t.externalDragData=this.#O(t.dataTransfer);let e=this.#h(t,"dragenter");this.#o(e)};#A=t=>{t.preventDefault(),t.dataTransfer.dropEffect=this.#t.externalDragData?.hasFiles?"copy":"move";let e=this.#h(t,"dragover");this.#o(e)};#P=t=>{t.preventDefault();let e=this.#e.getBoundingClientRect();if(t.clientX<e.left||t.clientX>=e.right||t.clientY<e.top||t.clientY>=e.bottom){this.#t.isExternalDragOver=!1,this.#t.externalDragData=null;let i=this.#h(t,"dragleave");this.#o(i)}};#T=t=>{t.preventDefault(),this.#t.isExternalDragOver=!1,this.#t.externalDragData=this.#O(t.dataTransfer);let e=this.#h(t,"drop"),s=this.#L(t.dataTransfer);this.#D(s,e),this.#o(e),this.#t.externalDragData=null};#L(t){let e=[];if(t?.items){console.log("\u{1F4E6} Processing",t.items.length,"items");for(let s of t.items)if(s.kind==="file"){let i=s.getAsFile();i&&e.push(i)}}if(e.length===0&&t?.files){console.log("\u{1F4E6} Fallback to DataTransfer.files:",t.files.length,"files");for(let s=0;s<t.files.length;s++){let i=t.files[s];i&&e.push(i)}}return e}#O(t){return t?{types:Array.from(t.types),hasFiles:t.types.includes("Files"),fileCount:t.items?.length||0,effectAllowed:t.effectAllowed}:null}#o(t){for(let e of this.#w)e(t)}#Y(t){for(let e of this.#g)e(t)}#v(t){let e=t.target===this.#e,s,i;return e?(s=t.offsetX,i=t.offsetY):this.#r?(s=t.clientX-this.#r.left,i=t.clientY-this.#r.top):(s=t.clientX,i=t.clientY),{x:s,y:i,isOverCanvas:e}}#h(t,e){let{x:s,y:i,isOverCanvas:a}=this.#v(t),n=a||this.#r&&s>=0&&s<=this.#r.width&&i>=0&&i<=this.#r.height,r=0,o=0,h=0,l=0;e==="scroll"?(r=t.deltaX,o=t.deltaY,h=t.deltaZ,l=t.deltaMode):e==="zoom"?(r=0,o=t.deltaY,h=0):(e==="move"||e==="drag"||e==="dragstart")&&this.#t.prevX!==null&&this.#t.prevY!==null&&(r=s-this.#t.prevX,o=i-this.#t.prevY);let w=0;if(this.#t.isDragging&&this.#t.dragStartX!==null&&this.#t.dragStartY!==null){let u=s-this.#t.dragStartX,C=i-this.#t.dragStartY;w=Math.sqrt(u*u+C*C)}let x={x:s,y:i,clientX:t.clientX,clientY:t.clientY,prevX:this.#t.prevX,prevY:this.#t.prevY,type:e,timestamp:Date.now(),isOverCanvas:a,isWithinBounds:n,deltaX:r,deltaY:o,deltaZ:h,deltaMode:l,button:t.button??this.#t.button,buttons:t.buttons??0,isPressed:this.#t.isPressed,isDragging:this.#t.isDragging,dragStartX:this.#t.dragStartX,dragStartY:this.#t.dragStartY,dragDistance:w,shiftKey:t.shiftKey||!1,ctrlKey:t.ctrlKey||!1,altKey:t.altKey||!1,metaKey:t.metaKey||!1,isExternalDragOver:this.#t.isExternalDragOver,externalDragData:this.#t.externalDragData};return e==="drop"&&t.dataTransfer&&(x.dataTransfer={items:Array.from(t.dataTransfer.items).map(u=>({kind:u.kind,type:u.type})),types:Array.from(t.dataTransfer.types)}),this.#t.prevX=s,this.#t.prevY=i,x}destroy(){this.#f&&(cancelAnimationFrame(this.#f),this.#f=null),this.#b(),this.#e=null,this.#c=null,this.#r=null,this.#w.clear(),this.#g.clear(),this.#y=!1,this.#t.isPressed=!1,this.#t.button=null,this.#t.dragStartX=null,this.#t.dragStartY=null,this.#t.isDragging=!1,this.#t.prevX=null,this.#t.prevY=null,this.#t.lastClickTime=null,this.#t.lastClickX=null,this.#t.lastClickY=null,this.#t.isExternalDragOver=!1,this.#t.externalDragData=null}};import{defineSurface as P}from"@jucie.io/reactive";var v=P(c=>{let t=c.signal(null),e=c.signal(null),s=c.signal(null),i=c.action((o,h)=>{t(h)}),a=c.action((o,h)=>{e(h)}),n=c.action((o,h)=>{s(h)}),r=c.action(()=>{t(null),e(null),s(null)});return{event:t,hoveredArea:e,activeArea:s,handleEvent:i,setHoveredArea:a,setActiveArea:n,reset:r}});import{ServiceProvider as T}from"@jucie.io/engine";import{createComputed as k,destroyComputed as y,addEffect as A}from"@jucie.io/reactive";import{createDefinition as b,definitionType as p}from"@jucie.io/engine";var d={BRUSH:"BRUSH",LAYER:"LAYER",SUBSCRIPTION:"SUBSCRIPTION",SUBSCRIPTIONS:"SUBSCRIPTIONS"},D="GLOBAL_LAYER",L=b(d.BRUSH,[Object]),E=b(d.LAYER,[Object]),O=b(d.SUBSCRIPTION,[Function]),Y=b(d.SUBSCRIPTIONS,[Object]),S=class extends T{#e=new Map;#c=new Map;#r=null;#n=new Map;#w=new Map;#g=!1;#d=null;#f=!1;#y=!1;#i={targetFPS:60,fixedTimeStep:1e3/60,timeScale:1,debug:{enabled:!1,showFPS:!0,showBounds:!0,showLayerTiming:!0}};#t={lastFrameTime:0,deltaTime:0,elapsedTime:0,frameCount:0};#x={fps:0,frameTime:0,layerTimes:new Map,brushTimes:new Map,skippedFrames:0};#D=new g;#a=v();#m=null;#b=null;#u=null;#p=new Map;#E=!1;static manifest={name:"Painter",namespace:"painter",version:"1.0.0",defaults:{targetFPS:60,fixedTimeStep:1e3/60,timeScale:1,debug:{enabled:!1,showFPS:!0,showBounds:!0,showLayerTiming:!0}}};getters(){return{pointer:()=>this.#a}}initialize(){this.#S(E(D,()=>({context:f["2D"]})))}actions(){return this.config&&Object.assign(this.#i,this.config),{addLayer:t=>this.#S(t),addLayers:(...t)=>{for(let e of t)this.#S(e)},use:(...t)=>this.use(t),updateCanvas:t=>this.updateCanvas(t),setCanvas:t=>this.setCanvas(t),setOffscreenCanvas:t=>this.setOffscreenCanvas(t),setAssets:t=>this.setAssets(t),removeLayer:t=>this.#P(t),start:()=>this.start(),stop:()=>this.stop(),forceRender:()=>this.#L(),setTargetFPS:t=>this.setTargetFPS(t),setTimeScale:t=>this.setTimeScale(t),setFixedTimeStep:t=>this.setFixedTimeStep(t),setDebug:t=>this.setDebug(t),getMetrics:()=>this.getMetrics(),handleResize:(t,e)=>this.handleResize(t,e),subscribe:(t,e)=>this.subscribe(t,e),handlePointerEvent:t=>this.handlePointerEvent(t),subscribeToPointer:t=>this.#a.$subscribe(t),bindPointer:t=>this.#a.$bind(t),_testEmitPointerEvent:t=>this._testEmitPointerEvent(t)}}use(t){for(let e of t){let s=p(e);switch(s){case d.BRUSH:this.#R(D,e);break;case d.LAYER:this.#S(e);break;case d.SUBSCRIPTION:this.#k(e);break;case d.SUBSCRIPTIONS:this.#A(e);break;default:throw new Error(`Invalid factory type: ${s}`)}}return this}setCanvas(t){let e=t,s=t.transferControlToOffscreen();s.width=e.width,s.height=e.height,this.#r=s,Object.values(f).forEach(i=>{try{let a=s.getContext(i);a&&this.#n.set(i,a)}catch{console.warn(`Context type ${i} not supported`)}}),this.#m||(this.#m=new m),this.#m.setCanvas(e),this.#u&&this.#u.disconnect(),this.#u=new ResizeObserver(i=>{let a=i[0];a&&a.target===e&&(s.width=e.width,s.height=e.height,this.handleResize(e.width,e.height))}),this.#u.observe(e),this.#b&&this.#b(),this.#b=this.#m.subscribe(i=>{this.handlePointerEvent(i)})}setOffscreenCanvas(t){this.#r=t,Object.values(f).forEach(e=>{try{let s=t.getContext(e);s&&this.#n.set(e,s)}catch{console.warn(`Context type ${e} not supported`)}})}updateCanvas(t){let e=t(this.#r);e&&(this.#r=e)}setAssets(t){this.#w=t}start(){this.#g||(this.#g=!0,this.#T())}stop(){this.#g&&(this.#g=!1,this.#d&&(cancelAnimationFrame(this.#d),this.#d=null),this.#y=!1)}#S(t){if(p(t)!=="LAYER")throw new Error("Invalid layer definition");let e=t._name,s=t(this.inject,this.#D),i={...s,name:e,context:this.#n.get(s.context||"2d")};if(s.data&&(i.dataReactor=this.#v(s.data,()=>this.#a)),s.when&&(i.whenReactor=this.#v(s.when,()=>i?.dataReactor?.computed()||void 0)),s.children&&s.children.length>0)for(let a of s.children)p(a)==="BRUSH"&&this.#R(e,a),p(a)==="LAYER"&&this.#S(a);if(this.#e.set(e,i),i.lifecycle?.onMount)try{i.lifecycle.onMount(i.context)}catch(a){console.error(`Error in layer "${e}" onMount:`,a)}return i}#R(t,e){let s=e._name,i=e(this.inject,this.#D),a={name:s,...i};if(i.data&&(a.dataReactor=this.#v(i.data,()=>this.#a)),i.when&&(a.whenReactor=this.#v(i.when,()=>a?.dataReactor?.computed()||void 0)),a.lifecycle?.onMount)try{a.lifecycle.onMount(this.#n.get(a.context||this.#e.get(t)?.context))}catch(n){console.error(`Error in brush "${a.name}" onMount:`,n)}return this.#c.has(t)||this.#c.set(t,[]),this.#c.get(t).push(a),a}#k(t){let e=t._name,s=t(this.inject);this.subscribe(e,s)}#A(t){let e=t._name,s=t(this.inject);for(let[i,a]of Object.entries(s)){let n=e?`${e}:${i}`:i;this.subscribe(n,a)}}#P(t){let e=this.#e.get(t);if(!e)return;if(e.lifecycle?.onUnmount)try{e.lifecycle.onUnmount(e.context)}catch(i){console.error(`Error in layer "${t}" onUnmount:`,i)}let s=this.#c.get(t)||[];this.#c.delete(t);for(let i of s){if(i.lifecycle?.onUnmount)try{i.lifecycle.onUnmount(this.#n.get(i.context||e.context))}catch(a){console.error(`Error in brush "${i.name}" onUnmount:`,a)}i.whenReactor&&y(i.whenReactor),i.dataReactor&&(i.dataReactor?.unsubscribe(),i.dataReactor?.computed&&y(i.dataReactor.computed))}e.whenReactor&&(e.whenReactor?.unsubscribe(),e.whenReactor?.computed&&y(e.whenReactor.computed)),this.#e.delete(t)}#T(){this.#y||this.#f||(this.#y=!0,this.#d=requestAnimationFrame(()=>{this.#y=!1,this.#d=null,this.#L()}))}async#L(){if(this.#r){this.#f=!0;try{this.#D.clear();let t=this.#i.debug?.enabled?performance.now():0;this.#n.forEach(e=>{e.clearRect(0,0,this.#r.width,this.#r.height)});for(let e of this.#e.values()){let s=this.#i.debug?.enabled?performance.now():0;if(e.whenReactor&&!e.whenReactor.computed())continue;let i=e.context;if(!i)continue;if(e.lifecycle?.beforeRender)try{e.lifecycle.beforeRender(i,this.#t)}catch(n){console.error(`Error in layer "${e.name}" beforeRender:`,n),e.lifecycle?.onError&&e.lifecycle.onError(n)}i.save(),e.settings&&Object.entries(e.settings).forEach(([n,r])=>{typeof i[n]=="function"?i[n](...Array.isArray(r)?r:[r]):i[n]=r});let a=this.#c.get(e.name)||[];for(let n of a){let r=this.#i.debug?.enabled?performance.now():0;if(n.whenReactor&&!n.whenReactor.computed())continue;let o=n.context?this.#n.get(n.context):i;if(o){if(n.lifecycle?.beforeRender)try{n.lifecycle.beforeRender(o,this.#t)}catch(h){console.error(`Error in brush "${n.name}" beforeRender:`,h),n.lifecycle?.onError&&n.lifecycle.onError(h);continue}o.save(),n.settings&&Object.entries(n.settings).forEach(([h,l])=>{typeof o[h]=="function"?o[h](...Array.isArray(l)?l:[l]):o[h]=l});try{let h={};if(n.assets)for(let l of n.assets)h[l]=this.#w.get(l);if(n.render(o,n.dataReactor?n.dataReactor.computed():void 0,h,this.#t),n.lifecycle?.afterRender&&n.lifecycle.afterRender(o,this.#t),this.#i.debug?.enabled){let l=performance.now()-r;this.#x.brushTimes.set(n.name,l),this.#i.debug?.showBounds&&this.#O(o,n)}}catch(h){console.error(`Error in brush "${n.name}":`,h),n.lifecycle?.onError&&n.lifecycle.onError(h)}finally{o.restore()}}}if(i.restore(),e.lifecycle?.afterRender)try{e.lifecycle.afterRender(i,this.#t)}catch(n){console.error(`Error in layer "${e.name}" afterRender:`,n),e.lifecycle?.onError&&e.lifecycle.onError(n)}if(this.#i.debug?.enabled){let n=performance.now()-s;this.#x.layerTimes.set(e.name,n),this.#i.debug?.showBounds&&this.#o(i,e)}}this.#i.debug?.enabled&&this.#Y()}finally{this.#f=!1}}}#O(t,e){t.save(),t.strokeStyle="rgba(0, 255, 0, 0.5)",t.lineWidth=1,t.strokeRect(0,0,t.canvas.width,t.canvas.height),t.restore()}#o(t,e){t.save(),t.strokeStyle="rgba(255, 0, 0, 0.5)",t.lineWidth=2,t.strokeRect(0,0,t.canvas.width,t.canvas.height),t.restore()}#Y(){let t=this.#n.get(f["2D"]);if(!t)return;t.save(),t.resetTransform(),t.font="12px monospace",t.fillStyle="white",t.strokeStyle="black",t.lineWidth=3;let e=20,s=15;if(this.#i.debug?.showFPS){let i=`FPS: ${Math.round(this.#x.fps)} (${this.#t.deltaTime.toFixed(2)}ms)`;t.strokeText(i,10,e),t.fillText(i,10,e),e+=s}if(this.#i.debug?.showLayerTiming){t.fillText("Layer Times:",10,e),e+=s;for(let[i,a]of this.#x.layerTimes){let n=` ${i}: ${a.toFixed(2)}ms`;t.strokeText(n,10,e),t.fillText(n,10,e),e+=s}t.fillText(this.state.get(["_transitions","pointer","currentState"]),10,e)}t.restore()}handleResize(t,e){for(let s of this.#e.values())if(s.lifecycle?.onResize)try{s.lifecycle.onResize(t,e,s.context)}catch(i){console.error(`Error in layer "${s.name}" onResize:`,i),s.lifecycle?.onError&&s.lifecycle.onError(i)}}#v(t,e=()=>{}){if(!t)return null;let s=k(t,{immediate:!0,context:e}),i=A(s,()=>this.#T());return{computed:s,unsubscribe:i}}destroy(){this.stop(),this.#b&&(this.#b(),this.#b=null),this.#m&&(this.#m.destroy(),this.#m=null),this.#u&&(this.#u.disconnect(),this.#u=null),this.#a&&this.#a.$destroy();for(let t of this.#e.keys())this.#P(t)}setTargetFPS(t){this.#i.targetFPS=t,this.#i.fixedTimeStep=1e3/t}setTimeScale(t){this.#i.timeScale=Math.max(0,t)}setFixedTimeStep(t){this.#i.fixedTimeStep=t}setDebug(t={}){this.#i.debug||(this.#i.debug={}),Object.assign(this.#i.debug,t)}getMetrics(){return{...this.#x,deltaTime:this.#t.deltaTime,elapsedTime:this.#t.elapsedTime,frameCount:this.#t.frameCount}}handlePointerEvent(t){this.#a.handleEvent(t),this.#B(t),this.#h(t)}#h(t){let{type:e}=t,s=this.#a,i=s.event;switch(e){case"down":this.#s("pointer:down",s);break;case"up":this.#s("pointer:up",s),i&&!i.isDragging&&this.#s("pointer:click",s);break;case"move":this.#s("pointer:move",s);break;case"dragstart":this.#s("pointer:drag:start",s);break;case"drag":this.#s("pointer:drag:move",s);break;case"dragend":this.#s("pointer:drag:end",s);break;case"scroll":this.#s("pointer:scroll",s);break;case"zoom":this.#s("pointer:zoom",s);break;case"dblclick":this.#s("pointer:dblclick",s);break;case"drop":this.#s("pointer:drop",s);break;case"dragenter":this.#s("pointer:dragenter",s);break;case"dragover":this.#s("pointer:dragover",s);break}let a=this.#E,n=i?.isOverCanvas||!1;n&&!a?this.#s("pointer:enter",s):!n&&a&&this.#s("pointer:leave",s),this.#E=n}#B(t){let{type:e,x:s,y:i}=t,a=this.#a;switch(e){case"down":{let r=this.#C(s,i);if(a.setActiveArea(r),r?.onPointerDown?.handler){let o=this.#l(r);r.onPointerDown.handler({event:t,ctx:o,emit:this.#s.bind(this)})}break}case"up":{let r=a.activeArea;if(r?.onPointerUp?.handler){let o=this.#l(r);r.onPointerUp.handler({event:t,ctx:o,emit:this.#s.bind(this)})}break}case"move":{let r=this.#C(s,i),o=a.hoveredArea;if(r?.onPointerMove?.handler&&!t.isDragging){let h=this.#l(r);r.onPointerMove.handler({event:t,ctx:h,emit:this.#s.bind(this)})}if(r?.id!==o?.id){if(o?.onPointerLeave?.handler){let h=this.#l(o);o.onPointerLeave.handler({event:t,ctx:h,emit:this.#s.bind(this)})}if(r?.onPointerEnter?.handler){let h=this.#l(r);r.onPointerEnter.handler({event:t,ctx:h,emit:this.#s.bind(this)})}a.setHoveredArea(r)}break}case"dragstart":{let r=this.#C(s,i);if(r?.onDragStart?.handler){let o=this.#l(r);r.onDragStart.handler({event:t,ctx:o,emit:this.#s.bind(this)})}break}case"drag":{let r=this.#C(s,i),o=a.hoveredArea;if(r?.id!==o?.id){if(o?.onPointerLeave?.handler){let h=this.#l(o);o.onPointerLeave.handler({event:t,ctx:h,emit:this.#s.bind(this)})}if(r?.onPointerEnter?.handler){let h=this.#l(r);r.onPointerEnter.handler({event:t,ctx:h,emit:this.#s.bind(this)})}a.setHoveredArea(r)}if(r?.onDragMove?.handler){let h=this.#l(r);r.onDragMove.handler({event:t,ctx:h,emit:this.#s.bind(this)})}break}case"dragend":{let r=this.#C(s,i);if(r?.onDragEnd?.handler){let o=this.#l(r);r.onDragEnd.handler({event:t,ctx:o,emit:this.#s.bind(this)})}break}case"dragenter":{let r=this.#C(s,i);if(r?.onDragEnter?.handler){let o=this.#l(r);r.onDragEnter.handler({event:t,ctx:o,emit:this.#s.bind(this)})}}case"dragover":{let r=this.#C(s,i),o=a.hoveredArea;if(r?.id!==o?.id){if(o?.onPointerLeave?.handler){let h=this.#l(o);o.onPointerLeave.handler({event:t,ctx:h,emit:this.#s.bind(this)})}if(r?.onPointerEnter?.handler){let h=this.#l(r);r.onPointerEnter.handler({event:t,ctx:h,emit:this.#s.bind(this)})}a.setHoveredArea(r)}if(r?.onDragOver?.handler){let h=this.#l(r);r.onDragOver.handler({event:t,ctx:h,emit:this.#s.bind(this)})}break}case"dblclick":let n=a.activeArea;if(n?.onPointerDblClick?.handler){let r=this.#l(n);n.onPointerDblClick.handler({event:t,ctx:r,emit:this.#s.bind(this)})}break}}#l(t){return t?t.context?this.#n.get(t.context):this.#n.get(f["2D"]):null}subscribe(t,e){return this.#p.has(t)||this.#p.set(t,new Set),this.#p.get(t).add(e),()=>{let s=this.#p.get(t);s&&(s.delete(e),s.size===0&&this.#p.delete(t))}}#C(t,e){let s=this.#D.areas.sort((i,a)=>(a.priority||0)-(i.priority||0));for(let i of s)if(this.#M(t,e,i.bounds))return i;return null}#M(t,e,s){return t>=s.x&&t<=s.x+s.width&&e>=s.y&&e<=s.y+s.height}#s(t,e){let s=this.#p.get(t);if(s)for(let i of s)i(e)}_testEmitPointerEvent(t){this.#a.handleEvent(t),this.#B(t)}};export{m as CanvasEvents,g as HitRegistry,S as Painter,L as defineBrush,E as defineLayer,O as defineSubscription,Y as defineSubscriptions,v as usePointerSurface};
|
|
2
2
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/ContextTypes.js", "../src/HitRegistry.js", "../src/CanvasEvents.js", "../src/usePointerSurface.js", "../src/Painter.js"],
|
|
4
|
-
"sourcesContent": ["export const ContextTypes = {\n '2D': '2d',\n 'WEBGL': 'webgl',\n 'WEBGL2': 'webgl2',\n 'BITMAPRENDERER': 'bitmaprenderer'\n};", "export class HitRegistry {\n #areas = new Map();\n\n register(id, area) {\n if (!id) {\n throw new Error('Hit area must have an id');\n }\n this.#areas.set(id, { id, ...area });\n return () => this.unregister(id);\n }\n\n unregister(id) {\n this.#areas.delete(id);\n }\n\n get(id) {\n return this.#areas.get(id);\n }\n\n has(id) {\n return this.#areas.has(id);\n }\n\n get areas() {\n return Array.from(this.#areas.values());\n }\n\n clear() {\n this.#areas.clear();\n }\n}", "import { ServiceProvider } from '@jucie.io/engine';\n\nexport class CanvasEvents extends ServiceProvider {\n #canvas = null;\n #offscreenCanvas = null;\n #cachedRect = null;\n #resizeObserver = null;\n #subscribers = new Set();\n #resizeSubscribers = new Set();\n #pendingMove = null;\n #rafId = null;\n #hasTransferredControl = false;\n #dropSubscribers = new Set();\n // Internal state for semantic event interpretation\n #state = {\n isPressed: false,\n button: null,\n dragStartX: null,\n dragStartY: null,\n isDragging: false,\n dragThreshold: 5,\n prevX: null,\n prevY: null,\n // Double click detection\n lastClickTime: null,\n lastClickX: null,\n lastClickY: null,\n lastClickIsOverCanvas: null,\n doubleClickThreshold: 300, // ms\n doubleClickDistanceThreshold: 5, // pixels\n // External drag-and-drop state (for file/data drops)\n isExternalDragOver: false,\n externalDragData: null\n };\n\n static manifest = {\n name: 'CanvasEvents',\n namespace: 'canvasEvents',\n version: '1.0.0'\n };\n\n actions() {\n return {\n setCanvas: (canvas) => this.setCanvas(canvas),\n subscribe: (listener) => this.subscribe(listener),\n onResize: (listener) => this.onResize(listener),\n transferControlToOffscreen: () => this.transferControlToOffscreen(),\n onFileDrop: (listener) => this.#addDropSubscriber(listener)\n };\n }\n\n setCanvas(canvas) {\n if (this.#canvas) {\n this.#removeListeners();\n }\n \n this.#canvas = canvas;\n this.#updateCachedRect();\n this.#initializeListeners();\n }\n\n subscribe(subscriber) {\n this.#subscribers.add(subscriber);\n return () => this.#subscribers.delete(subscriber);\n }\n\n onResize(subscriber) {\n this.#resizeSubscribers.add(subscriber);\n return () => this.#resizeSubscribers.delete(subscriber);\n }\n\n transferControlToOffscreen() {\n if (!this.#canvas) {\n throw new Error('Canvas must be set before transferring control to offscreen');\n }\n\n if (this.#hasTransferredControl) {\n throw new Error('Control has already been transferred to offscreen');\n }\n\n // Transfer control\n this.#offscreenCanvas = this.#canvas.transferControlToOffscreen();\n this.#hasTransferredControl = true;\n\n\n\n // Set initial dimensions on offscreen canvas\n this.#offscreenCanvas.width = this.#cachedRect.width;\n this.#offscreenCanvas.height = this.#cachedRect.height;\n\n // Emit initial resize event with actual canvas dimensions\n this.#emitResize({\n width: this.#canvas.width,\n height: this.#canvas.height\n });\n\n return this.#offscreenCanvas;\n }\n\n #addDropSubscriber(listener) {\n this.#dropSubscribers.add(listener);\n return () => this.#dropSubscribers.delete(listener);\n }\n\n #callDropSubscribers(...args) {\n for (const subscriber of this.#dropSubscribers) {\n subscriber(...args);\n }\n }\n\n #updateCachedRect() {\n if (this.#canvas) {\n this.#cachedRect = this.#canvas.getBoundingClientRect();\n }\n }\n\n #initializeListeners() {\n if (!this.#canvas) return;\n\n this.#updateCachedRect();\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target !== this.#canvas) {\n continue;\n }\n const { width, height } = entry.contentRect;\n this.#emitResize({\n width: width,\n height: height\n });\n }\n this.#updateCachedRect();\n });\n this.#resizeObserver.observe(this.#canvas);\n\n // Canvas-specific events\n this.#canvas.addEventListener('wheel', this.#handleScroll, { passive: false });\n this.#canvas.addEventListener('pointerdown', this.#handleDown);\n \n // HTML5 Drag-and-Drop events (for external file/data drops)\n this.#canvas.addEventListener('dragenter', this.#handleDragEnter);\n this.#canvas.addEventListener('dragover', this.#handleDragOver);\n this.#canvas.addEventListener('dragleave', this.#handleDragLeave);\n this.#canvas.addEventListener('drop', this.#handleDrop);\n \n // Document-level events (for when pointer is captured)\n document.addEventListener('pointermove', this.#handleMove);\n document.addEventListener('pointerup', this.#handleUp);\n document.addEventListener('pointercancel', this.#handleCancel);\n }\n\n #removeListeners() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n\n if (this.#canvas) {\n this.#canvas.removeEventListener('wheel', this.#handleScroll);\n this.#canvas.removeEventListener('pointerdown', this.#handleDown);\n this.#canvas.removeEventListener('dragenter', this.#handleDragEnter);\n this.#canvas.removeEventListener('dragover', this.#handleDragOver);\n this.#canvas.removeEventListener('dragleave', this.#handleDragLeave);\n this.#canvas.removeEventListener('drop', this.#handleDrop);\n }\n\n document.removeEventListener('pointermove', this.#handleMove);\n document.removeEventListener('pointerup', this.#handleUp);\n document.removeEventListener('pointercancel', this.#handleCancel);\n }\n\n #handleScroll = (event) => {\n event.preventDefault();\n event.stopPropagation();\n \n if (event.ctrlKey) {\n const normalized = this.#normalizeEvent(event, 'zoom');\n this.#emit(normalized);\n } else {\n const normalized = this.#normalizeEvent(event, 'scroll');\n this.#emit(normalized);\n }\n }\n\n #handleMove = (event) => {\n // Store latest raw event and throttle with RAF\n this.#pendingMove = event;\n if (this.#rafId) return;\n \n this.#rafId = requestAnimationFrame(() => {\n if (this.#pendingMove) {\n const rawEvent = this.#pendingMove;\n this.#pendingMove = null;\n \n // Determine event type based on state\n let type = 'move';\n const position = this.#getPosition(rawEvent);\n \n // Check for drag start\n if (this.#state.isPressed && !this.#state.isDragging) {\n const dx = position.x - this.#state.dragStartX;\n const dy = position.y - this.#state.dragStartY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n if (distance > this.#state.dragThreshold) {\n this.#state.isDragging = true;\n type = 'dragstart';\n }\n } else if (this.#state.isDragging) {\n type = 'drag';\n }\n \n const normalized = this.#normalizeEvent(rawEvent, type);\n this.#emit(normalized);\n }\n this.#rafId = null;\n });\n }\n\n #handleDown = (event) => {\n const position = this.#getPosition(event);\n \n // Update state\n this.#state.isPressed = true;\n this.#state.button = event.button ?? null;\n this.#state.dragStartX = position.x;\n this.#state.dragStartY = position.y;\n this.#state.isDragging = false;\n \n // Capture the pointer to ensure we receive all subsequent events\n // even if the pointer moves outside the canvas\n try {\n this.#canvas.setPointerCapture(event.pointerId);\n } catch (e) {\n // Pointer capture might fail in some scenarios (e.g., already captured)\n // Continue anyway as document-level listeners will still work\n console.warn('Failed to capture pointer:', e);\n }\n \n const normalized = this.#normalizeEvent(event, 'down');\n this.#emit(normalized); // Immediate\n }\n\n #handleUp = (event) => {\n // Release pointer capture\n if (this.#canvas && this.#state.isPressed) {\n try {\n this.#canvas.releasePointerCapture(event.pointerId);\n } catch (e) {\n // Capture might have already been released, ignore\n }\n }\n \n // Emit dragend if we were dragging\n if (this.#state.isDragging) {\n const dragend = this.#normalizeEvent(event, 'dragend');\n this.#emit(dragend);\n }\n \n // Detect double click if this was a clean click (not a drag)\n if (!this.#state.isDragging) {\n const position = this.#getPosition(event);\n const now = Date.now();\n \n if (this.#state.lastClickTime !== null) {\n const timeDiff = now - this.#state.lastClickTime;\n const dx = position.x - this.#state.lastClickX;\n const dy = position.y - this.#state.lastClickY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n // Check if this qualifies as a double click (both ups must be on canvas)\n if (\n timeDiff < this.#state.doubleClickThreshold &&\n distance < this.#state.doubleClickDistanceThreshold &&\n position.isOverCanvas &&\n this.#state.lastClickIsOverCanvas\n ) {\n // Emit double click event\n const dblclickEvent = this.#normalizeEvent(event, 'dblclick');\n this.#emit(dblclickEvent);\n \n // Reset double click tracking to prevent triple-click\n this.#state.lastClickTime = null;\n this.#state.lastClickX = null;\n this.#state.lastClickY = null;\n this.#state.lastClickIsOverCanvas = null;\n } else if (position.isOverCanvas) {\n // Update for potential next canvas click\n this.#state.lastClickTime = now;\n this.#state.lastClickX = position.x;\n this.#state.lastClickY = position.y;\n this.#state.lastClickIsOverCanvas = true;\n } else {\n // Off-canvas click \u2014 reset so canvas + sidebar clicks cannot pair\n this.#state.lastClickTime = null;\n this.#state.lastClickX = null;\n this.#state.lastClickY = null;\n this.#state.lastClickIsOverCanvas = null;\n }\n } else if (position.isOverCanvas) {\n // First canvas click, start tracking\n this.#state.lastClickTime = now;\n this.#state.lastClickX = position.x;\n this.#state.lastClickY = position.y;\n this.#state.lastClickIsOverCanvas = true;\n }\n }\n \n // Always emit up event\n const normalized = this.#normalizeEvent(event, 'up');\n this.#emit(normalized); // Immediate\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.isDragging = false;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n }\n\n #handleCancel = (event) => {\n // Release pointer capture\n if (this.#canvas && this.#state.isPressed) {\n try {\n this.#canvas.releasePointerCapture(event.pointerId);\n } catch (e) {\n // Capture might have already been released, ignore\n }\n }\n \n // Emit dragend if we were dragging (interaction was interrupted)\n if (this.#state.isDragging) {\n const dragend = this.#normalizeEvent(event, 'dragend');\n this.#emit(dragend);\n }\n \n // Emit cancel event (distinct from up - signals interrupted interaction)\n const normalized = this.#normalizeEvent(event, 'cancel');\n this.#emit(normalized);\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.isDragging = false;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n }\n\n #handleDragEnter = (event) => {\n event.preventDefault();\n \n this.#state.isExternalDragOver = true;\n this.#state.externalDragData = this.#extractDragData(event.dataTransfer);\n \n const normalized = this.#normalizeEvent(event, 'dragenter');\n this.#emit(normalized);\n }\n\n #handleDragOver = (event) => {\n event.preventDefault();\n \n // Set the drop effect (copy for files, move for internal drags)\n event.dataTransfer.dropEffect = this.#state.externalDragData?.hasFiles ? 'copy' : 'move';\n \n const normalized = this.#normalizeEvent(event, 'dragover');\n this.#emit(normalized);\n }\n\n #handleDragLeave = (event) => {\n event.preventDefault();\n \n // Only emit dragleave if we're actually leaving the canvas\n // (not just moving between child elements)\n const rect = this.#canvas.getBoundingClientRect();\n const isOutside = (\n event.clientX < rect.left ||\n event.clientX >= rect.right ||\n event.clientY < rect.top ||\n event.clientY >= rect.bottom\n );\n \n if (isOutside) {\n this.#state.isExternalDragOver = false;\n this.#state.externalDragData = null;\n \n const normalized = this.#normalizeEvent(event, 'dragleave');\n this.#emit(normalized);\n }\n }\n\n #handleDrop = (event) => {\n event.preventDefault();\n \n this.#state.isExternalDragOver = false;\n this.#state.externalDragData = this.#extractDragData(event.dataTransfer);\n \n const normalized = this.#normalizeEvent(event, 'drop');\n const files = this.#extractFiles(event.dataTransfer);\n this.#callDropSubscribers(files, normalized);\n this.#emit(normalized);\n \n // Reset state after drop\n this.#state.externalDragData = null;\n }\n\n #extractFiles(dataTransfer) {\n const files = [];\n if (dataTransfer?.items) {\n console.log('\uD83D\uDCE6 Processing', dataTransfer.items.length, 'items');\n for (const item of dataTransfer.items) {\n if (item.kind === \"file\") {\n const file = item.getAsFile();\n if (file) {\n files.push(file);\n }\n }\n }\n }\n \n // Fallback to DataTransfer.files if items is empty or not available\n if (files.length === 0 && dataTransfer?.files) {\n console.log('\uD83D\uDCE6 Fallback to DataTransfer.files:',dataTransfer.files.length, 'files');\n for (let i = 0; i < dataTransfer.files.length; i++) {\n const file = dataTransfer.files[i];\n if (file) {\n files.push(file);\n }\n }\n }\n return files;\n }\n\n #extractDragData(dataTransfer) {\n if (!dataTransfer) return null;\n \n return {\n types: Array.from(dataTransfer.types),\n hasFiles: dataTransfer.types.includes('Files'),\n fileCount: dataTransfer.items?.length || 0,\n // Note: Can't access files/data until drop event due to security\n effectAllowed: dataTransfer.effectAllowed\n };\n }\n\n #emit(event) {\n for (const subscriber of this.#subscribers) {\n subscriber(event);\n }\n }\n\n #emitResize(resizeData) {\n for (const subscriber of this.#resizeSubscribers) {\n subscriber(resizeData);\n }\n }\n\n #getPosition(event) {\n const isOverCanvas = event.target === this.#canvas;\n \n let x, y;\n if (isOverCanvas) {\n x = event.offsetX;\n y = event.offsetY;\n } else if (this.#cachedRect) {\n x = event.clientX - this.#cachedRect.left;\n y = event.clientY - this.#cachedRect.top;\n } else {\n x = event.clientX;\n y = event.clientY;\n }\n \n return { x, y, isOverCanvas };\n }\n\n #normalizeEvent(event, type) {\n const { x, y, isOverCanvas } = this.#getPosition(event);\n\n const isWithinBounds = isOverCanvas || (\n this.#cachedRect &&\n x >= 0 && \n x <= this.#cachedRect.width && \n y >= 0 && \n y <= this.#cachedRect.height\n );\n \n // Calculate deltas based on event type\n let deltaX = 0;\n let deltaY = 0;\n let deltaZ = 0;\n let deltaMode = 0;\n \n if (type === 'scroll') {\n // Scroll events use wheel deltas\n deltaX = event.deltaX;\n deltaY = event.deltaY;\n deltaZ = event.deltaZ;\n deltaMode = event.deltaMode;\n } else if (type === 'zoom') {\n // Zoom uses simplified delta\n deltaX = 0;\n deltaY = event.deltaY;\n deltaZ = 0;\n } else if (type === 'move' || type === 'drag' || type === 'dragstart') {\n // Position-based events calculate deltas from previous position\n if (this.#state.prevX !== null && this.#state.prevY !== null) {\n deltaX = x - this.#state.prevX;\n deltaY = y - this.#state.prevY;\n }\n }\n \n // Calculate drag distance if dragging\n let dragDistance = 0;\n if (this.#state.isDragging && this.#state.dragStartX !== null && this.#state.dragStartY !== null) {\n const dx = x - this.#state.dragStartX;\n const dy = y - this.#state.dragStartY;\n dragDistance = Math.sqrt(dx * dx + dy * dy);\n }\n\n const normalized = {\n // Position\n x,\n y,\n clientX: event.clientX,\n clientY: event.clientY,\n prevX: this.#state.prevX,\n prevY: this.#state.prevY,\n \n // Event metadata\n type,\n timestamp: Date.now(),\n isOverCanvas,\n isWithinBounds,\n \n // Deltas (appropriate to event type)\n deltaX,\n deltaY,\n deltaZ,\n deltaMode,\n \n // Button state\n button: event.button ?? this.#state.button,\n buttons: event.buttons ?? 0,\n isPressed: this.#state.isPressed,\n \n // Drag state\n isDragging: this.#state.isDragging,\n dragStartX: this.#state.dragStartX,\n dragStartY: this.#state.dragStartY,\n dragDistance,\n \n // Modifiers\n shiftKey: event.shiftKey || false,\n ctrlKey: event.ctrlKey || false,\n altKey: event.altKey || false,\n metaKey: event.metaKey || false,\n \n // External drag-and-drop state (for file/data drops)\n isExternalDragOver: this.#state.isExternalDragOver,\n externalDragData: this.#state.externalDragData\n };\n \n // Add DataTransfer for drop events (only available on drop, not dragover)\n if (type === 'drop' && event.dataTransfer) {\n normalized.dataTransfer = {\n items: Array.from(event.dataTransfer.items).map(item => ({\n kind: item.kind,\n type: item.type\n })),\n types: Array.from(event.dataTransfer.types)\n };\n }\n \n // Update previous position for next delta calculation\n this.#state.prevX = x;\n this.#state.prevY = y;\n\n return normalized;\n }\n\n destroy() {\n if (this.#rafId) {\n cancelAnimationFrame(this.#rafId);\n this.#rafId = null;\n }\n this.#removeListeners();\n this.#canvas = null;\n this.#offscreenCanvas = null;\n this.#cachedRect = null;\n this.#subscribers.clear();\n this.#resizeSubscribers.clear();\n this.#hasTransferredControl = false;\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.button = null;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n this.#state.isDragging = false;\n this.#state.prevX = null;\n this.#state.prevY = null;\n this.#state.lastClickTime = null;\n this.#state.lastClickX = null;\n this.#state.lastClickY = null;\n this.#state.lastClickIsOverCanvas = null;\n this.#state.isExternalDragOver = false;\n this.#state.externalDragData = null;\n }\n}\n", "import { defineSurface } from '@jucie.io/reactive';\n\nexport const usePointerSurface = defineSurface((setup) => {\n // Current normalized event from CanvasEvents\n const event = setup.signal(null);\n \n // Hit registry integration (still managed here)\n const hoveredArea = setup.signal(null);\n const activeArea = setup.signal(null);\n \n // Main handler - just stores the event\n const handleEvent = setup.action((_, normalizedEvent) => {\n event(normalizedEvent);\n });\n \n const setHoveredArea = setup.action((_, area) => {\n hoveredArea(area);\n });\n \n const setActiveArea = setup.action((_, area) => {\n activeArea(area);\n });\n \n const reset = setup.action(() => {\n event(null);\n hoveredArea(null);\n activeArea(null);\n });\n \n return {\n // Signals\n event,\n hoveredArea,\n activeArea,\n\n // Actions\n handleEvent,\n setHoveredArea,\n setActiveArea,\n reset\n };\n});\n", "import { ServiceProvider } from '@jucie.io/engine';\nimport { ContextTypes } from './ContextTypes.js';\nimport { createComputed, destroyComputed, addEffect } from '@jucie.io/reactive';\nimport { createDefinition, definitionType } from '@jucie.io/engine';\nimport { HitRegistry } from './HitRegistry.js';\nimport { CanvasEvents } from './CanvasEvents.js';\nimport { usePointerSurface } from './usePointerSurface.js';\n\nconst DEFINITIONS_TYPES = {\n BRUSH: 'BRUSH',\n LAYER: 'LAYER',\n SUBSCRIPTION: 'SUBSCRIPTION',\n SUBSCRIPTIONS: 'SUBSCRIPTIONS'\n};\n\nconst GLOBAL_LAYER_NAME = 'GLOBAL_LAYER';\n\nexport const defineBrush = createDefinition(DEFINITIONS_TYPES.BRUSH, [Object]);\nexport const defineLayer = createDefinition(DEFINITIONS_TYPES.LAYER, [Object]);\nexport const defineSubscription = createDefinition(DEFINITIONS_TYPES.SUBSCRIPTION, [Function]);\nexport const defineSubscriptions = createDefinition(DEFINITIONS_TYPES.SUBSCRIPTIONS, [Object]);\n\nexport class Painter extends ServiceProvider {\n #layers = new Map();\n #brushes = new Map();\n #canvas = null; // Always OffscreenCanvas\n #contexts = new Map();\n #assets = new Map();\n #isRunning = false;\n #frameId = null;\n #isRendering = false;\n #renderScheduled = false;\n\n // Mutable runtime config (separate from frozen config)\n #runtimeConfig = {\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n };\n\n // Timing state\n #timing = {\n lastFrameTime: 0,\n deltaTime: 0,\n elapsedTime: 0,\n frameCount: 0\n };\n\n // Debug metrics\n #metrics = {\n fps: 0,\n frameTime: 0,\n layerTimes: new Map(),\n brushTimes: new Map(),\n skippedFrames: 0\n };\n\n // Hit detection state\n #hitRegistry = new HitRegistry();\n #pointerSurface = usePointerSurface();\n #canvasEvents = null; // Only created in main thread mode\n #pointerUnsubscribe = null;\n #resizeObserver = null; // For main thread canvas resize watching\n #subscribers = new Map(); // Map<event, Set<callback>>\n \n // Track state for event emission\n #wasOverCanvas = false;\n\n static manifest = {\n name: 'Painter',\n namespace: 'painter',\n version: '1.0.0',\n defaults: {\n // Timing configuration\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n // Debug configuration\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n }\n };\n\n getters () {\n return {\n pointer: () => this.#pointerSurface,\n };\n }\n \n initialize () {\n this.#addLayer(defineLayer(GLOBAL_LAYER_NAME, () => ({\n context: ContextTypes['2D']\n })));\n }\n\n actions() {\n // Initialize runtime config from frozen config\n if (this.config) {\n Object.assign(this.#runtimeConfig, this.config);\n }\n \n return {\n addLayer: (layerDef) => this.#addLayer(layerDef),\n addLayers: (...layers) => {\n for (const layer of layers) {\n this.#addLayer(layer);\n }\n },\n use: (...factories) => this.use(factories),\n updateCanvas: (fn) => this.updateCanvas(fn),\n setCanvas: (canvas) => this.setCanvas(canvas),\n setOffscreenCanvas: (offscreenCanvas) => this.setOffscreenCanvas(offscreenCanvas),\n setAssets: (assets) => this.setAssets(assets),\n removeLayer: (name) => this.#removeLayer(name),\n start: () => this.start(),\n stop: () => this.stop(),\n forceRender: () => this.#render(),\n setTargetFPS: (fps) => this.setTargetFPS(fps),\n setTimeScale: (scale) => this.setTimeScale(scale),\n setFixedTimeStep: (step) => this.setFixedTimeStep(step),\n setDebug: (options) => this.setDebug(options),\n getMetrics: () => this.getMetrics(),\n handleResize: (width, height) => this.handleResize(width, height),\n subscribe: (event, callback) => this.subscribe(event, callback),\n // Pointer API - receives normalized events from main thread\n handlePointerEvent: (normalizedEvent) => this.handlePointerEvent(normalizedEvent),\n subscribeToPointer: (callback) => this.#pointerSurface.$subscribe(callback),\n bindPointer: (path) => this.#pointerSurface.$bind(path),\n // Test helpers - only for testing\n _testEmitPointerEvent: (normalizedEvent) => this._testEmitPointerEvent(normalizedEvent),\n _testClearHitRegistry: () => this.#hitRegistry.clear()\n };\n }\n\n use(factories) {\n for (const factory of factories) {\n const type = definitionType(factory);\n switch (type) {\n case DEFINITIONS_TYPES.BRUSH:\n this.#addBrush(GLOBAL_LAYER_NAME, factory);\n break;\n case DEFINITIONS_TYPES.LAYER:\n this.#addLayer(factory);\n break;\n case DEFINITIONS_TYPES.SUBSCRIPTION:\n this.#addSubscription(factory);\n break;\n\n case DEFINITIONS_TYPES.SUBSCRIPTIONS:\n this.#addSubscriptions(factory);\n break;\n\n default:\n throw new Error(`Invalid factory type: ${type}`);\n }\n }\n return this;\n }\n\n // Main thread mode: Pass regular canvas, we create OffscreenCanvas + CanvasEvents\n setCanvas(canvas) {\n // Store reference to DOM canvas for resize observation\n const domCanvas = canvas;\n \n // Transfer control to offscreen\n const offscreenCanvas = canvas.transferControlToOffscreen();\n \n // Set initial dimensions\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Create and set up canvas events (main thread only)\n if (!this.#canvasEvents) {\n this.#canvasEvents = new CanvasEvents();\n }\n \n this.#canvasEvents.setCanvas(domCanvas);\n\n // Watch for canvas resizes and sync to offscreen canvas\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n \n this.#resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry && entry.target === domCanvas) {\n // Sync dimensions to offscreen canvas\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n // Notify layers of resize\n this.handleResize(domCanvas.width, domCanvas.height);\n }\n });\n \n this.#resizeObserver.observe(domCanvas);\n\n // Connect canvas events to surface\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n }\n\n this.#pointerUnsubscribe = this.#canvasEvents.subscribe((normalizedEvent) => {\n this.handlePointerEvent(normalizedEvent);\n });\n }\n\n // Worker thread mode: Accept pre-created OffscreenCanvas, expect external events\n setOffscreenCanvas(offscreenCanvas) {\n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Don't create CanvasEvents - events will come from external source\n // via handlePointerEvent()\n }\n\n updateCanvas(fn) {\n const result = fn(this.#canvas);\n if (result) {\n this.#canvas = result;\n }\n }\n\n setAssets(assets) {\n this.#assets = assets;\n }\n\n start() {\n if (!this.#isRunning) {\n this.#isRunning = true;\n this.#scheduleRender();\n }\n }\n\n stop() {\n if (this.#isRunning) {\n this.#isRunning = false;\n if (this.#frameId) {\n cancelAnimationFrame(this.#frameId);\n this.#frameId = null;\n }\n this.#renderScheduled = false;\n }\n }\n\n #addLayer(layerDef) {\n if (definitionType(layerDef) !== 'LAYER') {\n throw new Error('Invalid layer definition');\n }\n\n const name = layerDef._name;\n const config = layerDef(this.inject, this.#hitRegistry);\n\n const layer = {...config, name, context: this.#contexts.get(config.context || '2d') };\n \n // Set up layer computed if it has data paths\n if (config.data) {\n layer.dataReactor = this.#createReactor(config.data, () => this.#pointerSurface);\n }\n\n // Set up when reactor if layer has condition\n if (config.when) {\n layer.whenReactor = this.#createReactor(config.when, () => (layer?.dataReactor?.computed() || undefined));\n }\n\n // Set up brush reactors and structure\n if (config.children && config.children.length > 0) {\n for (const child of config.children) {\n if (definitionType(child) === 'BRUSH') {\n this.#addBrush(name, child);\n }\n if (definitionType(child) === 'LAYER') {\n this.#addLayer(child);\n }\n }\n }\n\n this.#layers.set(name, layer);\n\n // Call layer mount hook\n if (layer.lifecycle?.onMount) {\n try {\n layer.lifecycle.onMount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onMount:`, error);\n }\n }\n\n return layer;\n }\n\n #addBrush(layerName, brushFactory) {\n const name = brushFactory._name;\n const brushConfig = brushFactory(this.inject, this.#hitRegistry);\n const brush = {\n name,\n ...brushConfig\n };\n\n if (brushConfig.data) {\n brush.dataReactor = this.#createReactor(brushConfig.data, () => this.#pointerSurface);\n }\n\n if (brushConfig.when) {\n brush.whenReactor = this.#createReactor(brushConfig.when, () => (brush?.dataReactor?.computed() || undefined));\n }\n\n // Call brush mount hook\n if (brush.lifecycle?.onMount) {\n try {\n brush.lifecycle.onMount(this.#contexts.get(brush.context || this.#layers.get(layerName)?.context));\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onMount:`, error);\n }\n }\n\n if (!this.#brushes.has(layerName)) {\n this.#brushes.set(layerName, []);\n }\n\n this.#brushes.get(layerName).push(brush);\n\n return brush;\n }\n\n #addSubscription(subscriptionFactory) {\n const name = subscriptionFactory._name;\n const subscriptionConfig = subscriptionFactory(this.inject);\n this.subscribe(name, subscriptionConfig);\n }\n\n #addSubscriptions(subscriptionsFactory) {\n const prefix = subscriptionsFactory._name;\n const subscriptions = subscriptionsFactory(this.inject);\n for (const [event, handler] of Object.entries(subscriptions)) {\n const finalEvent = prefix ? `${prefix}:${event}` : event;\n this.subscribe(finalEvent, handler);\n }\n }\n\n #removeLayer(name) {\n const layer = this.#layers.get(name);\n if (!layer) return;\n\n // Call layer unmount hook\n if (layer.lifecycle?.onUnmount) {\n try {\n layer.lifecycle.onUnmount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onUnmount:`, error);\n }\n }\n\n const brushes = this.#brushes.get(name) || [];\n this.#brushes.delete(name);\n\n // Call brush unmount hooks and clean up reactors\n\n for (const brush of brushes) {\n if (brush.lifecycle?.onUnmount) {\n try {\n brush.lifecycle.onUnmount(\n this.#contexts.get(brush.context || layer.context)\n );\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onUnmount:`, error);\n }\n }\n // Clean up brush when reactor\n if (brush.whenReactor) {\n destroyComputed(brush.whenReactor);\n }\n // Clean up brush computed and subscription\n if (brush.dataReactor) {\n brush.dataReactor?.unsubscribe();\n if (brush.dataReactor?.computed) {\n destroyComputed(brush.dataReactor.computed);\n }\n }\n }\n\n // Clean up layer when reactor\n if (layer.whenReactor) {\n layer.whenReactor?.unsubscribe();\n if (layer.whenReactor?.computed) {\n destroyComputed(layer.whenReactor.computed);\n }\n }\n\n this.#layers.delete(name);\n }\n\n #scheduleRender() {\n if (this.#renderScheduled || this.#isRendering) return;\n \n this.#renderScheduled = true;\n \n this.#frameId = requestAnimationFrame(() => {\n this.#renderScheduled = false;\n this.#frameId = null;\n this.#render();\n });\n }\n\n async #render() {\n if (!this.#canvas) return;\n this.#isRendering = true;\n \n try {\n // Clear hit registry at start of render\n this.#hitRegistry.clear();\n \n const renderStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Clear all contexts\n this.#contexts.forEach(ctx => {\n ctx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);\n });\n\n // Render layers in order\n for (const layer of this.#layers.values()) {\n const layerStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Check layer condition\n if (layer.whenReactor && !layer.whenReactor.computed()) continue;\n\n const ctx = layer.context;\n\n if (!ctx) continue;\n\n // Layer beforeRender hook\n if (layer.lifecycle?.beforeRender) {\n try {\n layer.lifecycle.beforeRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" beforeRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n // Apply layer settings\n ctx.save();\n if (layer.settings) {\n Object.entries(layer.settings).forEach(([key, value]) => {\n if (typeof ctx[key] === 'function') {\n ctx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n ctx[key] = value;\n }\n });\n }\n\n const brushes = this.#brushes.get(layer.name) || [];\n\n // Render brushes\n for (const brush of brushes) {\n const brushStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n if (brush.whenReactor && !brush.whenReactor.computed()) continue;\n\n\n const brushCtx = brush.context ? \n this.#contexts.get(brush.context) : \n ctx;\n\n if (!brushCtx) continue;\n\n // Brush beforeRender hook\n if (brush.lifecycle?.beforeRender) {\n try {\n brush.lifecycle.beforeRender(brushCtx, this.#timing);\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" beforeRender:`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n continue;\n }\n }\n\n brushCtx.save();\n \n if (brush.settings) {\n Object.entries(brush.settings).forEach(([key, value]) => {\n if (typeof brushCtx[key] === 'function') {\n brushCtx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n brushCtx[key] = value;\n }\n });\n }\n \n try {\n const requiredAssets = {};\n if (brush.assets) {\n for (const key of brush.assets) {\n requiredAssets[key] = this.#assets.get(key);\n }\n }\n brush.render(brushCtx, (brush.dataReactor ? brush.dataReactor.computed() : undefined), requiredAssets, this.#timing);\n\n // Brush afterRender hook\n if (brush.lifecycle?.afterRender) {\n brush.lifecycle.afterRender(brushCtx, this.#timing);\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const brushTime = performance.now() - brushStart;\n this.#metrics.brushTimes.set(brush.name, brushTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderBrushBounds(brushCtx, brush);\n }\n }\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\":`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n } finally {\n brushCtx.restore();\n }\n }\n\n ctx.restore();\n\n // Layer afterRender hook\n if (layer.lifecycle?.afterRender) {\n try {\n layer.lifecycle.afterRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" afterRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const layerTime = performance.now() - layerStart;\n this.#metrics.layerTimes.set(layer.name, layerTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderLayerBounds(ctx, layer);\n }\n }\n }\n\n // Render debug overlay if enabled\n if (this.#runtimeConfig.debug?.enabled) {\n this.#renderDebugOverlay();\n }\n \n } finally {\n this.#isRendering = false;\n }\n }\n\n #renderBrushBounds(ctx, brush) {\n ctx.save();\n ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';\n ctx.lineWidth = 1;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderLayerBounds(ctx, layer) {\n ctx.save();\n ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';\n ctx.lineWidth = 2;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderDebugOverlay() {\n const ctx = this.#contexts.get(ContextTypes['2D']);\n if (!ctx) return;\n\n ctx.save();\n ctx.resetTransform();\n ctx.font = '12px monospace';\n ctx.fillStyle = 'white';\n ctx.strokeStyle = 'black';\n ctx.lineWidth = 3;\n\n let y = 20;\n const lineHeight = 15;\n\n if (this.#runtimeConfig.debug?.showFPS) {\n const text = `FPS: ${Math.round(this.#metrics.fps)} (${this.#timing.deltaTime.toFixed(2)}ms)`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n if (this.#runtimeConfig.debug?.showLayerTiming) {\n ctx.fillText('Layer Times:', 10, y);\n y += lineHeight;\n\n for (const [name, time] of this.#metrics.layerTimes) {\n const text = ` ${name}: ${time.toFixed(2)}ms`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n ctx.fillText(this.state.get(['_transitions', 'pointer', 'currentState']), 10, y);\n }\n\n ctx.restore();\n }\n\n handleResize(width, height) {\n // Call onResize hooks for all layers\n for (const layer of this.#layers.values()) {\n if (layer.lifecycle?.onResize) {\n try {\n layer.lifecycle.onResize(width, height, layer.context);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" onResize:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n }\n }\n\n #createReactor(fn, context = () => undefined) {\n if (!fn) return null;\n \n const computed = createComputed(fn, {\n immediate: true,\n context\n });\n \n const unsubscribe = addEffect(computed, () => this.#scheduleRender());\n \n return {computed, unsubscribe};\n }\n\n destroy() {\n this.stop();\n\n // Clean up pointer system\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n this.#pointerUnsubscribe = null;\n }\n if (this.#canvasEvents) {\n this.#canvasEvents.destroy();\n this.#canvasEvents = null;\n }\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n if (this.#pointerSurface) {\n this.#pointerSurface.$destroy();\n }\n\n // Clean up all layers and reactors\n for (const name of this.#layers.keys()) {\n this.#removeLayer(name);\n }\n }\n\n setTargetFPS(fps) {\n this.#runtimeConfig.targetFPS = fps;\n this.#runtimeConfig.fixedTimeStep = 1000 / fps;\n }\n\n setTimeScale(scale) {\n this.#runtimeConfig.timeScale = Math.max(0, scale);\n }\n\n setFixedTimeStep(step) {\n this.#runtimeConfig.fixedTimeStep = step;\n }\n\n setDebug(options = {}) {\n if (!this.#runtimeConfig.debug) {\n this.#runtimeConfig.debug = {};\n }\n Object.assign(this.#runtimeConfig.debug, options);\n }\n\n getMetrics() {\n return {\n ...this.#metrics,\n deltaTime: this.#timing.deltaTime,\n elapsedTime: this.#timing.elapsedTime,\n frameCount: this.#timing.frameCount\n };\n }\n\n // Public method to receive pointer events from main thread\n handlePointerEvent(normalizedEvent) {\n // Feed normalized events into surface\n this.#pointerSurface.handleEvent(normalizedEvent);\n\n // Handle hit testing and interactions\n this.#handlePointerInteraction(normalizedEvent);\n \n // Emit generic pointer events for external subscribers\n this.#emitPointerEvents(normalizedEvent);\n }\n\n #emitPointerEvents(normalizedEvent) {\n const { type } = normalizedEvent;\n const pointer = this.#pointerSurface;\n const event = pointer.event;\n \n // Emit basic pointer events\n switch (type) {\n case 'down':\n this.#emit('pointer:down', pointer);\n break;\n \n case 'up':\n this.#emit('pointer:up', pointer);\n \n // Emit click if it wasn't a drag\n if (event && !event.isDragging) {\n this.#emit('pointer:click', pointer);\n }\n break;\n \n case 'move':\n this.#emit('pointer:move', pointer);\n break;\n \n case 'dragstart':\n this.#emit('pointer:drag:start', pointer);\n break;\n \n case 'drag':\n this.#emit('pointer:drag:move', pointer);\n break;\n \n case 'dragend':\n this.#emit('pointer:drag:end', pointer);\n break;\n \n case 'scroll':\n this.#emit('pointer:scroll', pointer);\n break;\n \n case 'zoom':\n this.#emit('pointer:zoom', pointer);\n break;\n \n case 'dblclick':\n this.#emit('pointer:dblclick', pointer);\n break;\n\n case 'drop':\n this.#emit('pointer:drop', pointer);\n break;\n\n case 'dragenter':\n this.#emit('pointer:dragenter', pointer);\n break;\n\n case 'dragover':\n this.#emit('pointer:dragover', pointer);\n break;\n }\n \n // Check for canvas enter/leave\n const wasOverCanvas = this.#wasOverCanvas;\n const isOverCanvas = event?.isOverCanvas || false;\n \n if (isOverCanvas && !wasOverCanvas) {\n this.#emit('pointer:enter', pointer);\n } else if (!isOverCanvas && wasOverCanvas) {\n this.#emit('pointer:leave', pointer);\n }\n \n this.#wasOverCanvas = isOverCanvas;\n }\n\n #handlePointerInteraction(normalizedEvent) {\n const { type, x, y } = normalizedEvent;\n const pointer = this.#pointerSurface;\n\n switch (type) {\n case 'down': {\n const hitArea = this.#hitTest(x, y);\n pointer.setActiveArea(hitArea);\n\n if (hitArea?.onPointerDown?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDown.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'up': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onPointerUp?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerUp.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'move': {\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle pointer move on hovered area (only when NOT dragging)\n if (hitArea?.onPointerMove?.handler && !normalizedEvent.isDragging) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerMove.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n // Handle hover changes\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n break;\n }\n\n case 'dragstart': {\n const hitArea = this.#hitTest(x, y);\n if (hitArea?.onDragStart?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragStart.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'drag': {\n // Perform hit test to detect drop targets while dragging\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle hover changes (for drop target detection)\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n\n // Internal drag movement dispatches to onDragMove\n if (hitArea?.onDragMove?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragMove.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dragend': {\n const hitArea = this.#hitTest(x, y);\n if (hitArea?.onDragEnd?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragEnd.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dragenter': {\n const hitArea = this.#hitTest(x, y);\n if (hitArea?.onDragEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n }\n \n case 'dragover': {\n // Perform hit test to detect drop targets while dragging\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle hover changes (for drop target detection)\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n\n // External/native drag-over dispatches to onDragOver\n if (hitArea?.onDragOver?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragOver.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dblclick': {\n if (!normalizedEvent.isOverCanvas) break;\n\n // Prefer fresh hit-test; fall back to activeArea when registry was cleared mid-gesture\n const hitArea = this.#hitTest(x, y) ?? pointer.activeArea;\n\n if (hitArea?.onPointerDblClick?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDblClick.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n }\n }\n\n #getContextForArea(area) {\n if (!area) return null;\n return area.context \n ? this.#contexts.get(area.context) \n : this.#contexts.get(ContextTypes['2D']);\n }\n\n subscribe(event, callback) {\n if (!this.#subscribers.has(event)) {\n this.#subscribers.set(event, new Set());\n }\n this.#subscribers.get(event).add(callback);\n \n return () => {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.#subscribers.delete(event);\n }\n }\n };\n }\n\n #hitTest(x, y) {\n // Sort by priority (highest first) and test\n const sorted = this.#hitRegistry.areas.sort((a, b) => \n (b.priority || 0) - (a.priority || 0)\n );\n \n for (const area of sorted) {\n if (this.#isPointInBounds(x, y, area.bounds)) {\n return area;\n }\n }\n return null;\n }\n\n #isPointInBounds(x, y, bounds) {\n return x >= bounds.x && \n x <= bounds.x + bounds.width &&\n y >= bounds.y && \n y <= bounds.y + bounds.height;\n }\n\n #emit(event, data) {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n callback(data);\n }\n }\n }\n\n // Test helper - only for testing, simulates normalized pointer events\n _testEmitPointerEvent(normalizedEvent) {\n this.#pointerSurface.handleEvent(normalizedEvent);\n this.#handlePointerInteraction(normalizedEvent);\n }\n}"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["export const ContextTypes = {\n '2D': '2d',\n 'WEBGL': 'webgl',\n 'WEBGL2': 'webgl2',\n 'BITMAPRENDERER': 'bitmaprenderer'\n};", "export class HitRegistry {\n #areas = new Map();\n\n register(id, area) {\n if (!id) {\n throw new Error('Hit area must have an id');\n }\n this.#areas.set(id, { id, ...area });\n return () => this.unregister(id);\n }\n\n unregister(id) {\n this.#areas.delete(id);\n }\n\n get(id) {\n return this.#areas.get(id);\n }\n\n has(id) {\n return this.#areas.has(id);\n }\n\n get areas() {\n return Array.from(this.#areas.values());\n }\n\n clear() {\n this.#areas.clear();\n }\n}", "import { ServiceProvider } from '@jucie.io/engine';\n\nexport class CanvasEvents extends ServiceProvider {\n #canvas = null;\n #offscreenCanvas = null;\n #cachedRect = null;\n #resizeObserver = null;\n #subscribers = new Set();\n #resizeSubscribers = new Set();\n #pendingMove = null;\n #rafId = null;\n #hasTransferredControl = false;\n #dropSubscribers = new Set();\n // Internal state for semantic event interpretation\n #state = {\n isPressed: false,\n button: null,\n dragStartX: null,\n dragStartY: null,\n isDragging: false,\n dragThreshold: 5,\n prevX: null,\n prevY: null,\n // Double click detection\n lastClickTime: null,\n lastClickX: null,\n lastClickY: null,\n doubleClickThreshold: 300, // ms\n doubleClickDistanceThreshold: 5, // pixels\n // External drag-and-drop state (for file/data drops)\n isExternalDragOver: false,\n externalDragData: null\n };\n\n static manifest = {\n name: 'CanvasEvents',\n namespace: 'canvasEvents',\n version: '1.0.0'\n };\n\n actions() {\n return {\n setCanvas: (canvas) => this.setCanvas(canvas),\n subscribe: (listener) => this.subscribe(listener),\n onResize: (listener) => this.onResize(listener),\n transferControlToOffscreen: () => this.transferControlToOffscreen(),\n onFileDrop: (listener) => this.#addDropSubscriber(listener)\n };\n }\n\n setCanvas(canvas) {\n if (this.#canvas) {\n this.#removeListeners();\n }\n \n this.#canvas = canvas;\n this.#updateCachedRect();\n this.#initializeListeners();\n }\n\n subscribe(subscriber) {\n this.#subscribers.add(subscriber);\n return () => this.#subscribers.delete(subscriber);\n }\n\n onResize(subscriber) {\n this.#resizeSubscribers.add(subscriber);\n return () => this.#resizeSubscribers.delete(subscriber);\n }\n\n transferControlToOffscreen() {\n if (!this.#canvas) {\n throw new Error('Canvas must be set before transferring control to offscreen');\n }\n\n if (this.#hasTransferredControl) {\n throw new Error('Control has already been transferred to offscreen');\n }\n\n // Transfer control\n this.#offscreenCanvas = this.#canvas.transferControlToOffscreen();\n this.#hasTransferredControl = true;\n\n\n\n // Set initial dimensions on offscreen canvas\n this.#offscreenCanvas.width = this.#cachedRect.width;\n this.#offscreenCanvas.height = this.#cachedRect.height;\n\n // Emit initial resize event with actual canvas dimensions\n this.#emitResize({\n width: this.#canvas.width,\n height: this.#canvas.height\n });\n\n return this.#offscreenCanvas;\n }\n\n #addDropSubscriber(listener) {\n this.#dropSubscribers.add(listener);\n return () => this.#dropSubscribers.delete(listener);\n }\n\n #callDropSubscribers(...args) {\n for (const subscriber of this.#dropSubscribers) {\n subscriber(...args);\n }\n }\n\n #updateCachedRect() {\n if (this.#canvas) {\n this.#cachedRect = this.#canvas.getBoundingClientRect();\n }\n }\n\n #initializeListeners() {\n if (!this.#canvas) return;\n\n this.#updateCachedRect();\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target !== this.#canvas) {\n continue;\n }\n const { width, height } = entry.contentRect;\n this.#emitResize({\n width: width,\n height: height\n });\n }\n this.#updateCachedRect();\n });\n this.#resizeObserver.observe(this.#canvas);\n\n // Canvas-specific events\n this.#canvas.addEventListener('wheel', this.#handleScroll, { passive: false });\n this.#canvas.addEventListener('pointerdown', this.#handleDown);\n \n // HTML5 Drag-and-Drop events (for external file/data drops)\n this.#canvas.addEventListener('dragenter', this.#handleDragEnter);\n this.#canvas.addEventListener('dragover', this.#handleDragOver);\n this.#canvas.addEventListener('dragleave', this.#handleDragLeave);\n this.#canvas.addEventListener('drop', this.#handleDrop);\n \n // Document-level events (for when pointer is captured)\n document.addEventListener('pointermove', this.#handleMove);\n document.addEventListener('pointerup', this.#handleUp);\n document.addEventListener('pointercancel', this.#handleCancel);\n }\n\n #removeListeners() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n\n if (this.#canvas) {\n this.#canvas.removeEventListener('wheel', this.#handleScroll);\n this.#canvas.removeEventListener('pointerdown', this.#handleDown);\n this.#canvas.removeEventListener('dragenter', this.#handleDragEnter);\n this.#canvas.removeEventListener('dragover', this.#handleDragOver);\n this.#canvas.removeEventListener('dragleave', this.#handleDragLeave);\n this.#canvas.removeEventListener('drop', this.#handleDrop);\n }\n\n document.removeEventListener('pointermove', this.#handleMove);\n document.removeEventListener('pointerup', this.#handleUp);\n document.removeEventListener('pointercancel', this.#handleCancel);\n }\n\n #handleScroll = (event) => {\n event.preventDefault();\n event.stopPropagation();\n \n if (event.ctrlKey) {\n const normalized = this.#normalizeEvent(event, 'zoom');\n this.#emit(normalized);\n } else {\n const normalized = this.#normalizeEvent(event, 'scroll');\n this.#emit(normalized);\n }\n }\n\n #handleMove = (event) => {\n // Store latest raw event and throttle with RAF\n this.#pendingMove = event;\n if (this.#rafId) return;\n \n this.#rafId = requestAnimationFrame(() => {\n if (this.#pendingMove) {\n const rawEvent = this.#pendingMove;\n this.#pendingMove = null;\n \n // Determine event type based on state\n let type = 'move';\n const position = this.#getPosition(rawEvent);\n \n // Check for drag start\n if (this.#state.isPressed && !this.#state.isDragging) {\n const dx = position.x - this.#state.dragStartX;\n const dy = position.y - this.#state.dragStartY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n if (distance > this.#state.dragThreshold) {\n this.#state.isDragging = true;\n type = 'dragstart';\n }\n } else if (this.#state.isDragging) {\n type = 'drag';\n }\n \n const normalized = this.#normalizeEvent(rawEvent, type);\n this.#emit(normalized);\n }\n this.#rafId = null;\n });\n }\n\n #handleDown = (event) => {\n const position = this.#getPosition(event);\n \n // Update state\n this.#state.isPressed = true;\n this.#state.button = event.button ?? null;\n this.#state.dragStartX = position.x;\n this.#state.dragStartY = position.y;\n this.#state.isDragging = false;\n \n // Capture the pointer to ensure we receive all subsequent events\n // even if the pointer moves outside the canvas\n try {\n this.#canvas.setPointerCapture(event.pointerId);\n } catch (e) {\n // Pointer capture might fail in some scenarios (e.g., already captured)\n // Continue anyway as document-level listeners will still work\n console.warn('Failed to capture pointer:', e);\n }\n \n const normalized = this.#normalizeEvent(event, 'down');\n this.#emit(normalized); // Immediate\n }\n\n #handleUp = (event) => {\n // Release pointer capture\n if (this.#canvas && this.#state.isPressed) {\n try {\n this.#canvas.releasePointerCapture(event.pointerId);\n } catch (e) {\n // Capture might have already been released, ignore\n }\n }\n \n // Emit dragend if we were dragging\n if (this.#state.isDragging) {\n const dragend = this.#normalizeEvent(event, 'dragend');\n this.#emit(dragend);\n }\n \n // Detect double click if this was a clean click (not a drag)\n if (!this.#state.isDragging) {\n const position = this.#getPosition(event);\n const now = Date.now();\n \n if (this.#state.lastClickTime !== null) {\n const timeDiff = now - this.#state.lastClickTime;\n const dx = position.x - this.#state.lastClickX;\n const dy = position.y - this.#state.lastClickY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n // Check if this qualifies as a double click\n if (\n timeDiff < this.#state.doubleClickThreshold &&\n distance < this.#state.doubleClickDistanceThreshold\n ) {\n // Emit double click event\n const dblclickEvent = this.#normalizeEvent(event, 'dblclick');\n this.#emit(dblclickEvent);\n \n // Reset double click tracking to prevent triple-click\n this.#state.lastClickTime = null;\n this.#state.lastClickX = null;\n this.#state.lastClickY = null;\n } else {\n // Update for potential next click\n this.#state.lastClickTime = now;\n this.#state.lastClickX = position.x;\n this.#state.lastClickY = position.y;\n }\n } else {\n // First click, start tracking\n this.#state.lastClickTime = now;\n this.#state.lastClickX = position.x;\n this.#state.lastClickY = position.y;\n }\n }\n \n // Always emit up event\n const normalized = this.#normalizeEvent(event, 'up');\n this.#emit(normalized); // Immediate\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.isDragging = false;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n }\n\n #handleCancel = (event) => {\n // Release pointer capture\n if (this.#canvas && this.#state.isPressed) {\n try {\n this.#canvas.releasePointerCapture(event.pointerId);\n } catch (e) {\n // Capture might have already been released, ignore\n }\n }\n \n // Emit dragend if we were dragging (interaction was interrupted)\n if (this.#state.isDragging) {\n const dragend = this.#normalizeEvent(event, 'dragend');\n this.#emit(dragend);\n }\n \n // Emit cancel event (distinct from up - signals interrupted interaction)\n const normalized = this.#normalizeEvent(event, 'cancel');\n this.#emit(normalized);\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.isDragging = false;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n }\n\n #handleDragEnter = (event) => {\n event.preventDefault();\n \n this.#state.isExternalDragOver = true;\n this.#state.externalDragData = this.#extractDragData(event.dataTransfer);\n \n const normalized = this.#normalizeEvent(event, 'dragenter');\n this.#emit(normalized);\n }\n\n #handleDragOver = (event) => {\n event.preventDefault();\n \n // Set the drop effect (copy for files, move for internal drags)\n event.dataTransfer.dropEffect = this.#state.externalDragData?.hasFiles ? 'copy' : 'move';\n \n const normalized = this.#normalizeEvent(event, 'dragover');\n this.#emit(normalized);\n }\n\n #handleDragLeave = (event) => {\n event.preventDefault();\n \n // Only emit dragleave if we're actually leaving the canvas\n // (not just moving between child elements)\n const rect = this.#canvas.getBoundingClientRect();\n const isOutside = (\n event.clientX < rect.left ||\n event.clientX >= rect.right ||\n event.clientY < rect.top ||\n event.clientY >= rect.bottom\n );\n \n if (isOutside) {\n this.#state.isExternalDragOver = false;\n this.#state.externalDragData = null;\n \n const normalized = this.#normalizeEvent(event, 'dragleave');\n this.#emit(normalized);\n }\n }\n\n #handleDrop = (event) => {\n event.preventDefault();\n \n this.#state.isExternalDragOver = false;\n this.#state.externalDragData = this.#extractDragData(event.dataTransfer);\n \n const normalized = this.#normalizeEvent(event, 'drop');\n const files = this.#extractFiles(event.dataTransfer);\n this.#callDropSubscribers(files, normalized);\n this.#emit(normalized);\n \n // Reset state after drop\n this.#state.externalDragData = null;\n }\n\n #extractFiles(dataTransfer) {\n const files = [];\n if (dataTransfer?.items) {\n console.log('\uD83D\uDCE6 Processing', dataTransfer.items.length, 'items');\n for (const item of dataTransfer.items) {\n if (item.kind === \"file\") {\n const file = item.getAsFile();\n if (file) {\n files.push(file);\n }\n }\n }\n }\n \n // Fallback to DataTransfer.files if items is empty or not available\n if (files.length === 0 && dataTransfer?.files) {\n console.log('\uD83D\uDCE6 Fallback to DataTransfer.files:',dataTransfer.files.length, 'files');\n for (let i = 0; i < dataTransfer.files.length; i++) {\n const file = dataTransfer.files[i];\n if (file) {\n files.push(file);\n }\n }\n }\n return files;\n }\n\n #extractDragData(dataTransfer) {\n if (!dataTransfer) return null;\n \n return {\n types: Array.from(dataTransfer.types),\n hasFiles: dataTransfer.types.includes('Files'),\n fileCount: dataTransfer.items?.length || 0,\n // Note: Can't access files/data until drop event due to security\n effectAllowed: dataTransfer.effectAllowed\n };\n }\n\n #emit(event) {\n for (const subscriber of this.#subscribers) {\n subscriber(event);\n }\n }\n\n #emitResize(resizeData) {\n for (const subscriber of this.#resizeSubscribers) {\n subscriber(resizeData);\n }\n }\n\n #getPosition(event) {\n const isOverCanvas = event.target === this.#canvas;\n \n let x, y;\n if (isOverCanvas) {\n x = event.offsetX;\n y = event.offsetY;\n } else if (this.#cachedRect) {\n x = event.clientX - this.#cachedRect.left;\n y = event.clientY - this.#cachedRect.top;\n } else {\n x = event.clientX;\n y = event.clientY;\n }\n \n return { x, y, isOverCanvas };\n }\n\n #normalizeEvent(event, type) {\n const { x, y, isOverCanvas } = this.#getPosition(event);\n\n const isWithinBounds = isOverCanvas || (\n this.#cachedRect &&\n x >= 0 && \n x <= this.#cachedRect.width && \n y >= 0 && \n y <= this.#cachedRect.height\n );\n \n // Calculate deltas based on event type\n let deltaX = 0;\n let deltaY = 0;\n let deltaZ = 0;\n let deltaMode = 0;\n \n if (type === 'scroll') {\n // Scroll events use wheel deltas\n deltaX = event.deltaX;\n deltaY = event.deltaY;\n deltaZ = event.deltaZ;\n deltaMode = event.deltaMode;\n } else if (type === 'zoom') {\n // Zoom uses simplified delta\n deltaX = 0;\n deltaY = event.deltaY;\n deltaZ = 0;\n } else if (type === 'move' || type === 'drag' || type === 'dragstart') {\n // Position-based events calculate deltas from previous position\n if (this.#state.prevX !== null && this.#state.prevY !== null) {\n deltaX = x - this.#state.prevX;\n deltaY = y - this.#state.prevY;\n }\n }\n \n // Calculate drag distance if dragging\n let dragDistance = 0;\n if (this.#state.isDragging && this.#state.dragStartX !== null && this.#state.dragStartY !== null) {\n const dx = x - this.#state.dragStartX;\n const dy = y - this.#state.dragStartY;\n dragDistance = Math.sqrt(dx * dx + dy * dy);\n }\n\n const normalized = {\n // Position\n x,\n y,\n clientX: event.clientX,\n clientY: event.clientY,\n prevX: this.#state.prevX,\n prevY: this.#state.prevY,\n \n // Event metadata\n type,\n timestamp: Date.now(),\n isOverCanvas,\n isWithinBounds,\n \n // Deltas (appropriate to event type)\n deltaX,\n deltaY,\n deltaZ,\n deltaMode,\n \n // Button state\n button: event.button ?? this.#state.button,\n buttons: event.buttons ?? 0,\n isPressed: this.#state.isPressed,\n \n // Drag state\n isDragging: this.#state.isDragging,\n dragStartX: this.#state.dragStartX,\n dragStartY: this.#state.dragStartY,\n dragDistance,\n \n // Modifiers\n shiftKey: event.shiftKey || false,\n ctrlKey: event.ctrlKey || false,\n altKey: event.altKey || false,\n metaKey: event.metaKey || false,\n \n // External drag-and-drop state (for file/data drops)\n isExternalDragOver: this.#state.isExternalDragOver,\n externalDragData: this.#state.externalDragData\n };\n \n // Add DataTransfer for drop events (only available on drop, not dragover)\n if (type === 'drop' && event.dataTransfer) {\n normalized.dataTransfer = {\n items: Array.from(event.dataTransfer.items).map(item => ({\n kind: item.kind,\n type: item.type\n })),\n types: Array.from(event.dataTransfer.types)\n };\n }\n \n // Update previous position for next delta calculation\n this.#state.prevX = x;\n this.#state.prevY = y;\n\n return normalized;\n }\n\n destroy() {\n if (this.#rafId) {\n cancelAnimationFrame(this.#rafId);\n this.#rafId = null;\n }\n this.#removeListeners();\n this.#canvas = null;\n this.#offscreenCanvas = null;\n this.#cachedRect = null;\n this.#subscribers.clear();\n this.#resizeSubscribers.clear();\n this.#hasTransferredControl = false;\n \n // Reset state\n this.#state.isPressed = false;\n this.#state.button = null;\n this.#state.dragStartX = null;\n this.#state.dragStartY = null;\n this.#state.isDragging = false;\n this.#state.prevX = null;\n this.#state.prevY = null;\n this.#state.lastClickTime = null;\n this.#state.lastClickX = null;\n this.#state.lastClickY = null;\n this.#state.isExternalDragOver = false;\n this.#state.externalDragData = null;\n }\n}\n", "import { defineSurface } from '@jucie.io/reactive';\n\nexport const usePointerSurface = defineSurface((setup) => {\n // Current normalized event from CanvasEvents\n const event = setup.signal(null);\n \n // Hit registry integration (still managed here)\n const hoveredArea = setup.signal(null);\n const activeArea = setup.signal(null);\n \n // Main handler - just stores the event\n const handleEvent = setup.action((_, normalizedEvent) => {\n event(normalizedEvent);\n });\n \n const setHoveredArea = setup.action((_, area) => {\n hoveredArea(area);\n });\n \n const setActiveArea = setup.action((_, area) => {\n activeArea(area);\n });\n \n const reset = setup.action(() => {\n event(null);\n hoveredArea(null);\n activeArea(null);\n });\n \n return {\n // Signals\n event,\n hoveredArea,\n activeArea,\n\n // Actions\n handleEvent,\n setHoveredArea,\n setActiveArea,\n reset\n };\n});\n", "import { ServiceProvider } from '@jucie.io/engine';\nimport { ContextTypes } from './ContextTypes.js';\nimport { createComputed, destroyComputed, addEffect } from '@jucie.io/reactive';\nimport { createDefinition, definitionType } from '@jucie.io/engine';\nimport { HitRegistry } from './HitRegistry.js';\nimport { CanvasEvents } from './CanvasEvents.js';\nimport { usePointerSurface } from './usePointerSurface.js';\n\nconst DEFINITIONS_TYPES = {\n BRUSH: 'BRUSH',\n LAYER: 'LAYER',\n SUBSCRIPTION: 'SUBSCRIPTION',\n SUBSCRIPTIONS: 'SUBSCRIPTIONS'\n};\n\nconst GLOBAL_LAYER_NAME = 'GLOBAL_LAYER';\n\nexport const defineBrush = createDefinition(DEFINITIONS_TYPES.BRUSH, [Object]);\nexport const defineLayer = createDefinition(DEFINITIONS_TYPES.LAYER, [Object]);\nexport const defineSubscription = createDefinition(DEFINITIONS_TYPES.SUBSCRIPTION, [Function]);\nexport const defineSubscriptions = createDefinition(DEFINITIONS_TYPES.SUBSCRIPTIONS, [Object]);\n\nexport class Painter extends ServiceProvider {\n #layers = new Map();\n #brushes = new Map();\n #canvas = null; // Always OffscreenCanvas\n #contexts = new Map();\n #assets = new Map();\n #isRunning = false;\n #frameId = null;\n #isRendering = false;\n #renderScheduled = false;\n\n // Mutable runtime config (separate from frozen config)\n #runtimeConfig = {\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n };\n\n // Timing state\n #timing = {\n lastFrameTime: 0,\n deltaTime: 0,\n elapsedTime: 0,\n frameCount: 0\n };\n\n // Debug metrics\n #metrics = {\n fps: 0,\n frameTime: 0,\n layerTimes: new Map(),\n brushTimes: new Map(),\n skippedFrames: 0\n };\n\n // Hit detection state\n #hitRegistry = new HitRegistry();\n #pointerSurface = usePointerSurface();\n #canvasEvents = null; // Only created in main thread mode\n #pointerUnsubscribe = null;\n #resizeObserver = null; // For main thread canvas resize watching\n #subscribers = new Map(); // Map<event, Set<callback>>\n \n // Track state for event emission\n #wasOverCanvas = false;\n\n static manifest = {\n name: 'Painter',\n namespace: 'painter',\n version: '1.0.0',\n defaults: {\n // Timing configuration\n targetFPS: 60,\n fixedTimeStep: 1000 / 60,\n timeScale: 1.0,\n // Debug configuration\n debug: {\n enabled: false,\n showFPS: true,\n showBounds: true,\n showLayerTiming: true\n }\n }\n };\n\n getters () {\n return {\n pointer: () => this.#pointerSurface,\n };\n }\n \n initialize () {\n this.#addLayer(defineLayer(GLOBAL_LAYER_NAME, () => ({\n context: ContextTypes['2D']\n })));\n }\n\n actions() {\n // Initialize runtime config from frozen config\n if (this.config) {\n Object.assign(this.#runtimeConfig, this.config);\n }\n \n return {\n addLayer: (layerDef) => this.#addLayer(layerDef),\n addLayers: (...layers) => {\n for (const layer of layers) {\n this.#addLayer(layer);\n }\n },\n use: (...factories) => this.use(factories),\n updateCanvas: (fn) => this.updateCanvas(fn),\n setCanvas: (canvas) => this.setCanvas(canvas),\n setOffscreenCanvas: (offscreenCanvas) => this.setOffscreenCanvas(offscreenCanvas),\n setAssets: (assets) => this.setAssets(assets),\n removeLayer: (name) => this.#removeLayer(name),\n start: () => this.start(),\n stop: () => this.stop(),\n forceRender: () => this.#render(),\n setTargetFPS: (fps) => this.setTargetFPS(fps),\n setTimeScale: (scale) => this.setTimeScale(scale),\n setFixedTimeStep: (step) => this.setFixedTimeStep(step),\n setDebug: (options) => this.setDebug(options),\n getMetrics: () => this.getMetrics(),\n handleResize: (width, height) => this.handleResize(width, height),\n subscribe: (event, callback) => this.subscribe(event, callback),\n // Pointer API - receives normalized events from main thread\n handlePointerEvent: (normalizedEvent) => this.handlePointerEvent(normalizedEvent),\n subscribeToPointer: (callback) => this.#pointerSurface.$subscribe(callback),\n bindPointer: (path) => this.#pointerSurface.$bind(path),\n // Test helper - only for testing\n _testEmitPointerEvent: (normalizedEvent) => this._testEmitPointerEvent(normalizedEvent)\n };\n }\n\n use(factories) {\n for (const factory of factories) {\n const type = definitionType(factory);\n switch (type) {\n case DEFINITIONS_TYPES.BRUSH:\n this.#addBrush(GLOBAL_LAYER_NAME, factory);\n break;\n case DEFINITIONS_TYPES.LAYER:\n this.#addLayer(factory);\n break;\n case DEFINITIONS_TYPES.SUBSCRIPTION:\n this.#addSubscription(factory);\n break;\n\n case DEFINITIONS_TYPES.SUBSCRIPTIONS:\n this.#addSubscriptions(factory);\n break;\n\n default:\n throw new Error(`Invalid factory type: ${type}`);\n }\n }\n return this;\n }\n\n // Main thread mode: Pass regular canvas, we create OffscreenCanvas + CanvasEvents\n setCanvas(canvas) {\n // Store reference to DOM canvas for resize observation\n const domCanvas = canvas;\n \n // Transfer control to offscreen\n const offscreenCanvas = canvas.transferControlToOffscreen();\n \n // Set initial dimensions\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Create and set up canvas events (main thread only)\n if (!this.#canvasEvents) {\n this.#canvasEvents = new CanvasEvents();\n }\n \n this.#canvasEvents.setCanvas(domCanvas);\n\n // Watch for canvas resizes and sync to offscreen canvas\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n \n this.#resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry && entry.target === domCanvas) {\n // Sync dimensions to offscreen canvas\n offscreenCanvas.width = domCanvas.width;\n offscreenCanvas.height = domCanvas.height;\n \n // Notify layers of resize\n this.handleResize(domCanvas.width, domCanvas.height);\n }\n });\n \n this.#resizeObserver.observe(domCanvas);\n\n // Connect canvas events to surface\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n }\n\n this.#pointerUnsubscribe = this.#canvasEvents.subscribe((normalizedEvent) => {\n this.handlePointerEvent(normalizedEvent);\n });\n }\n\n // Worker thread mode: Accept pre-created OffscreenCanvas, expect external events\n setOffscreenCanvas(offscreenCanvas) {\n this.#canvas = offscreenCanvas;\n \n // Create contexts for each type\n Object.values(ContextTypes).forEach(type => {\n try {\n const ctx = offscreenCanvas.getContext(type);\n if (ctx) this.#contexts.set(type, ctx);\n } catch (e) {\n console.warn(`Context type ${type} not supported`);\n }\n });\n\n // Don't create CanvasEvents - events will come from external source\n // via handlePointerEvent()\n }\n\n updateCanvas(fn) {\n const result = fn(this.#canvas);\n if (result) {\n this.#canvas = result;\n }\n }\n\n setAssets(assets) {\n this.#assets = assets;\n }\n\n start() {\n if (!this.#isRunning) {\n this.#isRunning = true;\n this.#scheduleRender();\n }\n }\n\n stop() {\n if (this.#isRunning) {\n this.#isRunning = false;\n if (this.#frameId) {\n cancelAnimationFrame(this.#frameId);\n this.#frameId = null;\n }\n this.#renderScheduled = false;\n }\n }\n\n #addLayer(layerDef) {\n if (definitionType(layerDef) !== 'LAYER') {\n throw new Error('Invalid layer definition');\n }\n\n const name = layerDef._name;\n const config = layerDef(this.inject, this.#hitRegistry);\n\n const layer = {...config, name, context: this.#contexts.get(config.context || '2d') };\n \n // Set up layer computed if it has data paths\n if (config.data) {\n layer.dataReactor = this.#createReactor(config.data, () => this.#pointerSurface);\n }\n\n // Set up when reactor if layer has condition\n if (config.when) {\n layer.whenReactor = this.#createReactor(config.when, () => (layer?.dataReactor?.computed() || undefined));\n }\n\n // Set up brush reactors and structure\n if (config.children && config.children.length > 0) {\n for (const child of config.children) {\n if (definitionType(child) === 'BRUSH') {\n this.#addBrush(name, child);\n }\n if (definitionType(child) === 'LAYER') {\n this.#addLayer(child);\n }\n }\n }\n\n this.#layers.set(name, layer);\n\n // Call layer mount hook\n if (layer.lifecycle?.onMount) {\n try {\n layer.lifecycle.onMount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onMount:`, error);\n }\n }\n\n return layer;\n }\n\n #addBrush(layerName, brushFactory) {\n const name = brushFactory._name;\n const brushConfig = brushFactory(this.inject, this.#hitRegistry);\n const brush = {\n name,\n ...brushConfig\n };\n\n if (brushConfig.data) {\n brush.dataReactor = this.#createReactor(brushConfig.data, () => this.#pointerSurface);\n }\n\n if (brushConfig.when) {\n brush.whenReactor = this.#createReactor(brushConfig.when, () => (brush?.dataReactor?.computed() || undefined));\n }\n\n // Call brush mount hook\n if (brush.lifecycle?.onMount) {\n try {\n brush.lifecycle.onMount(this.#contexts.get(brush.context || this.#layers.get(layerName)?.context));\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onMount:`, error);\n }\n }\n\n if (!this.#brushes.has(layerName)) {\n this.#brushes.set(layerName, []);\n }\n\n this.#brushes.get(layerName).push(brush);\n\n return brush;\n }\n\n #addSubscription(subscriptionFactory) {\n const name = subscriptionFactory._name;\n const subscriptionConfig = subscriptionFactory(this.inject);\n this.subscribe(name, subscriptionConfig);\n }\n\n #addSubscriptions(subscriptionsFactory) {\n const prefix = subscriptionsFactory._name;\n const subscriptions = subscriptionsFactory(this.inject);\n for (const [event, handler] of Object.entries(subscriptions)) {\n const finalEvent = prefix ? `${prefix}:${event}` : event;\n this.subscribe(finalEvent, handler);\n }\n }\n\n #removeLayer(name) {\n const layer = this.#layers.get(name);\n if (!layer) return;\n\n // Call layer unmount hook\n if (layer.lifecycle?.onUnmount) {\n try {\n layer.lifecycle.onUnmount(layer.context);\n } catch (error) {\n console.error(`Error in layer \"${name}\" onUnmount:`, error);\n }\n }\n\n const brushes = this.#brushes.get(name) || [];\n this.#brushes.delete(name);\n\n // Call brush unmount hooks and clean up reactors\n\n for (const brush of brushes) {\n if (brush.lifecycle?.onUnmount) {\n try {\n brush.lifecycle.onUnmount(\n this.#contexts.get(brush.context || layer.context)\n );\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" onUnmount:`, error);\n }\n }\n // Clean up brush when reactor\n if (brush.whenReactor) {\n destroyComputed(brush.whenReactor);\n }\n // Clean up brush computed and subscription\n if (brush.dataReactor) {\n brush.dataReactor?.unsubscribe();\n if (brush.dataReactor?.computed) {\n destroyComputed(brush.dataReactor.computed);\n }\n }\n }\n\n // Clean up layer when reactor\n if (layer.whenReactor) {\n layer.whenReactor?.unsubscribe();\n if (layer.whenReactor?.computed) {\n destroyComputed(layer.whenReactor.computed);\n }\n }\n\n this.#layers.delete(name);\n }\n\n #scheduleRender() {\n if (this.#renderScheduled || this.#isRendering) return;\n \n this.#renderScheduled = true;\n \n this.#frameId = requestAnimationFrame(() => {\n this.#renderScheduled = false;\n this.#frameId = null;\n this.#render();\n });\n }\n\n async #render() {\n if (!this.#canvas) return;\n this.#isRendering = true;\n \n try {\n // Clear hit registry at start of render\n this.#hitRegistry.clear();\n \n const renderStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Clear all contexts\n this.#contexts.forEach(ctx => {\n ctx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);\n });\n\n // Render layers in order\n for (const layer of this.#layers.values()) {\n const layerStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n // Check layer condition\n if (layer.whenReactor && !layer.whenReactor.computed()) continue;\n\n const ctx = layer.context;\n\n if (!ctx) continue;\n\n // Layer beforeRender hook\n if (layer.lifecycle?.beforeRender) {\n try {\n layer.lifecycle.beforeRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" beforeRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n // Apply layer settings\n ctx.save();\n if (layer.settings) {\n Object.entries(layer.settings).forEach(([key, value]) => {\n if (typeof ctx[key] === 'function') {\n ctx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n ctx[key] = value;\n }\n });\n }\n\n const brushes = this.#brushes.get(layer.name) || [];\n\n // Render brushes\n for (const brush of brushes) {\n const brushStart = this.#runtimeConfig.debug?.enabled ? performance.now() : 0;\n\n if (brush.whenReactor && !brush.whenReactor.computed()) continue;\n\n\n const brushCtx = brush.context ? \n this.#contexts.get(brush.context) : \n ctx;\n\n if (!brushCtx) continue;\n\n // Brush beforeRender hook\n if (brush.lifecycle?.beforeRender) {\n try {\n brush.lifecycle.beforeRender(brushCtx, this.#timing);\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\" beforeRender:`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n continue;\n }\n }\n\n brushCtx.save();\n \n if (brush.settings) {\n Object.entries(brush.settings).forEach(([key, value]) => {\n if (typeof brushCtx[key] === 'function') {\n brushCtx[key](...(Array.isArray(value) ? value : [value]));\n } else {\n brushCtx[key] = value;\n }\n });\n }\n \n try {\n const requiredAssets = {};\n if (brush.assets) {\n for (const key of brush.assets) {\n requiredAssets[key] = this.#assets.get(key);\n }\n }\n brush.render(brushCtx, (brush.dataReactor ? brush.dataReactor.computed() : undefined), requiredAssets, this.#timing);\n\n // Brush afterRender hook\n if (brush.lifecycle?.afterRender) {\n brush.lifecycle.afterRender(brushCtx, this.#timing);\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const brushTime = performance.now() - brushStart;\n this.#metrics.brushTimes.set(brush.name, brushTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderBrushBounds(brushCtx, brush);\n }\n }\n } catch (error) {\n console.error(`Error in brush \"${brush.name}\":`, error);\n if (brush.lifecycle?.onError) brush.lifecycle.onError(error);\n } finally {\n brushCtx.restore();\n }\n }\n\n ctx.restore();\n\n // Layer afterRender hook\n if (layer.lifecycle?.afterRender) {\n try {\n layer.lifecycle.afterRender(ctx, this.#timing);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" afterRender:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n\n if (this.#runtimeConfig.debug?.enabled) {\n const layerTime = performance.now() - layerStart;\n this.#metrics.layerTimes.set(layer.name, layerTime);\n\n if (this.#runtimeConfig.debug?.showBounds) {\n this.#renderLayerBounds(ctx, layer);\n }\n }\n }\n\n // Render debug overlay if enabled\n if (this.#runtimeConfig.debug?.enabled) {\n this.#renderDebugOverlay();\n }\n \n } finally {\n this.#isRendering = false;\n }\n }\n\n #renderBrushBounds(ctx, brush) {\n ctx.save();\n ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';\n ctx.lineWidth = 1;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderLayerBounds(ctx, layer) {\n ctx.save();\n ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';\n ctx.lineWidth = 2;\n ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n ctx.restore();\n }\n\n #renderDebugOverlay() {\n const ctx = this.#contexts.get(ContextTypes['2D']);\n if (!ctx) return;\n\n ctx.save();\n ctx.resetTransform();\n ctx.font = '12px monospace';\n ctx.fillStyle = 'white';\n ctx.strokeStyle = 'black';\n ctx.lineWidth = 3;\n\n let y = 20;\n const lineHeight = 15;\n\n if (this.#runtimeConfig.debug?.showFPS) {\n const text = `FPS: ${Math.round(this.#metrics.fps)} (${this.#timing.deltaTime.toFixed(2)}ms)`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n if (this.#runtimeConfig.debug?.showLayerTiming) {\n ctx.fillText('Layer Times:', 10, y);\n y += lineHeight;\n\n for (const [name, time] of this.#metrics.layerTimes) {\n const text = ` ${name}: ${time.toFixed(2)}ms`;\n ctx.strokeText(text, 10, y);\n ctx.fillText(text, 10, y);\n y += lineHeight;\n }\n\n ctx.fillText(this.state.get(['_transitions', 'pointer', 'currentState']), 10, y);\n }\n\n ctx.restore();\n }\n\n handleResize(width, height) {\n // Call onResize hooks for all layers\n for (const layer of this.#layers.values()) {\n if (layer.lifecycle?.onResize) {\n try {\n layer.lifecycle.onResize(width, height, layer.context);\n } catch (error) {\n console.error(`Error in layer \"${layer.name}\" onResize:`, error);\n if (layer.lifecycle?.onError) layer.lifecycle.onError(error);\n }\n }\n }\n }\n\n #createReactor(fn, context = () => undefined) {\n if (!fn) return null;\n \n const computed = createComputed(fn, {\n immediate: true,\n context\n });\n \n const unsubscribe = addEffect(computed, () => this.#scheduleRender());\n \n return {computed, unsubscribe};\n }\n\n destroy() {\n this.stop();\n\n // Clean up pointer system\n if (this.#pointerUnsubscribe) {\n this.#pointerUnsubscribe();\n this.#pointerUnsubscribe = null;\n }\n if (this.#canvasEvents) {\n this.#canvasEvents.destroy();\n this.#canvasEvents = null;\n }\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n if (this.#pointerSurface) {\n this.#pointerSurface.$destroy();\n }\n\n // Clean up all layers and reactors\n for (const name of this.#layers.keys()) {\n this.#removeLayer(name);\n }\n }\n\n setTargetFPS(fps) {\n this.#runtimeConfig.targetFPS = fps;\n this.#runtimeConfig.fixedTimeStep = 1000 / fps;\n }\n\n setTimeScale(scale) {\n this.#runtimeConfig.timeScale = Math.max(0, scale);\n }\n\n setFixedTimeStep(step) {\n this.#runtimeConfig.fixedTimeStep = step;\n }\n\n setDebug(options = {}) {\n if (!this.#runtimeConfig.debug) {\n this.#runtimeConfig.debug = {};\n }\n Object.assign(this.#runtimeConfig.debug, options);\n }\n\n getMetrics() {\n return {\n ...this.#metrics,\n deltaTime: this.#timing.deltaTime,\n elapsedTime: this.#timing.elapsedTime,\n frameCount: this.#timing.frameCount\n };\n }\n\n // Public method to receive pointer events from main thread\n handlePointerEvent(normalizedEvent) {\n // Feed normalized events into surface\n this.#pointerSurface.handleEvent(normalizedEvent);\n\n // Handle hit testing and interactions\n this.#handlePointerInteraction(normalizedEvent);\n \n // Emit generic pointer events for external subscribers\n this.#emitPointerEvents(normalizedEvent);\n }\n\n #emitPointerEvents(normalizedEvent) {\n const { type } = normalizedEvent;\n const pointer = this.#pointerSurface;\n const event = pointer.event;\n \n // Emit basic pointer events\n switch (type) {\n case 'down':\n this.#emit('pointer:down', pointer);\n break;\n \n case 'up':\n this.#emit('pointer:up', pointer);\n \n // Emit click if it wasn't a drag\n if (event && !event.isDragging) {\n this.#emit('pointer:click', pointer);\n }\n break;\n \n case 'move':\n this.#emit('pointer:move', pointer);\n break;\n \n case 'dragstart':\n this.#emit('pointer:drag:start', pointer);\n break;\n \n case 'drag':\n this.#emit('pointer:drag:move', pointer);\n break;\n \n case 'dragend':\n this.#emit('pointer:drag:end', pointer);\n break;\n \n case 'scroll':\n this.#emit('pointer:scroll', pointer);\n break;\n \n case 'zoom':\n this.#emit('pointer:zoom', pointer);\n break;\n \n case 'dblclick':\n this.#emit('pointer:dblclick', pointer);\n break;\n\n case 'drop':\n this.#emit('pointer:drop', pointer);\n break;\n\n case 'dragenter':\n this.#emit('pointer:dragenter', pointer);\n break;\n\n case 'dragover':\n this.#emit('pointer:dragover', pointer);\n break;\n }\n \n // Check for canvas enter/leave\n const wasOverCanvas = this.#wasOverCanvas;\n const isOverCanvas = event?.isOverCanvas || false;\n \n if (isOverCanvas && !wasOverCanvas) {\n this.#emit('pointer:enter', pointer);\n } else if (!isOverCanvas && wasOverCanvas) {\n this.#emit('pointer:leave', pointer);\n }\n \n this.#wasOverCanvas = isOverCanvas;\n }\n\n #handlePointerInteraction(normalizedEvent) {\n const { type, x, y } = normalizedEvent;\n const pointer = this.#pointerSurface;\n\n switch (type) {\n case 'down': {\n const hitArea = this.#hitTest(x, y);\n pointer.setActiveArea(hitArea);\n\n if (hitArea?.onPointerDown?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerDown.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'up': {\n const activeArea = pointer.activeArea;\n if (activeArea?.onPointerUp?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerUp.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'move': {\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle pointer move on hovered area (only when NOT dragging)\n if (hitArea?.onPointerMove?.handler && !normalizedEvent.isDragging) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerMove.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n // Handle hover changes\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n break;\n }\n\n case 'dragstart': {\n const hitArea = this.#hitTest(x, y);\n if (hitArea?.onDragStart?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragStart.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'drag': {\n // Perform hit test to detect drop targets while dragging\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle hover changes (for drop target detection)\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n\n // Internal drag movement dispatches to current hit area\n if (hitArea?.onDragMove?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragMove.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dragend': {\n const hitArea = this.#hitTest(x, y);\n if (hitArea?.onDragEnd?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragEnd.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dragenter': {\n const hitArea = this.#hitTest(x, y);\n if (hitArea?.onDragEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n }\n \n case 'dragover': {\n // Perform hit test to detect drop targets while dragging\n const hitArea = this.#hitTest(x, y);\n const prevHovered = pointer.hoveredArea;\n\n // Handle hover changes (for drop target detection)\n if (hitArea?.id !== prevHovered?.id) {\n if (prevHovered?.onPointerLeave?.handler) {\n const ctx = this.#getContextForArea(prevHovered);\n prevHovered.onPointerLeave.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n if (hitArea?.onPointerEnter?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onPointerEnter.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n\n pointer.setHoveredArea(hitArea);\n }\n\n // External/native drag-over dispatches to onDragOver\n if (hitArea?.onDragOver?.handler) {\n const ctx = this.#getContextForArea(hitArea);\n hitArea.onDragOver.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n\n case 'dblclick':\n // Use active area from the last down event instead of a new hit test\n // This prevents issues when the hit registry is cleared during re-render\n const activeArea = pointer.activeArea;\n\n if (activeArea?.onPointerDblClick?.handler) {\n const ctx = this.#getContextForArea(activeArea);\n activeArea.onPointerDblClick.handler({\n event: normalizedEvent,\n ctx,\n emit: this.#emit.bind(this)\n });\n }\n break;\n }\n }\n\n #getContextForArea(area) {\n if (!area) return null;\n return area.context \n ? this.#contexts.get(area.context) \n : this.#contexts.get(ContextTypes['2D']);\n }\n\n subscribe(event, callback) {\n if (!this.#subscribers.has(event)) {\n this.#subscribers.set(event, new Set());\n }\n this.#subscribers.get(event).add(callback);\n \n return () => {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.#subscribers.delete(event);\n }\n }\n };\n }\n\n #hitTest(x, y) {\n // Sort by priority (highest first) and test\n const sorted = this.#hitRegistry.areas.sort((a, b) => \n (b.priority || 0) - (a.priority || 0)\n );\n \n for (const area of sorted) {\n if (this.#isPointInBounds(x, y, area.bounds)) {\n return area;\n }\n }\n return null;\n }\n\n #isPointInBounds(x, y, bounds) {\n return x >= bounds.x && \n x <= bounds.x + bounds.width &&\n y >= bounds.y && \n y <= bounds.y + bounds.height;\n }\n\n #emit(event, data) {\n const callbacks = this.#subscribers.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n callback(data);\n }\n }\n }\n\n // Test helper - only for testing, simulates normalized pointer events\n _testEmitPointerEvent(normalizedEvent) {\n this.#pointerSurface.handleEvent(normalizedEvent);\n this.#handlePointerInteraction(normalizedEvent);\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["ContextTypes", "HitRegistry", "#areas", "id", "area", "ServiceProvider", "CanvasEvents", "#canvas", "#offscreenCanvas", "#cachedRect", "#resizeObserver", "#subscribers", "#resizeSubscribers", "#pendingMove", "#rafId", "#hasTransferredControl", "#dropSubscribers", "#state", "canvas", "listener", "#addDropSubscriber", "#removeListeners", "#updateCachedRect", "#initializeListeners", "subscriber", "#emitResize", "#callDropSubscribers", "args", "entries", "entry", "width", "height", "#handleScroll", "#handleDown", "#handleDragEnter", "#handleDragOver", "#handleDragLeave", "#handleDrop", "#handleMove", "#handleUp", "#handleCancel", "event", "normalized", "#normalizeEvent", "#emit", "rawEvent", "type", "position", "#getPosition", "dx", "dy", "e", "dragend", "now", "timeDiff", "distance", "dblclickEvent", "#extractDragData", "rect", "files", "#extractFiles", "dataTransfer", "item", "file", "i", "resizeData", "isOverCanvas", "x", "y", "isWithinBounds", "deltaX", "deltaY", "deltaZ", "deltaMode", "dragDistance", "defineSurface", "usePointerSurface", "setup", "event", "hoveredArea", "activeArea", "handleEvent", "_", "normalizedEvent", "setHoveredArea", "area", "setActiveArea", "reset", "ServiceProvider", "createComputed", "destroyComputed", "addEffect", "createDefinition", "definitionType", "DEFINITIONS_TYPES", "GLOBAL_LAYER_NAME", "defineBrush", "defineLayer", "defineSubscription", "defineSubscriptions", "Painter", "#layers", "#brushes", "#canvas", "#contexts", "#assets", "#isRunning", "#frameId", "#isRendering", "#renderScheduled", "#runtimeConfig", "#timing", "#metrics", "#hitRegistry", "HitRegistry", "#pointerSurface", "usePointerSurface", "#canvasEvents", "#pointerUnsubscribe", "#resizeObserver", "#subscribers", "#wasOverCanvas", "#addLayer", "ContextTypes", "layerDef", "layers", "layer", "factories", "fn", "canvas", "offscreenCanvas", "assets", "name", "#removeLayer", "#render", "fps", "scale", "step", "options", "width", "height", "event", "callback", "normalizedEvent", "path", "factory", "type", "#addBrush", "#addSubscription", "#addSubscriptions", "domCanvas", "ctx", "CanvasEvents", "entries", "entry", "result", "#scheduleRender", "config", "#createReactor", "child", "error", "layerName", "brushFactory", "brushConfig", "brush", "subscriptionFactory", "subscriptionConfig", "subscriptionsFactory", "prefix", "subscriptions", "handler", "finalEvent", "brushes", "renderStart", "layerStart", "key", "value", "brushStart", "brushCtx", "requiredAssets", "brushTime", "#renderBrushBounds", "layerTime", "#renderLayerBounds", "#renderDebugOverlay", "y", "lineHeight", "text", "time", "context", "computed", "unsubscribe", "#handlePointerInteraction", "#emitPointerEvents", "pointer", "#emit", "wasOverCanvas", "isOverCanvas", "x", "hitArea", "#hitTest", "#getContextForArea", "activeArea", "prevHovered", "area", "callbacks", "sorted", "a", "b", "#isPointInBounds", "bounds", "data"]
|
|
7
7
|
}
|