@sunspots/core 0.1.1 → 0.1.3

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/index.d.mts CHANGED
@@ -40,6 +40,7 @@ declare enum ResizeDirection {
40
40
  TopLeft = 7
41
41
  }
42
42
 
43
+ declare function millimeterToDot(mm: number): number;
43
44
  declare function pixelToDot(px: number): number;
44
45
  declare function dotToPixel(dot: number): number;
45
46
  declare function millimeterToPixel(mm: number): number;
@@ -259,4 +260,4 @@ interface PointerEvent {
259
260
  offsetY: number;
260
261
  }
261
262
 
262
- export { type Box, Color, Placement, type PointerEvent, type PointerEventName, ReferenceLine, type ResizableConfig, ResizeDirection, type RightAngleRotation, Shape, type ShapeConfig, type ShapeEvent, Stage, type StageConfig, type StageEvent, type StageEventName, type Vector2, angleToRadian, dotToPixel, isLockAspectRatioResize, localDeltaToWorldRightAngle, millimeterToPixel, pixelToDot, pixelToMillimeter, radianToAngle, randomColor, rgbToHex, rgba, rotateBoxRightAngle, rotatePointRightAngle, withDpr, withHash, withPixel, worldDeltaToLocalRightAngle };
263
+ export { type Box, Color, Placement, type PointerEvent, type PointerEventName, ReferenceLine, type ResizableConfig, ResizeDirection, type RightAngleRotation, Shape, type ShapeConfig, type ShapeEvent, Stage, type StageConfig, type StageEvent, type StageEventName, type Vector2, angleToRadian, dotToPixel, isLockAspectRatioResize, localDeltaToWorldRightAngle, millimeterToDot, millimeterToPixel, pixelToDot, pixelToMillimeter, radianToAngle, randomColor, rgbToHex, rgba, rotateBoxRightAngle, rotatePointRightAngle, withDpr, withHash, withPixel, worldDeltaToLocalRightAngle };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var it=Object.defineProperty;var tt=Object.getOwnPropertySymbols;var pt=Object.prototype.hasOwnProperty,ut=Object.prototype.propertyIsEnumerable;var et=(i,t,e)=>t in i?it(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e,nt=(i,t)=>{for(var e in t||(t={}))pt.call(t,e)&&et(i,e,t[e]);if(tt)for(var e of tt(t))ut.call(t,e)&&et(i,e,t[e]);return i};var c=(i,t)=>it(i,"name",{value:t,configurable:!0});var ot="#",xt="px";function St(i){return Math.round(i*.8)}c(St,"pixelToDot");function Ct(i){return Math.round(i/.8)}c(Ct,"dotToPixel");function Rt(i){return i*10}c(Rt,"millimeterToPixel");function Bt(i){return i/10}c(Bt,"pixelToMillimeter");function L(i){return i*devicePixelRatio}c(L,"withDpr");function z(i){return i+xt}c(z,"withPixel");function rt(i){return ot+i}c(rt,"withHash");function at(){let i=(Math.random()*16777215<<0).toString(16);for(;i.length<6;)i=0+i;return ot+i}c(at,"randomColor");function st(i,t,e){return((1<<24)+(i<<16)+(t<<8)+e).toString(16).slice(1)}c(st,"rgbToHex");function ht(i,t,e,n=1){return`rgba(${i},${t},${e},${n})`}c(ht,"rgba");function X(i){return i*Math.PI/180}c(X,"angleToRadian");function kt(i){return i*180/Math.PI}c(kt,"radianToAngle");function U(i,t){switch(t){case 90:return{x:-i.y,y:i.x};case 180:return{x:-i.x,y:-i.y};case 270:return{x:i.y,y:-i.x};default:return i}}c(U,"rotatePointRightAngle");function ct(i,t,e){switch(e){case 90:return{x:t,y:-i};case 180:return{x:-i,y:-t};case 270:return{x:-t,y:i};default:return{x:i,y:t}}}c(ct,"worldDeltaToLocalRightAngle");function dt(i,t,e){switch(e){case 90:return{x:-t,y:i};case 180:return{x:-i,y:-t};case 270:return{x:t,y:-i};default:return{x:i,y:t}}}c(dt,"localDeltaToWorldRightAngle");function J(i,t,e){if(e===0)return nt({},i);let n=[{x:i.x,y:i.y},{x:i.x+i.width,y:i.y},{x:i.x,y:i.y+i.height},{x:i.x+i.width,y:i.y+i.height}],s=1/0,d=1/0,h=-1/0,l=-1/0;for(let o of n){let a={x:o.x-t.x,y:o.y-t.y},r=U(a,e),B={x:t.x+r.x,y:t.y+r.y};s=Math.min(s,B.x),d=Math.min(d,B.y),h=Math.max(h,B.x),l=Math.max(l,B.y)}return{x:s,y:d,width:h-s,height:l-d}}c(J,"rotateBoxRightAngle");var T={Transparent:ht(0,0,0,0),Black:"#000000",White:"#ffffff",Primary:"#3b82f6"};var lt=(e=>(e[e.Horizontal=0]="Horizontal",e[e.Vertical=1]="Vertical",e))(lt||{}),K=class K{constructor(t,e){this.placement=t;this.position=e}};c(K,"ReferenceLine");var y=K;var mt=(o=>(o[o.Top=0]="Top",o[o.Right=1]="Right",o[o.Bottom=2]="Bottom",o[o.Left=3]="Left",o[o.TopRight=4]="TopRight",o[o.BottomRight=5]="BottomRight",o[o.BottomLeft=6]="BottomLeft",o[o.TopLeft=7]="TopLeft",o))(mt||{});import{filter as bt,Subject as yt}from"rxjs";var P=new Map;var Q=class Q{constructor(t){this.config=t;this.index=0;this.resizable=!0;this.events=new yt;this.strokeWidth=0;this.rotation=0;for(;;){let e=at();if(e&&!P.has(e)){this.key=e,P.set(e,this);break}}Object.assign(this,t)}get x(){var t;return(t=this.config.x)!=null?t:0}set x(t){this.config.x=t}get y(){var t;return(t=this.config.y)!=null?t:0}set y(t){this.config.y=t}get width(){var t;return(t=this.config.width)!=null?t:0}set width(t){this.config.width=t}get height(){var t;return(t=this.config.height)!=null?t:0}set height(t){this.config.height=t}worldInnerBox(){return J(this.innerBox(),{x:this.x,y:this.y},this.rotation)}worldBoundingBox(){return J(this.boundingBox(),{x:this.x,y:this.y},this.rotation)}coord(){return{x:this.x,y:this.y}}emit(t){this.events.next(t)}on(t){return this.events.pipe(bt(e=>e.type===t))}destroy(){P.delete(this.key),this.events.complete()}setAttrs(t){Object.assign(this,t)}toObject(t={}){return Object.assign({type:this.type,index:this.index,x:this.x,y:this.y,width:this.width,height:this.height,fill:this.fill,stroke:this.stroke,strokeWidth:this.strokeWidth,rotation:this.rotation},t)}};c(Q,"Shape");var Y=Q;function O(i){return typeof i.resizable=="object"&&!!i.resizable.aspectRatio}c(O,"isLockAspectRatioResize");import{animationFrames as wt,filter as W,Subject as gt,takeUntil as j}from"rxjs";var Z=class Z extends Y{constructor(e){super({fill:T.White,stroke:T.Primary,strokeWidth:2});this.direction=e;this.type="anchor";this.radius=5}getAnchorLocalPoint(e,n){switch(this.direction){case 7:return{x:0,y:0};case 0:return{x:e/2,y:0};case 4:return{x:e,y:0};case 1:return{x:e,y:n/2};case 5:return{x:e,y:n};case 2:return{x:e/2,y:n};case 6:return{x:0,y:n};case 3:return{x:0,y:n/2}}}getAnchorWorldPoint(){let e=this.target.boundingBox(),{rotation:n}=this.target;if(!n){let a,r;switch(this.direction){case 0:case 2:a=e.x+e.width/2;break;case 4:case 1:case 5:a=e.x+e.width;break;case 7:case 6:case 3:a=e.x;break}switch(this.direction){case 7:case 0:case 4:r=e.y;break;case 1:case 3:r=e.y+e.height/2;break;case 5:case 2:case 6:r=e.y+e.height;break}return{x:a,y:r}}let s=e.x-this.target.x,d=e.y-this.target.y,h=this.getAnchorLocalPoint(e.width,e.height),l={x:s+h.x,y:d+h.y},o=U(l,n);return{x:this.target.x+o.x,y:this.target.y+o.y}}getRadius(){return this.radius/this.stage.scale}render(e){let{x:n,y:s,stroke:d,rotation:h,strokeWidth:l}=this;e.save(),h&&(e.translate(n,s),e.rotate(X(h))),e.beginPath(),e.arc(h?0:n,h?0:s,this.getRadius(),0,Math.PI*2,!1),e.fill(),d&&(e.lineWidth=(l!=null?l:1)/this.stage.scale,e.stroke()),e.closePath(),e.restore()}innerBox(){return{x:this.x-this.getRadius(),y:this.y-this.getRadius(),width:this.getRadius()*2,height:this.getRadius()*2}}boundingBox(){var d;let e=this.innerBox(),n=(d=this.strokeWidth)!=null?d:0,s=n/2;return e.x-=s,e.y-=s,e.width+=n,e.height+=n,e}setWidth(e){this.width=e,this.radius=e/2}setHeight(e){this.height=e,this.radius=e/2}get x(){return this.getAnchorWorldPoint().x}set x(e){}get y(){return this.getAnchorWorldPoint().y}set y(e){}setTarget(e){this.target=e}};c(Z,"Anchor");var v=Z;var _=class _{constructor(t){this.config=t;this.anchors=[new v(7),new v(0),new v(4),new v(1),new v(5),new v(2),new v(6),new v(3)];this.shapes=[];this.activatedShape=null;this.scale=1;this.snapLines=null;this.events=new gt;this.destroyed$=new gt;let{sceneCanvas:e,shadowCanvas:n,draggableCanvas:s,draftCanvas:d,canvasEvents:h,clientEvents:l}=t;this.context=e.getContext("2d"),this.shadowContext=n.getContext("2d",{willReadFrequently:!0}),this.draggableContext=s.getContext("2d"),this.draftContext=d.getContext("2d");for(let x of this.anchors)x.stage=this;this.resize();let o,a,r,B,I=!1;h.pipe(W(x=>x.type==="pointerdown"),j(this.destroyed$)).subscribe(x=>{if(x.button!==void 0&&x.button!==0)return;I=!0,o=x.offsetX,a=x.offsetY;let $=L(x.offsetX),N=L(x.offsetY),D=this.getShadowColor($,N),S=P.get(D);if(!S){this.emit({type:"pointerdown"}),this.setActivatedShape(null);return}if(this.activatedShape=S,S.emit({type:"pointerdown"}),S instanceof v){r=S.target.innerBox(),B=S.target.coord(),this.drawScene();return}this.setActivatedShape(S),this.emit({type:"pointerdown",target:S}),r=S.innerBox(),B=S.coord(),this.drawDraggable(),this.drawScene()}),l.pipe(W(x=>x.type==="pointermove"),W(()=>I),j(this.destroyed$)).subscribe(x=>{let $=x.offsetX,N=x.offsetY,D=($-o)/this.scale,S=(N-a)/this.scale;if(this.activatedShape instanceof v){this.snapLines=null;let C=this.activatedShape,g=C.target,{rotation:H}=g,E=ct(D,S,H),p=E.x,R=E.y,k=0,w=0,f=r.width,u=r.height;switch(C.direction){case 7:k=p,w=R,u=r.height-R,f=r.width-p;break;case 0:w=R,u=r.height-R,O(g)&&(f=u*g.resizable.aspectRatio);break;case 4:w=R,u=r.height-R,f=r.width+p;break;case 1:f=r.width+p,O(g)&&(u=f/g.resizable.aspectRatio);break;case 5:f=r.width+p,u=r.height+R;break;case 2:u=r.height+R,O(g)&&(f=u*g.resizable.aspectRatio);break;case 6:u=r.height+R,k=p,f=r.width-p;break;case 3:k=p,f=r.width-p,O(g)&&(u=f/g.resizable.aspectRatio);break}let M=1,b=1;(C.direction===7||C.direction===3||C.direction===6)&&(k=Math.min(k,r.width-M)),(C.direction===7||C.direction===0||C.direction===4)&&(w=Math.min(w,r.height-b)),f=Math.max(M,f),u=Math.max(b,u),k=Math.round(k),w=Math.round(w),f=Math.round(f),u=Math.round(u);let m=dt(k,w,H);g.x=Math.round(B.x+m.x),g.y=Math.round(B.y+m.y),g.setWidth?g.setWidth(Math.max(1,f)):g.width=Math.max(1,f),g.setHeight?g.setHeight(Math.max(1,u)):g.height=Math.max(1,u)}else if(this.activatedShape){let C=Math.round(B.x+D),g=Math.round(B.y+S),H=1/0,E=1/0;this.activatedShape.x=C,this.activatedShape.y=g;let p=this.activatedShape.worldBoundingBox(),R=[new y(0,0),new y(0,this.config.height/2),new y(0,this.config.height),new y(1,0),new y(1,this.config.width/2),new y(1,this.config.width)];for(let b of this.shapes){if(b===this.activatedShape)continue;let m=b.worldBoundingBox();R.push(new y(0,m.y),new y(0,m.y+m.height/2),new y(0,m.y+m.height),new y(1,m.x),new y(1,m.x+m.width/2),new y(1,m.x+m.width))}let k=2/this.scale,w=0,f=0,u,M;for(let b of R)switch(b.placement){case 0:{let m=p.y+f,F=p.y+p.height/2+f,G=p.y+p.height+f,q=[b.position-m,b.position-F,b.position-G];for(let V of q){let A=Math.abs(V);A<=k&&A<E&&(f=V,E=A,M=b.position)}break}case 1:{let m=p.x+w,F=p.x+p.width/2+w,G=p.x+p.width+w,q=[b.position-m,b.position-F,b.position-G];for(let V of q){let A=Math.abs(V);A<=k&&A<H&&(w=V,H=A,u=b.position)}break}}C=Math.round(C+w),g=Math.round(g+f),this.snapLines=u!==void 0||M!==void 0?{x:u,y:M}:null,this.activatedShape.x=C,this.activatedShape.y=g}}),l.pipe(W(x=>x.type==="pointerup"||x.type==="pointercancel"),j(this.destroyed$)).subscribe(()=>{I=!1,this.snapLines=null,this.render()}),wt().pipe(W(()=>I&&!!this.activatedShape),j(this.destroyed$)).subscribe(()=>{this.drawDraggable()})}resize(t){Object.assign(this.config,t);let{sceneCanvas:e,shadowCanvas:n,draggableCanvas:s,draftCanvas:d,width:h,height:l,dpr:o}=this.config;for(let a of[e,n,s,d]){let r=a.getContext("2d");a.style.width=z(h),a.style.height=z(l),a.width=L(h),a.height=L(l),r.scale(o,o)}}zoom(t){let{sceneCanvas:e,shadowCanvas:n,draggableCanvas:s,draftCanvas:d,dpr:h,width:l,height:o}=this.config;for(let a of[e,n,s,d]){let r=a.getContext("2d");a.style.width=z(l*t),a.style.height=z(o*t),a.width=L(l*t),a.height=L(o*t),r.scale(h*t,h*t)}this.scale=t}add(...t){for(let e of t)e.index=this.shapes.length,e.stage=this,this.shapes.push(e),this.draw(e),this.emit({type:"add",target:e})}remove(...t){let e=this.getActivatedShape();for(let n of t){let s=this.shapes.indexOf(n);s!==-1&&(n.destroy(),this.shapes.splice(s,1),e===n&&this.setActivatedShape(null),this.emit({type:"remove",target:n}))}for(let n=0;n<this.shapes.length;n++)this.shapes[n].index=n}setActivatedShape(t){if(!t){this.activatedShape=null;return}for(let e of this.shapes)e.index>t.index&&e.index--;t.index=this.shapes.length;for(let e of this.anchors)e.target=t;this.activatedShape=t}getActivatedShape(){return this.activatedShape instanceof v?this.activatedShape.target:this.activatedShape}render(){this.activatedShape?this.drawDraggable():this.clear(this.draggableContext),this.drawScene()}isActivatedShape(t){let e=this.getActivatedShape();return t===e}drawScene(){this.clear(this.context),this.clear(this.shadowContext);for(let e of this.shapes.slice().sort((n,s)=>n.index-s.index))this.draw(e);let t=this.getActivatedShape();if(t&&t.resizable)for(let e of this.anchors)this.drawShadow(e)}draw(t){var e;this.drawShadow(t),!this.isActivatedShape(t)&&(this.context.save(),this.context.fillStyle=(e=t.fill)!=null?e:T.Transparent,t.stroke&&(this.context.lineWidth=t.strokeWidth,this.context.strokeStyle=t.stroke),this.context.beginPath(),t.render(this.context),this.context.stroke(),this.context.restore())}drawDraggable(){var n;let t=this.getActivatedShape(),e=this.draggableContext;t&&(this.clear(e),e.save(),e.fillStyle=(n=t.fill)!=null?n:T.Transparent,t.stroke&&(e.lineWidth=t.strokeWidth,e.strokeStyle=t.stroke),e.beginPath(),t.render(e),e.stroke(),e.restore(),this.drawTransformer(t),this.drawSnapLines())}drawSnapLines(){if(!this.snapLines)return;let t=this.draggableContext,{x:e,y:n}=this.snapLines;t.save(),t.strokeStyle=T.Primary,t.lineWidth=.5/this.scale,n!==void 0&&(t.beginPath(),t.moveTo(0,n),t.lineTo(this.config.width,n),t.stroke()),e!==void 0&&(t.beginPath(),t.moveTo(e,0),t.lineTo(e,this.config.height),t.stroke()),t.restore()}drawTransformer(t){var o;let e=this.draggableContext,{x:n,y:s,rotation:d}=t,h=t.boundingBox();if(e.save(),d&&(e.translate(n,s),e.rotate(X(d))),e.fillStyle=T.White,e.strokeStyle=T.Primary,e.lineWidth=2/this.scale,e.strokeRect(d?h.x-n:h.x,d?h.y-s:h.y,h.width,h.height),e.restore(),!t.resizable)return;let l=[];typeof t.resizable=="object"&&(t.resizable.aspectRatio?l=[0,1,2,3]:t.resizable.directions&&(l=t.resizable.directions));for(let a of this.anchors)l.length&&!l.includes(a.direction)||(e.fillStyle=(o=a.fill)!=null?o:T.Transparent,e.strokeStyle=a.stroke,a.rotation=d,a.render(e))}drawShadow(t){var n;let e=this.shadowContext;e.fillStyle=t.fill?t.key:T.Transparent,e.strokeStyle=t.key,t.stroke&&(e.lineWidth=t.strokeWidth),e.beginPath(),((n=t.renderShadow)!=null?n:t.render).call(t,e),e.stroke()}getShadowColor(t,e){let{data:n}=this.shadowContext.getImageData(t,e,1,1);return rt(st(n[0],n[1],n[2]))}clear(t){t.clearRect(0,0,this.config.width,this.config.height)}emit(t){this.events.next(t)}on(t){return this.events.pipe(W(e=>e.type===t))}destroy(){this.destroyed$.next(),this.destroyed$.complete(),this.events.complete();for(let t of this.shapes)t.destroy()}toObject(){return{width:this.config.width,height:this.config.height,children:this.shapes.map(t=>t.toObject())}}toBlob(t=1){return this.setActivatedShape(null),this.render(),new Promise(e=>{this.config.sceneCanvas.toBlob(n=>e(n),"image/webp",t)})}};c(_,"Stage");var ft=_;export{T as Color,lt as Placement,y as ReferenceLine,mt as ResizeDirection,Y as Shape,ft as Stage,X as angleToRadian,Ct as dotToPixel,O as isLockAspectRatioResize,dt as localDeltaToWorldRightAngle,Rt as millimeterToPixel,St as pixelToDot,Bt as pixelToMillimeter,kt as radianToAngle,at as randomColor,st as rgbToHex,ht as rgba,J as rotateBoxRightAngle,U as rotatePointRightAngle,L as withDpr,rt as withHash,z as withPixel,ct as worldDeltaToLocalRightAngle};
1
+ var it=Object.defineProperty;var tt=Object.getOwnPropertySymbols;var pt=Object.prototype.hasOwnProperty,ut=Object.prototype.propertyIsEnumerable;var et=(i,t,e)=>t in i?it(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e,nt=(i,t)=>{for(var e in t||(t={}))pt.call(t,e)&&et(i,e,t[e]);if(tt)for(var e of tt(t))ut.call(t,e)&&et(i,e,t[e]);return i};var s=(i,t)=>it(i,"name",{value:t,configurable:!0});var ot="#",xt="px";function St(i){return Math.round(i*.8*10)}s(St,"millimeterToDot");function Ct(i){return Math.round(i*.8)}s(Ct,"pixelToDot");function Rt(i){return Math.round(i/.8)}s(Rt,"dotToPixel");function Bt(i){return i*10}s(Bt,"millimeterToPixel");function kt(i){return i/10}s(kt,"pixelToMillimeter");function L(i){return i*devicePixelRatio}s(L,"withDpr");function z(i){return i+xt}s(z,"withPixel");function rt(i){return ot+i}s(rt,"withHash");function at(){let i=(Math.random()*16777215<<0).toString(16);for(;i.length<6;)i=0+i;return ot+i}s(at,"randomColor");function st(i,t,e){return((1<<24)+(i<<16)+(t<<8)+e).toString(16).slice(1)}s(st,"rgbToHex");function ht(i,t,e,n=1){return`rgba(${i},${t},${e},${n})`}s(ht,"rgba");function X(i){return i*Math.PI/180}s(X,"angleToRadian");function Tt(i){return i*180/Math.PI}s(Tt,"radianToAngle");function U(i,t){switch(t){case 90:return{x:-i.y,y:i.x};case 180:return{x:-i.x,y:-i.y};case 270:return{x:i.y,y:-i.x};default:return i}}s(U,"rotatePointRightAngle");function ct(i,t,e){switch(e){case 90:return{x:t,y:-i};case 180:return{x:-i,y:-t};case 270:return{x:-t,y:i};default:return{x:i,y:t}}}s(ct,"worldDeltaToLocalRightAngle");function dt(i,t,e){switch(e){case 90:return{x:-t,y:i};case 180:return{x:-i,y:-t};case 270:return{x:t,y:-i};default:return{x:i,y:t}}}s(dt,"localDeltaToWorldRightAngle");function J(i,t,e){if(e===0)return nt({},i);let n=[{x:i.x,y:i.y},{x:i.x+i.width,y:i.y},{x:i.x,y:i.y+i.height},{x:i.x+i.width,y:i.y+i.height}],h=1/0,d=1/0,c=-1/0,l=-1/0;for(let o of n){let a={x:o.x-t.x,y:o.y-t.y},r=U(a,e),B={x:t.x+r.x,y:t.y+r.y};h=Math.min(h,B.x),d=Math.min(d,B.y),c=Math.max(c,B.x),l=Math.max(l,B.y)}return{x:h,y:d,width:c-h,height:l-d}}s(J,"rotateBoxRightAngle");var T={Transparent:ht(0,0,0,0),Black:"#000000",White:"#ffffff",Primary:"#3b82f6"};var lt=(e=>(e[e.Horizontal=0]="Horizontal",e[e.Vertical=1]="Vertical",e))(lt||{}),K=class K{constructor(t,e){this.placement=t;this.position=e}};s(K,"ReferenceLine");var y=K;var mt=(o=>(o[o.Top=0]="Top",o[o.Right=1]="Right",o[o.Bottom=2]="Bottom",o[o.Left=3]="Left",o[o.TopRight=4]="TopRight",o[o.BottomRight=5]="BottomRight",o[o.BottomLeft=6]="BottomLeft",o[o.TopLeft=7]="TopLeft",o))(mt||{});import{filter as bt,Subject as yt}from"rxjs";var P=new Map;var Q=class Q{constructor(t){this.config=t;this.index=0;this.resizable=!0;this.events=new yt;this.strokeWidth=0;this.rotation=0;for(;;){let e=at();if(e&&!P.has(e)){this.key=e,P.set(e,this);break}}Object.assign(this,t)}get x(){var t;return(t=this.config.x)!=null?t:0}set x(t){this.config.x=t}get y(){var t;return(t=this.config.y)!=null?t:0}set y(t){this.config.y=t}get width(){var t;return(t=this.config.width)!=null?t:0}set width(t){this.config.width=t}get height(){var t;return(t=this.config.height)!=null?t:0}set height(t){this.config.height=t}worldInnerBox(){return J(this.innerBox(),{x:this.x,y:this.y},this.rotation)}worldBoundingBox(){return J(this.boundingBox(),{x:this.x,y:this.y},this.rotation)}coord(){return{x:this.x,y:this.y}}emit(t){this.events.next(t)}on(t){return this.events.pipe(bt(e=>e.type===t))}destroy(){P.delete(this.key),this.events.complete()}setAttrs(t){Object.assign(this,t)}toObject(t={}){return Object.assign({type:this.type,index:this.index,x:this.x,y:this.y,width:this.width,height:this.height,fill:this.fill,stroke:this.stroke,strokeWidth:this.strokeWidth,rotation:this.rotation},t)}};s(Q,"Shape");var Y=Q;function O(i){return typeof i.resizable=="object"&&!!i.resizable.aspectRatio}s(O,"isLockAspectRatioResize");import{animationFrames as wt,filter as W,Subject as gt,takeUntil as j}from"rxjs";var Z=class Z extends Y{constructor(e){super({fill:T.White,stroke:T.Primary,strokeWidth:2});this.direction=e;this.type="anchor";this.radius=5}getAnchorLocalPoint(e,n){switch(this.direction){case 7:return{x:0,y:0};case 0:return{x:e/2,y:0};case 4:return{x:e,y:0};case 1:return{x:e,y:n/2};case 5:return{x:e,y:n};case 2:return{x:e/2,y:n};case 6:return{x:0,y:n};case 3:return{x:0,y:n/2}}}getAnchorWorldPoint(){let e=this.target.boundingBox(),{rotation:n}=this.target;if(!n){let a,r;switch(this.direction){case 0:case 2:a=e.x+e.width/2;break;case 4:case 1:case 5:a=e.x+e.width;break;case 7:case 6:case 3:a=e.x;break}switch(this.direction){case 7:case 0:case 4:r=e.y;break;case 1:case 3:r=e.y+e.height/2;break;case 5:case 2:case 6:r=e.y+e.height;break}return{x:a,y:r}}let h=e.x-this.target.x,d=e.y-this.target.y,c=this.getAnchorLocalPoint(e.width,e.height),l={x:h+c.x,y:d+c.y},o=U(l,n);return{x:this.target.x+o.x,y:this.target.y+o.y}}getRadius(){return this.radius/this.stage.scale}render(e){let{x:n,y:h,stroke:d,rotation:c,strokeWidth:l}=this;e.save(),c&&(e.translate(n,h),e.rotate(X(c))),e.beginPath(),e.arc(c?0:n,c?0:h,this.getRadius(),0,Math.PI*2,!1),e.fill(),d&&(e.lineWidth=(l!=null?l:1)/this.stage.scale,e.stroke()),e.closePath(),e.restore()}innerBox(){return{x:this.x-this.getRadius(),y:this.y-this.getRadius(),width:this.getRadius()*2,height:this.getRadius()*2}}boundingBox(){var d;let e=this.innerBox(),n=(d=this.strokeWidth)!=null?d:0,h=n/2;return e.x-=h,e.y-=h,e.width+=n,e.height+=n,e}setWidth(e){this.width=e,this.radius=e/2}setHeight(e){this.height=e,this.radius=e/2}get x(){return this.getAnchorWorldPoint().x}set x(e){}get y(){return this.getAnchorWorldPoint().y}set y(e){}setTarget(e){this.target=e}};s(Z,"Anchor");var v=Z;var _=class _{constructor(t){this.config=t;this.anchors=[new v(7),new v(0),new v(4),new v(1),new v(5),new v(2),new v(6),new v(3)];this.shapes=[];this.activatedShape=null;this.scale=1;this.snapLines=null;this.events=new gt;this.destroyed$=new gt;let{sceneCanvas:e,shadowCanvas:n,draggableCanvas:h,draftCanvas:d,canvasEvents:c,clientEvents:l}=t;this.context=e.getContext("2d"),this.shadowContext=n.getContext("2d",{willReadFrequently:!0}),this.draggableContext=h.getContext("2d"),this.draftContext=d.getContext("2d");for(let x of this.anchors)x.stage=this;this.resize();let o,a,r,B,I=!1;c.pipe(W(x=>x.type==="pointerdown"),j(this.destroyed$)).subscribe(x=>{if(x.button!==void 0&&x.button!==0)return;I=!0,o=x.offsetX,a=x.offsetY;let $=L(x.offsetX),N=L(x.offsetY),D=this.getShadowColor($,N),S=P.get(D);if(!S){this.emit({type:"pointerdown"}),this.setActivatedShape(null);return}if(this.activatedShape=S,S.emit({type:"pointerdown"}),S instanceof v){r=S.target.innerBox(),B=S.target.coord(),this.drawScene();return}this.setActivatedShape(S),this.emit({type:"pointerdown",target:S}),r=S.innerBox(),B=S.coord(),this.drawDraggable(),this.drawScene()}),l.pipe(W(x=>x.type==="pointermove"),W(()=>I),j(this.destroyed$)).subscribe(x=>{let $=x.offsetX,N=x.offsetY,D=($-o)/this.scale,S=(N-a)/this.scale;if(this.activatedShape instanceof v){this.snapLines=null;let C=this.activatedShape,g=C.target,{rotation:H}=g,E=ct(D,S,H),p=E.x,R=E.y,k=0,w=0,f=r.width,u=r.height;switch(C.direction){case 7:k=p,w=R,u=r.height-R,f=r.width-p;break;case 0:w=R,u=r.height-R,O(g)&&(f=u*g.resizable.aspectRatio);break;case 4:w=R,u=r.height-R,f=r.width+p;break;case 1:f=r.width+p,O(g)&&(u=f/g.resizable.aspectRatio);break;case 5:f=r.width+p,u=r.height+R;break;case 2:u=r.height+R,O(g)&&(f=u*g.resizable.aspectRatio);break;case 6:u=r.height+R,k=p,f=r.width-p;break;case 3:k=p,f=r.width-p,O(g)&&(u=f/g.resizable.aspectRatio);break}let M=1,b=1;(C.direction===7||C.direction===3||C.direction===6)&&(k=Math.min(k,r.width-M)),(C.direction===7||C.direction===0||C.direction===4)&&(w=Math.min(w,r.height-b)),f=Math.max(M,f),u=Math.max(b,u),k=Math.round(k),w=Math.round(w),f=Math.round(f),u=Math.round(u);let m=dt(k,w,H);g.x=Math.round(B.x+m.x),g.y=Math.round(B.y+m.y),g.setWidth?g.setWidth(Math.max(1,f)):g.width=Math.max(1,f),g.setHeight?g.setHeight(Math.max(1,u)):g.height=Math.max(1,u)}else if(this.activatedShape){let C=Math.round(B.x+D),g=Math.round(B.y+S),H=1/0,E=1/0;this.activatedShape.x=C,this.activatedShape.y=g;let p=this.activatedShape.worldBoundingBox(),R=[new y(0,0),new y(0,this.config.height/2),new y(0,this.config.height),new y(1,0),new y(1,this.config.width/2),new y(1,this.config.width)];for(let b of this.shapes){if(b===this.activatedShape)continue;let m=b.worldBoundingBox();R.push(new y(0,m.y),new y(0,m.y+m.height/2),new y(0,m.y+m.height),new y(1,m.x),new y(1,m.x+m.width/2),new y(1,m.x+m.width))}let k=2/this.scale,w=0,f=0,u,M;for(let b of R)switch(b.placement){case 0:{let m=p.y+f,F=p.y+p.height/2+f,G=p.y+p.height+f,q=[b.position-m,b.position-F,b.position-G];for(let V of q){let A=Math.abs(V);A<=k&&A<E&&(f=V,E=A,M=b.position)}break}case 1:{let m=p.x+w,F=p.x+p.width/2+w,G=p.x+p.width+w,q=[b.position-m,b.position-F,b.position-G];for(let V of q){let A=Math.abs(V);A<=k&&A<H&&(w=V,H=A,u=b.position)}break}}C=Math.round(C+w),g=Math.round(g+f),this.snapLines=u!==void 0||M!==void 0?{x:u,y:M}:null,this.activatedShape.x=C,this.activatedShape.y=g}}),l.pipe(W(x=>x.type==="pointerup"||x.type==="pointercancel"),j(this.destroyed$)).subscribe(()=>{I=!1,this.snapLines=null,this.render()}),wt().pipe(W(()=>I&&!!this.activatedShape),j(this.destroyed$)).subscribe(()=>{this.drawDraggable()})}resize(t){Object.assign(this.config,t);let{sceneCanvas:e,shadowCanvas:n,draggableCanvas:h,draftCanvas:d,width:c,height:l,dpr:o}=this.config;for(let a of[e,n,h,d]){let r=a.getContext("2d");a.style.width=z(c),a.style.height=z(l),a.width=L(c),a.height=L(l),r.scale(o,o)}}zoom(t){let{sceneCanvas:e,shadowCanvas:n,draggableCanvas:h,draftCanvas:d,dpr:c,width:l,height:o}=this.config;for(let a of[e,n,h,d]){let r=a.getContext("2d");a.style.width=z(l*t),a.style.height=z(o*t),a.width=L(l*t),a.height=L(o*t),r.scale(c*t,c*t)}this.scale=t}add(...t){for(let e of t)e.index=this.shapes.length,e.stage=this,this.shapes.push(e),this.draw(e),this.emit({type:"add",target:e})}remove(...t){let e=this.getActivatedShape();for(let n of t){let h=this.shapes.indexOf(n);h!==-1&&(n.destroy(),this.shapes.splice(h,1),e===n&&this.setActivatedShape(null),this.emit({type:"remove",target:n}))}for(let n=0;n<this.shapes.length;n++)this.shapes[n].index=n}setActivatedShape(t){if(!t){this.activatedShape=null;return}for(let e of this.shapes)e.index>t.index&&e.index--;t.index=this.shapes.length;for(let e of this.anchors)e.target=t;this.activatedShape=t}getActivatedShape(){return this.activatedShape instanceof v?this.activatedShape.target:this.activatedShape}render(){this.activatedShape?this.drawDraggable():this.clear(this.draggableContext),this.drawScene()}isActivatedShape(t){let e=this.getActivatedShape();return t===e}drawScene(){this.clear(this.context),this.clear(this.shadowContext);for(let e of this.shapes.slice().sort((n,h)=>n.index-h.index))this.draw(e);let t=this.getActivatedShape();if(t&&t.resizable)for(let e of this.anchors)this.drawShadow(e)}draw(t){var e;this.drawShadow(t),!this.isActivatedShape(t)&&(this.context.save(),this.context.fillStyle=(e=t.fill)!=null?e:T.Transparent,t.stroke&&(this.context.lineWidth=t.strokeWidth,this.context.strokeStyle=t.stroke),this.context.beginPath(),t.render(this.context),this.context.stroke(),this.context.restore())}drawDraggable(){var n;let t=this.getActivatedShape(),e=this.draggableContext;t&&(this.clear(e),e.save(),e.fillStyle=(n=t.fill)!=null?n:T.Transparent,t.stroke&&(e.lineWidth=t.strokeWidth,e.strokeStyle=t.stroke),e.beginPath(),t.render(e),e.stroke(),e.restore(),this.drawTransformer(t),this.drawSnapLines())}drawSnapLines(){if(!this.snapLines)return;let t=this.draggableContext,{x:e,y:n}=this.snapLines;t.save(),t.strokeStyle=T.Primary,t.lineWidth=.5/this.scale,n!==void 0&&(t.beginPath(),t.moveTo(0,n),t.lineTo(this.config.width,n),t.stroke()),e!==void 0&&(t.beginPath(),t.moveTo(e,0),t.lineTo(e,this.config.height),t.stroke()),t.restore()}drawTransformer(t){var o;let e=this.draggableContext,{x:n,y:h,rotation:d}=t,c=t.boundingBox();if(e.save(),d&&(e.translate(n,h),e.rotate(X(d))),e.fillStyle=T.White,e.strokeStyle=T.Primary,e.lineWidth=2/this.scale,e.strokeRect(d?c.x-n:c.x,d?c.y-h:c.y,c.width,c.height),e.restore(),!t.resizable)return;let l=[];typeof t.resizable=="object"&&(t.resizable.aspectRatio?l=[0,1,2,3]:t.resizable.directions&&(l=t.resizable.directions));for(let a of this.anchors)l.length&&!l.includes(a.direction)||(e.fillStyle=(o=a.fill)!=null?o:T.Transparent,e.strokeStyle=a.stroke,a.rotation=d,a.render(e))}drawShadow(t){var n;let e=this.shadowContext;e.fillStyle=t.fill?t.key:T.Transparent,e.strokeStyle=t.key,t.stroke&&(e.lineWidth=t.strokeWidth),e.beginPath(),((n=t.renderShadow)!=null?n:t.render).call(t,e),e.stroke()}getShadowColor(t,e){let{data:n}=this.shadowContext.getImageData(t,e,1,1);return rt(st(n[0],n[1],n[2]))}clear(t){t.clearRect(0,0,this.config.width,this.config.height)}emit(t){this.events.next(t)}on(t){return this.events.pipe(W(e=>e.type===t))}destroy(){this.destroyed$.next(),this.destroyed$.complete(),this.events.complete();for(let t of this.shapes)t.destroy()}toObject(){return{width:this.config.width,height:this.config.height,children:this.shapes.map(t=>t.toObject())}}toBlob(t=1){return this.setActivatedShape(null),this.render(),new Promise(e=>{this.config.sceneCanvas.toBlob(n=>e(n),"image/webp",t)})}};s(_,"Stage");var ft=_;export{T as Color,lt as Placement,y as ReferenceLine,mt as ResizeDirection,Y as Shape,ft as Stage,X as angleToRadian,Rt as dotToPixel,O as isLockAspectRatioResize,dt as localDeltaToWorldRightAngle,St as millimeterToDot,Bt as millimeterToPixel,Ct as pixelToDot,kt as pixelToMillimeter,Tt as radianToAngle,at as randomColor,st as rgbToHex,ht as rgba,J as rotateBoxRightAngle,U as rotatePointRightAngle,L as withDpr,rt as withHash,z as withPixel,ct as worldDeltaToLocalRightAngle};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sunspots/core",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",
@@ -28,5 +28,5 @@
28
28
  "peerDependencies": {
29
29
  "rxjs": "^7.8.1"
30
30
  },
31
- "gitHead": "8c984a1f9793fade14eb872f87a063ae8bfbded1"
31
+ "gitHead": "d8273ddb1fde69f3713633dbbf28a4cf89d513f5"
32
32
  }