@sketch-ruler/core 3.0.0-beta.0
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/AGENTS.md +145 -0
- package/README.md +230 -0
- package/lib/engine/coordinate.d.ts +38 -0
- package/lib/engine/coordinate.d.ts.map +1 -0
- package/lib/engine/index.d.ts +7 -0
- package/lib/engine/index.d.ts.map +1 -0
- package/lib/engine/matrix.d.ts +45 -0
- package/lib/engine/matrix.d.ts.map +1 -0
- package/lib/engine/minimap-engine.d.ts +64 -0
- package/lib/engine/minimap-engine.d.ts.map +1 -0
- package/lib/engine/transform-engine.d.ts +78 -0
- package/lib/engine/transform-engine.d.ts.map +1 -0
- package/lib/index.cjs +1 -0
- package/lib/index.d.ts +23 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.iife.js +1 -0
- package/lib/index.js +950 -0
- package/lib/index.umd.cjs +1 -0
- package/lib/managers/canvas-manager.d.ts +61 -0
- package/lib/managers/canvas-manager.d.ts.map +1 -0
- package/lib/plugins/index.d.ts +2 -0
- package/lib/plugins/index.d.ts.map +1 -0
- package/lib/plugins/plugin-manager.d.ts +33 -0
- package/lib/plugins/plugin-manager.d.ts.map +1 -0
- package/lib/scale/index.d.ts +18 -0
- package/lib/scale/index.d.ts.map +1 -0
- package/lib/scale/tick-config.d.ts +15 -0
- package/lib/scale/tick-config.d.ts.map +1 -0
- package/lib/snap/snap-engine.d.ts +50 -0
- package/lib/snap/snap-engine.d.ts.map +1 -0
- package/lib/state/index.d.ts +3 -0
- package/lib/state/index.d.ts.map +1 -0
- package/lib/state/line-manager.d.ts +20 -0
- package/lib/state/line-manager.d.ts.map +1 -0
- package/lib/state/ruler-state.d.ts +49 -0
- package/lib/state/ruler-state.d.ts.map +1 -0
- package/lib/types/index.d.ts +164 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/utils/id-utils.d.ts +3 -0
- package/lib/utils/id-utils.d.ts.map +1 -0
- package/lib/utils/line-utils.d.ts +40 -0
- package/lib/utils/line-utils.d.ts.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.SketchRulerCore={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(){return new Float64Array([1,0,0,1,0,0])}function n(e,t,n){return new Float64Array([e,0,0,e,t,n])}function r(e,t){let n=new Float64Array(6);return n[0]=e[0]*t[0]+e[2]*t[1],n[1]=e[1]*t[0]+e[3]*t[1],n[2]=e[0]*t[2]+e[2]*t[3],n[3]=e[1]*t[2]+e[3]*t[3],n[4]=e[0]*t[4]+e[2]*t[5]+e[4],n[5]=e[1]*t[4]+e[3]*t[5]+e[5],n}function i(e){let t=e[0]*e[3]-e[1]*e[2];if(Math.abs(t)<1e-10)return null;let n=1/t,r=new Float64Array(6);return r[0]=e[3]*n,r[1]=-e[1]*n,r[2]=-e[2]*n,r[3]=e[0]*n,r[4]=(e[2]*e[5]-e[3]*e[4])*n,r[5]=(e[1]*e[4]-e[0]*e[5])*n,r}function a(e){return{scale:e[0],translateX:e[4],translateY:e[5]}}function o(e){return`matrix(${e[0]}, ${e[1]}, ${e[2]}, ${e[3]}, ${e[4]}, ${e[5]})`}function s(e,t,n=1e-6){for(let r=0;r<6;r++)if(Math.abs(e[r]-t[r])>n)return!1;return!0}function c(e,t,n){let r=e[0]*e[3]-e[1]*e[2];if(Math.abs(r)<1e-10)return{x:0,y:0};let i=1/r,a=t-e[4],o=n-e[5];return{x:(e[3]*a-e[2]*o)*i,y:(-e[1]*a+e[0]*o)*i}}function l(e,t,n){return{x:e[0]*t+e[2]*n+e[4],y:e[1]*t+e[3]*n+e[5]}}function u(e,t){return t.map(t=>c(e,t.x,t.y))}function d(e,t){return t.map(t=>l(e,t.x,t.y))}function f(e,t,n=`contain`,r=0){if(e.width<=0||e.height<=0)return{scale:1,x:t.x,y:t.y};let i={x:t.x+t.width*r/2,y:t.y+t.height*r/2,width:t.width*(1-r),height:t.height*(1-r)},a=i.width/e.width,o=i.height/e.height,s;s=n===`contain`?Math.min(a,o):n===`cover`?Math.max(a,o):1;let c=i.x+(i.width-e.width*s)/2,l=i.y+(i.height-e.height*s)/2;return{scale:s,x:c,y:l}}var p=class{matrix;targetState;currentState;minZoom;maxZoom;enableAnimation;animationDuration;animationMode;dampingRatio;naturalFrequency;timeConstant;pendingTransform=!1;rafId=null;callbacks=new Set;lastFrameTime=0;velocity={x:0,y:0,scale:0};constructor(e={x:0,y:0,scale:1},t={}){this.minZoom=t.minZoom??.1,this.maxZoom=t.maxZoom??10,this.enableAnimation=t.enableAnimation??!1,this.animationDuration=t.animationDuration??200,this.animationMode=t.animationMode??`ease-out`,this.dampingRatio=t.dampingRatio??.8,this.naturalFrequency=t.naturalFrequency??20,this.timeConstant=t.timeConstant??80;let r=this.clampScale(e.scale);this.currentState={...e,scale:r},this.targetState={...this.currentState},this.matrix=n(r,e.x,e.y)}onUpdate(e){return this.callbacks.add(e),e({...this.currentState}),()=>{this.callbacks.delete(e)}}setTransform(e){e.scale!==void 0&&(this.targetState.scale=this.clampScale(e.scale)),e.x!==void 0&&(this.targetState.x=e.x),e.y!==void 0&&(this.targetState.y=e.y),this.enableAnimation?this.scheduleUpdate():(this.currentState={...this.targetState},this.updateMatrix(),this.notify())}panBy(e,t){this.targetState.x+=e,this.targetState.y+=t,this.enableAnimation?this.scheduleUpdate():(this.currentState={...this.targetState},this.updateMatrix(),this.notify())}zoomBy(e,t,n){let r=this.targetState.scale,i=this.clampScale(r+e),a=i/r;Math.abs(a-1)<1e-6||(this.targetState.x=t-(t-this.targetState.x)*a,this.targetState.y=n-(n-this.targetState.y)*a,this.targetState.scale=i,this.enableAnimation?this.scheduleUpdate():(this.currentState={...this.targetState},this.updateMatrix(),this.notify()))}zoomTo(e,t,n){let r=this.clampScale(e)-this.targetState.scale;this.zoomBy(r,t,n)}toWorldPoint(e,t){return c(this.matrix,e,t)}toScreenPoint(e,t){return l(this.matrix,e,t)}getState(){return{...this.currentState}}getMatrix(){return new Float64Array(this.matrix)}destroy(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.callbacks.clear()}clampScale(e){return Math.max(this.minZoom,Math.min(this.maxZoom,e))}updateMatrix(){this.matrix=n(this.currentState.scale,this.currentState.x,this.currentState.y)}scheduleUpdate(){this.pendingTransform=!0,this.rafId===null&&(this.rafId=requestAnimationFrame(e=>this.onFrame(e)))}onFrame(e){if(this.rafId=null,!this.pendingTransform)return;if(this.pendingTransform=!1,!this.enableAnimation){this.currentState={...this.targetState},this.updateMatrix(),this.notify();return}let t=this.lastFrameTime===0?16:e-this.lastFrameTime;this.lastFrameTime=e;let n=t/1e3;switch(this.animationMode){case`direct`:this.currentState={...this.targetState};break;case`ease-out`:{let e=1-(1-Math.min(1,t/this.animationDuration))**3;this.currentState.x=this.lerp(this.currentState.x,this.targetState.x,e),this.currentState.y=this.lerp(this.currentState.y,this.targetState.y,e),this.currentState.scale=this.lerp(this.currentState.scale,this.targetState.scale,e);break}case`exponential`:{let e=this.timeConstant/1e3,t=1-Math.exp(-n/e);this.currentState.x=this.lerp(this.currentState.x,this.targetState.x,t),this.currentState.y=this.lerp(this.currentState.y,this.targetState.y,t),this.currentState.scale=this.lerp(this.currentState.scale,this.targetState.scale,t);break}case`damped`:{let e=this.dampingRatio,t=this.naturalFrequency,r=t*t,i=r*(this.targetState.x-this.currentState.x)-2*e*t*this.velocity.x;this.velocity.x+=i*n,this.currentState.x+=this.velocity.x*n;let a=r*(this.targetState.y-this.currentState.y)-2*e*t*this.velocity.y;this.velocity.y+=a*n,this.currentState.y+=this.velocity.y*n;let o=r*(this.targetState.scale-this.currentState.scale)-2*e*t*this.velocity.scale;this.velocity.scale+=o*n,this.currentState.scale+=this.velocity.scale*n;break}}this.currentState.scale=this.clampScale(this.currentState.scale);let r=this.animationMode===`damped`?.01:1e-4,i=Math.abs(this.currentState.x-this.targetState.x)>r||Math.abs(this.currentState.y-this.targetState.y)>r||Math.abs(this.currentState.scale-this.targetState.scale)>r||this.animationMode===`damped`&&(Math.abs(this.velocity.x)>r||Math.abs(this.velocity.y)>r||Math.abs(this.velocity.scale)>r);this.updateMatrix(),this.notify(),i?this.scheduleUpdate():(this.currentState={...this.targetState},this.velocity={x:0,y:0,scale:0},this.lastFrameTime=0)}lerp(e,t,n){return e+(t-e)*n}notify(){let e={...this.currentState};this.callbacks.forEach(t=>t(e))}};function m(){return{lines:[],palette:{bgColor:`#f6f7f9`,tickColor:`#BABBBC`,labelColor:`#7D8694`,guideLineColor:`#51d6a9`,guideLineLockedColor:`#d4d7dc`,hoverBg:`#000`,hoverColor:`#fff`,borderColor:`#eeeeef`,shadowColor:`#e9f7fe`,guideLineStyle:`dashed`,guideLineWidth:1,labelEnabled:!0,labelPosition:`end`},snapConfig:{enabled:!0,threshold:5,strength:.5},showReferLine:!0}}function h(e,t){switch(t.type){case`addLine`:return{...e,lines:[...e.lines,t.line]};case`removeLine`:{let n=e.lines.filter(e=>e.id!==t.id);return n.length===e.lines.length?e:{...e,lines:n}}case`moveLine`:{let n=e.lines.findIndex(e=>e.id===t.id);if(n===-1)return e;let r=[...e.lines];return r[n]={...r[n],position:t.position},{...e,lines:r}}case`updateLine`:{let n=e.lines.findIndex(e=>e.id===t.id);if(n===-1)return e;let r=[...e.lines];return r[n]={...r[n],...t.updates},{...e,lines:r}}case`setLines`:return t.lines===e.lines?e:{...e,lines:t.lines};case`setPalette`:return{...e,palette:{...e.palette,...t.palette}};case`setSnapConfig`:return{...e,snapConfig:{...e.snapConfig,...t.config}};case`toggleReferLine`:return{...e,showReferLine:t.value===void 0?!e.showReferLine:t.value};default:return e}}var g=class{plugins=[];renderers=new Map;rendererOwners=new WeakMap;activeRenderer=null;api=null;setApi(e){this.api=e}register(e){if(this.plugins.push(e),this.sortPlugins(),e.registerRenderer){let t=e.registerRenderer();this.renderers.set(t.name,t.renderer),this.rendererOwners.set(e,t),this.activeRenderer===null&&(this.activeRenderer=t.name)}return()=>this.unregister(e)}unregister(e){let t=this.plugins.indexOf(e);t!==-1&&this.plugins.splice(t,1);let n=this.rendererOwners.get(e);n&&(this.renderers.delete(n.name),this.rendererOwners.delete(e),this.activeRenderer===n.name&&(this.activeRenderer=this.renderers.keys().next().value??null))}sortPlugins(){this.plugins.sort((e,t)=>(t.priority??0)-(e.priority??0))}getContext(e){if(!this.api)throw Error(`[PluginManager] api not set. Call setApi() before dispatching hooks.`);return{...e,api:this.api}}safeCall(e,t,n){try{e()}catch(e){console.error(`[PluginManager] Plugin "${t}" ${n} threw:`,e)}}async safeCallAsync(e,t,n){try{await e()}catch(e){console.error(`[PluginManager] Plugin "${t}" ${n} threw:`,e)}}async beforeZoom(e){let t=!1,n=()=>{t=!0},r=this.getContext({...e,cancel:n});for(let e of this.plugins)if(e.beforeZoom&&(await this.safeCallAsync(()=>e.beforeZoom(r),e.name,`beforeZoom`),t))return!1;return!0}afterZoom(e){let t=this.getContext(e);for(let e of this.plugins)e.afterZoom&&this.safeCall(()=>e.afterZoom(t),e.name,`afterZoom`)}async beforePan(e){let t=!1,n=()=>{t=!0},r=this.getContext({...e,cancel:n});for(let e of this.plugins)if(e.beforePan&&(await this.safeCallAsync(()=>e.beforePan(r),e.name,`beforePan`),t))return!1;return!0}afterPan(e){let t=this.getContext(e);for(let e of this.plugins)e.afterPan&&this.safeCall(()=>e.afterPan(t),e.name,`afterPan`)}onSnap(e){let t=this.getContext(e);for(let e of this.plugins)e.onSnap&&this.safeCall(()=>e.onSnap(t),e.name,`onSnap`)}onLineCreate(e){let t=this.getContext(e);for(let e of this.plugins)e.onLineCreate&&this.safeCall(()=>e.onLineCreate(t),e.name,`onLineCreate`)}onLineDelete(e){let t=this.getContext(e);for(let e of this.plugins)e.onLineDelete&&this.safeCall(()=>e.onLineDelete(t),e.name,`onLineDelete`)}onLineMove(e){let t=this.getContext(e);for(let e of this.plugins)e.onLineMove&&this.safeCall(()=>e.onLineMove(t),e.name,`onLineMove`)}setActiveRenderer(e){return this.renderers.has(e)?(this.activeRenderer=e,!0):!1}getActiveRenderer(){return this.activeRenderer?this.renderers.get(this.activeRenderer)??null:null}getRendererNames(){return Array.from(this.renderers.keys())}hasRenderer(e){return this.renderers.has(e)}clear(){this.plugins=[],this.renderers.clear(),this.rendererOwners=new WeakMap,this.activeRenderer=null}},_=[{maxScale:.2,interval:500,subdivisions:5,showLabel:!0,formatLabel:e=>`${Math.round(e/1e3)}k`},{maxScale:.5,interval:200,subdivisions:4,showLabel:!0},{maxScale:1,interval:100,subdivisions:5,showLabel:!0},{maxScale:2,interval:50,subdivisions:5,showLabel:!0},{maxScale:5,interval:20,subdivisions:4,showLabel:!0},{maxScale:10,interval:10,subdivisions:5,showLabel:!0},{maxScale:1/0,interval:5,subdivisions:5,showLabel:!0}],v=1.1,y=.9;function b(e){let t=_.findIndex(t=>e<t.maxScale);return _[t===-1?_.length-1:t]}function x(e,t){let n=e;for(;n<_.length-1&&t>=_[n].maxScale*v;)n++;for(;n>0&&t<_[n-1].maxScale*y;)n--;return n}function S(e){let{scale:t,offset:n,viewportSize:r,thick:i,canvasSize:a,showMinorTicks:o}=e;if(r<=0||t<=0)return[];let s=b(t),c=s.interval,l=s.subdivisions,u=c/l,d=-n/t,f=(r-n)/t,p=r/t,m=d-p*.5,h=f+p*.5,g=Math.floor(m/c)*c,_=[],v=a??1/0;for(let e=g;e<=h;e+=c){let a=e*t+n;if(a>=-i&&a<=r+i){let t=e>=0&&e<=v&&(v===1/0||e===v||v-e>=c);_.push({position:a,length:i*.6,isMajor:!0,label:t?s.formatLabel?s.formatLabel(e):`${Math.round(e)}`:void 0,value:e})}if(o)for(let a=1;a<l;a++){let o=e+a*u,s=o*t+n;s>=-i&&s<=r+i&&_.push({position:s,length:i*.3,isMajor:!1,value:o})}}if(v!==1/0&&v>0&&!_.some(e=>e.isMajor&&e.value===v)){let e=v*t+n;e>=-i&&e<=r+i*2&&(_.push({position:e,length:i*.6,isMajor:!0,label:`${Math.round(v)}`,value:v}),_.sort((e,t)=>e.position-t.position))}return _}var C=0,w=0;function T(){return`line-${++C}-${Date.now()}`}function E(){return`canvas-${++w}-${Date.now()}`}function D(e){if(!e)return[];let t=[],n=0;for(let r of e.h)t.push({id:`h-${n++}-${Date.now()}`,orientation:`h`,position:r,visible:!0,locked:!1});for(let r of e.v)t.push({id:`v-${n++}-${Date.now()}`,orientation:`v`,position:r,visible:!0,locked:!1});return t}function O(e){return{h:e.filter(e=>e.orientation===`h`).map(e=>e.position),v:e.filter(e=>e.orientation===`v`).map(e=>e.position)}}function k(e,t){return`${e?`X`:`Y`}: ${Math.round(t)}`}function A(e,t,n,r,i){let a=e.position*t+n,o=e.locked?`default`:r?`ns-resize`:`ew-resize`;return r?{left:`${a}px`,top:`0`,height:`100vh`,width:`1px`,borderLeft:`1px dashed ${i}`,cursor:o}:{top:`${a}px`,left:`0`,width:`100vw`,height:`1px`,borderBottom:`1px dashed ${i}`,cursor:o}}function j(e,t,n){return(e-t)/n}function M(e,t,n){return e*n+t}function N(e){let{worldPos:t,majorTicks:n,thresholdWorld:r}=e;if(n.length===0)return null;let i=null,a=1/0;for(let e of n){let n=Math.abs(t-e.value);n<r&&n<a&&(a=n,i=e.value)}return i}function P(e){let{startMouse:t,startPos:n,currentMouse:r,scale:i,majorTicks:a,snapThresholdWorld:o}=e,s=n+(r-t)/i,c=N({worldPos:s,majorTicks:a,thresholdWorld:o});return c!==null&&(s=c),Math.round(s)}var F=class{state;listeners=new Set;constructor(e=[]){this.state=m(),e.length>0&&(this.state=h(this.state,{type:`setLines`,lines:e}))}dispatch(e){this.state=h(this.state,e),this.listeners.forEach(e=>e(this.state))}onUpdate(e){return this.listeners.add(e),()=>this.listeners.delete(e)}getState(){return this.state}getLines(){return this.state.lines}addLine(e){let t={...e,id:T()};return this.dispatch({type:`addLine`,line:t}),t}removeLine(e){return this.state.lines.some(t=>t.id===e)?(this.dispatch({type:`removeLine`,id:e}),!0):!1}updateLine(e,t){return this.state.lines.some(t=>t.id===e)?(this.dispatch({type:`updateLine`,id:e,updates:t}),!0):!1}moveLine(e,t){return this.updateLine(e,{position:t})}toggleLock(e){let t=this.state.lines.find(t=>t.id===e);return t?this.updateLine(e,{locked:!t.locked}):!1}toggleVisible(e){let t=this.state.lines.find(t=>t.id===e);return t?this.updateLine(e,{visible:!t.visible}):!1}clear(){this.dispatch({type:`setLines`,lines:[]})}setLines(e){this.dispatch({type:`setLines`,lines:[...e]})}},I={"A4 Portrait":{name:`A4 纵向`,width:794,height:1123},"A4 Landscape":{name:`A4 横向`,width:1123,height:794},"Web 1920":{name:`Web 1920`,width:1920,height:1080},"Web 1440":{name:`Web 1440`,width:1440,height:900},"Mobile 375":{name:`Mobile 375`,width:375,height:812},"Mobile 414":{name:`Mobile 414`,width:414,height:896}},L=class{canvases=[];activeId=``;templates=new Map;globalLines=[];listeners=new Set;constructor(e=[]){for(let[e,t]of Object.entries(I))this.templates.set(e,t);for(let t of e)this.addCanvas(t)}notify(){let e={canvases:[...this.canvases],activeId:this.activeId};this.listeners.forEach(t=>t(e))}onUpdate(e){return this.listeners.add(e),()=>this.listeners.delete(e)}getState(){return{canvases:[...this.canvases],activeId:this.activeId}}get activeCanvas(){return this.canvases.find(e=>e.id===this.activeId)??null}addCanvas(e){let t=e?.id??E(),n={id:t,name:e?.name??`画布 ${this.canvases.length+1}`,width:e?.width??1920,height:e?.height??1080,scale:e?.scale??1,offsetX:e?.offsetX??0,offsetY:e?.offsetY??0,lines:D(e?.lines),thumbnail:null};return this.canvases=[...this.canvases,n],this.activeId||=t,this.notify(),t}removeCanvas(e){let t=this.canvases.findIndex(t=>t.id===e);if(t===-1)return;let n=[...this.canvases];n.splice(t,1),this.canvases=n,this.activeId===e&&n.length>0&&(this.activeId=n[0].id),this.notify()}switchCanvas(e){if(!this.canvases.some(t=>t.id===e))return;let t=this.activeCanvas;t&&t.id!==e&&this.captureThumbnail(t.id),this.activeId=e;let n=this.canvases.find(t=>t.id===e);n&&(n.thumbnail=null),this.notify()}updateCanvasState(e,t){this.canvases=this.canvases.map(n=>n.id===e?{...n,...t}:n),this.notify()}updateCanvasLines(e,t){this.canvases=this.canvases.map(n=>n.id===e?{...n,lines:[...t]}:n),this.notify()}registerTemplate(e,t){this.templates.set(e,t)}getTemplateNames(){return Array.from(this.templates.keys())}applyTemplate(e){let t=this.templates.get(e);return t?this.addCanvas(t):null}setGlobalLines(e){this.globalLines=D(e)}getGlobalLines(){return[...this.globalLines]}getMergedLines(e){let t=this.canvases.find(t=>t.id===e);return t?[...this.globalLines,...t.lines]:[]}exportCanvas(e){let t=this.canvases.find(t=>t.id===e);return t?{...t}:null}importCanvas(e){this.canvases.some(t=>t.id===e.id)?this.canvases=this.canvases.map(t=>t.id===e.id?{...e}:t):this.canvases=[...this.canvases,{...e}],this.notify()}captureThumbnail(e){let t=this.canvases.find(t=>t.id===e);t&&(t.thumbnail=`data:image/png;base64,placeholder`)}},R=class{options;constructor(e){this.options=e}snap(e,t){let n=this.options.scale;if(n<=0)return null;let r=this.collectCandidates(e,t);if(r.length===0)return null;let i=e*n,a=this.options.threshold,o=null,s=1/0;for(let e of r){let t=e.position*n,r=Math.abs(i-t);r<=a&&r<s&&(s=r,o=e)}if(!o)return null;let c=this.options.strength??.5;return{position:e*(1-c)+o.position*c,target:o,original:e}}collectCandidates(e,t){let n=[];if(this.options.tickTargets)for(let e of this.options.tickTargets)n.push({type:`tick`,position:e,priority:1});if(this.options.guideLineTargets)for(let e of this.options.guideLineTargets)n.push({type:`guide-line`,position:e,priority:2});if(this.options.customTargets)for(let e of this.options.customTargets)n.push({type:`custom`,position:e,priority:3});if(this.options.gridSize&&this.options.gridSize>0){let t=Math.round(e/this.options.gridSize)*this.options.gridSize;n.push({type:`grid`,position:t,priority:4})}if(this.options.enableEquidistant&&this.options.lines){let e=z(this.options.lines.filter(e=>e.orientation===t&&e.visible!==!1).map(e=>e.position).sort((e,t)=>e-t));for(let t of e)n.push({type:`equidistant`,position:t,priority:5})}if(this.options.customRules&&this.options.lines&&this.options.viewportSize){let r={direction:t,position:e,scale:this.options.scale,lines:this.options.lines,viewportSize:this.options.viewportSize};for(let e of this.options.customRules){let t=e.getTargets(r);for(let r of t)n.push({...r,priority:e.priority})}}return n}};function z(e){if(e.length<2)return[];let t=[];for(let n=1;n<e.length;n++){let r=e[n]-e[n-1],i=e[n]+r;e.includes(i)||t.push(i);let a=e[n-1]-r;e.includes(a)||t.push(a)}return t}var B=class{options;constructor(e){this.options=e}getState(){let e=Math.min(this.options.width/this.options.contentWidth,this.options.height/this.options.contentHeight),t=this.options.contentWidth*e,n=this.options.contentHeight*e,r=(this.options.width-t)/2,i=(this.options.height-n)/2,a=r+-this.options.viewportX/this.options.scale*e,o=i+-this.options.viewportY/this.options.scale*e,s=this.options.viewportWidth/this.options.scale*e,c=this.options.viewportHeight/this.options.scale*e;return{miniScale:e,contentOffset:{x:r,y:i},viewportRect:{left:a,top:o,width:s,height:c}}}clampTransform(e,t){let n=this.options.contentWidth*this.options.scale,r=this.options.contentHeight*this.options.scale,i=e,a=t;return i=n<=this.options.viewportWidth?(this.options.viewportWidth-n)/2:Math.min(0,Math.max(this.options.viewportWidth-n,e)),a=r<=this.options.viewportHeight?(this.options.viewportHeight-r)/2:Math.min(0,Math.max(this.options.viewportHeight-r,t)),{x:i,y:a}}canPan(){return this.options.contentWidth*this.options.scale>this.options.viewportWidth||this.options.contentHeight*this.options.scale>this.options.viewportHeight}clickAt(e,t,n,r){let i=this.getState(),a=(e-n-i.contentOffset.x)/i.miniScale,o=(t-r-i.contentOffset.y)/i.miniScale,s=this.options.viewportWidth/2-a*this.options.scale,c=this.options.viewportHeight/2-o*this.options.scale;return this.clampTransform(s,c)}startDrag(e,t,n,r){return new V(this,e,t,n,r)}},V=class{engine;startViewportX;startViewportY;startMinimapLeft;startMinimapTop;ratio;constructor(e,t,n,r,i){this.engine=e,this.startViewportX=t,this.startViewportY=n,this.startMinimapLeft=r,this.startMinimapTop=i,this.ratio=e.options.scale/e.getState().miniScale}move(e,t){let n=this.startViewportX-e*this.ratio,r=this.startViewportY-t*this.ratio,i=this.engine.clampTransform(n,r),a=(this.startViewportX-i.x)/this.ratio,o=(this.startViewportY-i.y)/this.ratio,s=this.engine.getState();return{targetX:i.x,targetY:i.y,dragRect:{left:this.startMinimapLeft+a,top:this.startMinimapTop+o,width:s.viewportRect.width,height:s.viewportRect.height}}}end(e,t){let n=this.startViewportX-e*this.ratio,r=this.startViewportY-t*this.ratio,i=this.engine.clampTransform(n,r);return{x:i.x,y:i.y}}};e.BUILTIN_TEMPLATES=I,e.CanvasManager=L,e.LineManager=F,e.MinimapDragSession=V,e.MinimapEngine=B,e.PluginManager=g,e.SnapEngine=R,e.TICK_CONFIGS=_,e.TransformEngine=p,e.applyHysteresis=x,e.batchToScreen=d,e.batchToWorld=u,e.computeDraggedLinePosition=P,e.computeEquidistantTargets=z,e.computeLineStyle=A,e.computeScaleMarks=S,e.createDefaultState=m,e.createMatrix=t,e.decompose=a,e.equals=s,e.exportLines=O,e.fitRect=f,e.formatLineLabel=k,e.fromTransform=n,e.generateCanvasId=E,e.generateLineId=T,e.getTickConfig=b,e.importLines=D,e.invert=i,e.multiply=r,e.produceState=h,e.screenToWorld=j,e.snapToNearestTick=N,e.toCSSString=o,e.toScreenPoint=l,e.toWorldPoint=c,e.worldToScreen=M});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { GuideLine } from '../types';
|
|
2
|
+
export interface CanvasConfig {
|
|
3
|
+
id?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
scale?: number;
|
|
8
|
+
offsetX?: number;
|
|
9
|
+
offsetY?: number;
|
|
10
|
+
lines?: {
|
|
11
|
+
h: number[];
|
|
12
|
+
v: number[];
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface CanvasState {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
scale: number;
|
|
21
|
+
offsetX: number;
|
|
22
|
+
offsetY: number;
|
|
23
|
+
lines: GuideLine[];
|
|
24
|
+
thumbnail?: string | null;
|
|
25
|
+
}
|
|
26
|
+
export type CanvasTemplate = Omit<CanvasConfig, 'id'>;
|
|
27
|
+
export declare const BUILTIN_TEMPLATES: Record<string, CanvasTemplate>;
|
|
28
|
+
export interface CanvasManagerState {
|
|
29
|
+
canvases: CanvasState[];
|
|
30
|
+
activeId: string;
|
|
31
|
+
}
|
|
32
|
+
export declare class CanvasManager {
|
|
33
|
+
private canvases;
|
|
34
|
+
private activeId;
|
|
35
|
+
private templates;
|
|
36
|
+
private globalLines;
|
|
37
|
+
private listeners;
|
|
38
|
+
constructor(initialCanvases?: CanvasConfig[]);
|
|
39
|
+
private notify;
|
|
40
|
+
onUpdate(cb: (state: CanvasManagerState) => void): () => void;
|
|
41
|
+
getState(): CanvasManagerState;
|
|
42
|
+
get activeCanvas(): CanvasState | null;
|
|
43
|
+
addCanvas(config?: Partial<CanvasConfig>): string;
|
|
44
|
+
removeCanvas(canvasId: string): void;
|
|
45
|
+
switchCanvas(canvasId: string): void;
|
|
46
|
+
updateCanvasState(canvasId: string, updates: Partial<Pick<CanvasState, 'scale' | 'offsetX' | 'offsetY' | 'name'>>): void;
|
|
47
|
+
updateCanvasLines(canvasId: string, lines: GuideLine[]): void;
|
|
48
|
+
registerTemplate(name: string, template: CanvasTemplate): void;
|
|
49
|
+
getTemplateNames(): string[];
|
|
50
|
+
applyTemplate(name: string): string | null;
|
|
51
|
+
setGlobalLines(lines: {
|
|
52
|
+
h: number[];
|
|
53
|
+
v: number[];
|
|
54
|
+
}): void;
|
|
55
|
+
getGlobalLines(): GuideLine[];
|
|
56
|
+
getMergedLines(canvasId: string): GuideLine[];
|
|
57
|
+
exportCanvas(canvasId: string): CanvasState | null;
|
|
58
|
+
importCanvas(snapshot: CanvasState): void;
|
|
59
|
+
private captureThumbnail;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=canvas-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-manager.d.ts","sourceRoot":"","sources":["../../src/managers/canvas-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAIzC,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;AAErD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAO5D,CAAA;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,SAAS,CAAiD;gBAEtD,eAAe,GAAE,YAAY,EAAO;IAShD,OAAO,CAAC,MAAM;IAQd,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,MAAM,IAAI;IAK7D,QAAQ,IAAI,kBAAkB;IAI9B,IAAI,YAAY,IAAI,WAAW,GAAG,IAAI,CAErC;IAED,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,MAAM;IAqBjD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAYpC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAcpC,iBAAiB,CACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC,GAC5E,IAAI;IAKP,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI;IAK7D,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI;IAI9D,gBAAgB,IAAI,MAAM,EAAE;IAI5B,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAM1C,cAAc,CAAC,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI;IAIzD,cAAc,IAAI,SAAS,EAAE;IAI7B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAM7C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAKlD,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAUzC,OAAO,CAAC,gBAAgB;CAMzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SketchRulerPlugin, RulerRenderer, BeforeZoomContext, AfterZoomContext, BeforePanContext, AfterPanContext, OnSnapContext, OnLineContext, OnLineMoveContext, PluginApi } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* PluginManager - 插件生命周期管理与钩子分发
|
|
4
|
+
* M4 W18:支持 before/after 类钩子、自定义渲染器注册、优先级、错误隔离
|
|
5
|
+
*/
|
|
6
|
+
export declare class PluginManager {
|
|
7
|
+
private plugins;
|
|
8
|
+
private renderers;
|
|
9
|
+
private rendererOwners;
|
|
10
|
+
private activeRenderer;
|
|
11
|
+
private api;
|
|
12
|
+
setApi(api: PluginApi): void;
|
|
13
|
+
register(plugin: SketchRulerPlugin): () => void;
|
|
14
|
+
unregister(plugin: SketchRulerPlugin): void;
|
|
15
|
+
private sortPlugins;
|
|
16
|
+
private getContext;
|
|
17
|
+
private safeCall;
|
|
18
|
+
private safeCallAsync;
|
|
19
|
+
beforeZoom(ctx: BeforeZoomContext): Promise<boolean>;
|
|
20
|
+
afterZoom(ctx: AfterZoomContext): void;
|
|
21
|
+
beforePan(ctx: BeforePanContext): Promise<boolean>;
|
|
22
|
+
afterPan(ctx: AfterPanContext): void;
|
|
23
|
+
onSnap(ctx: OnSnapContext): void;
|
|
24
|
+
onLineCreate(ctx: OnLineContext): void;
|
|
25
|
+
onLineDelete(ctx: OnLineContext): void;
|
|
26
|
+
onLineMove(ctx: OnLineMoveContext): void;
|
|
27
|
+
setActiveRenderer(name: string): boolean;
|
|
28
|
+
getActiveRenderer(): RulerRenderer | null;
|
|
29
|
+
getRendererNames(): string[];
|
|
30
|
+
hasRenderer(name: string): boolean;
|
|
31
|
+
clear(): void;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=plugin-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-manager.d.ts","sourceRoot":"","sources":["../../src/plugins/plugin-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,SAAS,EACV,MAAM,UAAU,CAAA;AAOjB;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,cAAc,CAAyD;IAC/E,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,GAAG,CAAyB;IAEpC,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI;IAI5B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAiB/C,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAgB3C,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,QAAQ;YAQF,aAAa;IAYrB,UAAU,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAoB1D,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAShC,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBxD,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IASpC,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAShC,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAStC,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAStC,UAAU,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI;IAWxC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQxC,iBAAiB,IAAI,aAAa,GAAG,IAAI;IAKzC,gBAAgB,IAAI,MAAM,EAAE;IAI5B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIlC,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ScaleMark } from '../types';
|
|
2
|
+
import { TICK_CONFIGS, getTickConfig, applyHysteresis } from './tick-config';
|
|
3
|
+
export interface ComputeScaleOptions {
|
|
4
|
+
scale: number;
|
|
5
|
+
offset: number;
|
|
6
|
+
viewportSize: number;
|
|
7
|
+
thick: number;
|
|
8
|
+
vertical?: boolean;
|
|
9
|
+
canvasSize?: number;
|
|
10
|
+
showMinorTicks?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 计算标尺刻度标记
|
|
14
|
+
* 纯函数,零框架依赖
|
|
15
|
+
*/
|
|
16
|
+
export declare function computeScaleMarks(options: ComputeScaleOptions): ScaleMark[];
|
|
17
|
+
export { TICK_CONFIGS, getTickConfig, applyHysteresis };
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scale/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE5E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,EAAE,CAuF3E;AAED,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TickConfig } from '../types';
|
|
2
|
+
/** 刻度配置表,按 maxScale 升序排列 */
|
|
3
|
+
export declare const TICK_CONFIGS: Array<TickConfig & {
|
|
4
|
+
maxScale: number;
|
|
5
|
+
}>;
|
|
6
|
+
/** 根据缩放级别获取刻度配置 */
|
|
7
|
+
export declare function getTickConfig(scale: number): TickConfig;
|
|
8
|
+
/**
|
|
9
|
+
* 应用滞后带(Hysteresis)机制,避免临界振荡
|
|
10
|
+
* @param currentIdx 当前配置索引
|
|
11
|
+
* @param scale 当前缩放值
|
|
12
|
+
* @returns 新的配置索引
|
|
13
|
+
*/
|
|
14
|
+
export declare function applyHysteresis(currentIdx: number, scale: number): number;
|
|
15
|
+
//# sourceMappingURL=tick-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tick-config.d.ts","sourceRoot":"","sources":["../../src/scale/tick-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C,4BAA4B;AAC5B,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,UAAU,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAcjE,CAAA;AAKD,mBAAmB;AACnB,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAczE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { GuideLine } from '../types';
|
|
2
|
+
export interface SnapTarget {
|
|
3
|
+
type: 'tick' | 'guide-line' | 'custom' | 'grid' | 'equidistant';
|
|
4
|
+
position: number;
|
|
5
|
+
priority: number;
|
|
6
|
+
}
|
|
7
|
+
export interface SnapResult {
|
|
8
|
+
position: number;
|
|
9
|
+
target: SnapTarget;
|
|
10
|
+
original: number;
|
|
11
|
+
}
|
|
12
|
+
export interface SnapRule {
|
|
13
|
+
id: string;
|
|
14
|
+
priority: number;
|
|
15
|
+
getTargets: (context: SnapContext) => SnapTarget[];
|
|
16
|
+
}
|
|
17
|
+
export interface SnapContext {
|
|
18
|
+
direction: 'h' | 'v';
|
|
19
|
+
position: number;
|
|
20
|
+
scale: number;
|
|
21
|
+
lines: GuideLine[];
|
|
22
|
+
viewportSize: {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface SnapEngineOptions {
|
|
28
|
+
threshold: number;
|
|
29
|
+
scale: number;
|
|
30
|
+
tickTargets?: number[];
|
|
31
|
+
guideLineTargets?: number[];
|
|
32
|
+
customTargets?: number[];
|
|
33
|
+
strength?: number;
|
|
34
|
+
gridSize?: number;
|
|
35
|
+
enableEquidistant?: boolean;
|
|
36
|
+
customRules?: SnapRule[];
|
|
37
|
+
lines?: GuideLine[];
|
|
38
|
+
viewportSize?: {
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export declare class SnapEngine {
|
|
44
|
+
private options;
|
|
45
|
+
constructor(options: SnapEngineOptions);
|
|
46
|
+
snap(position: number, direction: 'h' | 'v'): SnapResult | null;
|
|
47
|
+
private collectCandidates;
|
|
48
|
+
}
|
|
49
|
+
export declare function computeEquidistantTargets(positions: number[]): number[];
|
|
50
|
+
//# sourceMappingURL=snap-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snap-engine.d.ts","sourceRoot":"","sources":["../../src/snap/snap-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAA;IAC/D,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,UAAU,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,UAAU,EAAE,CAAA;CACnD;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,GAAG,GAAG,GAAG,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAChD;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAA;IACnB,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CACjD;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,iBAAiB;IAE9C,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,UAAU,GAAG,IAAI;IAkC/D,OAAO,CAAC,iBAAiB;CAwD1B;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAiBvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAChE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RulerState } from './ruler-state';
|
|
2
|
+
import { GuideLine } from '../types';
|
|
3
|
+
export declare class LineManager {
|
|
4
|
+
private state;
|
|
5
|
+
private listeners;
|
|
6
|
+
constructor(initialLines?: GuideLine[]);
|
|
7
|
+
private dispatch;
|
|
8
|
+
onUpdate(cb: (state: RulerState) => void): () => void;
|
|
9
|
+
getState(): RulerState;
|
|
10
|
+
getLines(): GuideLine[];
|
|
11
|
+
addLine(line: Omit<GuideLine, 'id'>): GuideLine;
|
|
12
|
+
removeLine(id: string): boolean;
|
|
13
|
+
updateLine(id: string, updates: Partial<Omit<GuideLine, 'id'>>): boolean;
|
|
14
|
+
moveLine(id: string, position: number): boolean;
|
|
15
|
+
toggleLock(id: string): boolean;
|
|
16
|
+
toggleVisible(id: string): boolean;
|
|
17
|
+
clear(): void;
|
|
18
|
+
setLines(lines: GuideLine[]): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=line-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-manager.d.ts","sourceRoot":"","sources":["../../src/state/line-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGzC,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,SAAS,CAAyC;gBAE9C,YAAY,GAAE,SAAS,EAAO;IAO1C,OAAO,CAAC,QAAQ;IAKhB,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAKrD,QAAQ,IAAI,UAAU;IAItB,QAAQ,IAAI,SAAS,EAAE;IAIvB,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,SAAS;IAM/C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAO/B,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,OAAO;IAOxE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI/C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAM/B,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAMlC,KAAK,IAAI,IAAI;IAIb,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI;CAGnC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { GuideLine, RulerPalette, SnapConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* RulerState - 标尺全局状态快照
|
|
4
|
+
* M1 基础版:包含参考线、配色、吸附配置
|
|
5
|
+
*/
|
|
6
|
+
export interface RulerState {
|
|
7
|
+
lines: GuideLine[];
|
|
8
|
+
palette: RulerPalette;
|
|
9
|
+
snapConfig: SnapConfig;
|
|
10
|
+
showReferLine: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** 状态变更动作联合类型 */
|
|
13
|
+
export type RulerAction = {
|
|
14
|
+
type: 'addLine';
|
|
15
|
+
line: GuideLine;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'removeLine';
|
|
18
|
+
id: string;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'moveLine';
|
|
21
|
+
id: string;
|
|
22
|
+
position: number;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'updateLine';
|
|
25
|
+
id: string;
|
|
26
|
+
updates: Partial<Omit<GuideLine, 'id'>>;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'setLines';
|
|
29
|
+
lines: GuideLine[];
|
|
30
|
+
} | {
|
|
31
|
+
type: 'setPalette';
|
|
32
|
+
palette: Partial<RulerPalette>;
|
|
33
|
+
} | {
|
|
34
|
+
type: 'setSnapConfig';
|
|
35
|
+
config: Partial<SnapConfig>;
|
|
36
|
+
} | {
|
|
37
|
+
type: 'toggleReferLine';
|
|
38
|
+
value?: boolean;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* 创建默认状态
|
|
42
|
+
*/
|
|
43
|
+
export declare function createDefaultState(): RulerState;
|
|
44
|
+
/**
|
|
45
|
+
* produceState - 纯函数状态更新
|
|
46
|
+
* 返回新状态,结构共享未变更部分
|
|
47
|
+
*/
|
|
48
|
+
export declare function produceState(current: RulerState, action: RulerAction): RulerState;
|
|
49
|
+
//# sourceMappingURL=ruler-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruler-state.d.ts","sourceRoot":"","sources":["../../src/state/ruler-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAEnE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,UAAU,CAAA;IACtB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,iBAAiB;AACjB,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAEhD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CAyB/C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,UAAU,CA4DjF"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 框架无关的纯类型定义
|
|
3
|
+
* 供 @sketch-ruler/core、@sketch-ruler/canvas、vue3-sketch-ruler、react-sketch-ruler 共用
|
|
4
|
+
*/
|
|
5
|
+
export interface GuideLine {
|
|
6
|
+
id: string;
|
|
7
|
+
orientation: 'h' | 'v';
|
|
8
|
+
position: number;
|
|
9
|
+
locked?: boolean;
|
|
10
|
+
visible?: boolean;
|
|
11
|
+
label?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RulerPalette {
|
|
14
|
+
bgColor: string;
|
|
15
|
+
tickColor: string;
|
|
16
|
+
labelColor: string;
|
|
17
|
+
guideLineColor: string;
|
|
18
|
+
guideLineLockedColor: string;
|
|
19
|
+
hoverBg: string;
|
|
20
|
+
hoverColor: string;
|
|
21
|
+
borderColor: string;
|
|
22
|
+
shadowColor?: string;
|
|
23
|
+
/** 参考线样式:solid | dashed | dotted */
|
|
24
|
+
guideLineStyle?: 'solid' | 'dashed' | 'dotted';
|
|
25
|
+
/** 参考线宽度 */
|
|
26
|
+
guideLineWidth?: number;
|
|
27
|
+
/** 是否显示参考线标签 */
|
|
28
|
+
labelEnabled?: boolean;
|
|
29
|
+
/** 标签位置 */
|
|
30
|
+
labelPosition?: 'start' | 'center' | 'end';
|
|
31
|
+
/** 标签格式化函数 */
|
|
32
|
+
labelFormat?: (value: number) => string;
|
|
33
|
+
}
|
|
34
|
+
export interface SnapConfig {
|
|
35
|
+
enabled: boolean;
|
|
36
|
+
threshold: number;
|
|
37
|
+
strength: number;
|
|
38
|
+
}
|
|
39
|
+
export interface TickConfig {
|
|
40
|
+
/** 主刻度间隔(世界坐标) */
|
|
41
|
+
interval: number;
|
|
42
|
+
/** 次刻度分割数 */
|
|
43
|
+
subdivisions: number;
|
|
44
|
+
/** 是否显示标签 */
|
|
45
|
+
showLabel: boolean;
|
|
46
|
+
/** 标签格式化函数 */
|
|
47
|
+
formatLabel?: (value: number) => string;
|
|
48
|
+
}
|
|
49
|
+
export interface ScaleMark {
|
|
50
|
+
/** 屏幕坐标位置 */
|
|
51
|
+
position: number;
|
|
52
|
+
/** 刻度长度(像素) */
|
|
53
|
+
length: number;
|
|
54
|
+
/** 是否主刻度 */
|
|
55
|
+
isMajor: boolean;
|
|
56
|
+
/** 标签文本(仅主刻度) */
|
|
57
|
+
label?: string;
|
|
58
|
+
/** 对应的世界坐标值 */
|
|
59
|
+
value: number;
|
|
60
|
+
}
|
|
61
|
+
export interface Point {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
}
|
|
65
|
+
export interface SnapTarget {
|
|
66
|
+
id: string;
|
|
67
|
+
position: number;
|
|
68
|
+
orientation: 'h' | 'v';
|
|
69
|
+
priority: number;
|
|
70
|
+
}
|
|
71
|
+
export interface BeforeZoomContext {
|
|
72
|
+
from: number;
|
|
73
|
+
to: number;
|
|
74
|
+
center: Point;
|
|
75
|
+
cancel: () => void;
|
|
76
|
+
}
|
|
77
|
+
export interface BeforePanContext {
|
|
78
|
+
offset: Point;
|
|
79
|
+
delta: Point;
|
|
80
|
+
cancel: () => void;
|
|
81
|
+
}
|
|
82
|
+
export interface AfterPanContext {
|
|
83
|
+
offset: Point;
|
|
84
|
+
delta: Point;
|
|
85
|
+
}
|
|
86
|
+
export interface AfterZoomContext {
|
|
87
|
+
from: number;
|
|
88
|
+
to: number;
|
|
89
|
+
center: Point;
|
|
90
|
+
}
|
|
91
|
+
export interface OnSnapContext {
|
|
92
|
+
line: GuideLine;
|
|
93
|
+
targets: SnapTarget[];
|
|
94
|
+
applied: SnapTarget | null;
|
|
95
|
+
}
|
|
96
|
+
export interface OnLineContext {
|
|
97
|
+
line: GuideLine;
|
|
98
|
+
}
|
|
99
|
+
export interface OnLineMoveContext extends OnLineContext {
|
|
100
|
+
from: number;
|
|
101
|
+
to: number;
|
|
102
|
+
}
|
|
103
|
+
export interface TickInfo {
|
|
104
|
+
position: number;
|
|
105
|
+
isMajor: boolean;
|
|
106
|
+
value: number;
|
|
107
|
+
}
|
|
108
|
+
export interface LabelInfo {
|
|
109
|
+
text: string;
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
align: 'left' | 'center' | 'right';
|
|
113
|
+
}
|
|
114
|
+
export interface RenderConfig {
|
|
115
|
+
scale: number;
|
|
116
|
+
offset: number;
|
|
117
|
+
thick: number;
|
|
118
|
+
width: number;
|
|
119
|
+
height: number;
|
|
120
|
+
palette: Record<string, string>;
|
|
121
|
+
}
|
|
122
|
+
export interface RulerRenderer {
|
|
123
|
+
renderTicks(ctx: CanvasRenderingContext2D, ticks: TickInfo[], config: RenderConfig): void;
|
|
124
|
+
renderLabels(ctx: CanvasRenderingContext2D, labels: LabelInfo[], config: RenderConfig): void;
|
|
125
|
+
}
|
|
126
|
+
/** 插件可访问的只读状态与可控 API */
|
|
127
|
+
export interface PluginApi {
|
|
128
|
+
getState: () => {
|
|
129
|
+
scale: number;
|
|
130
|
+
offset: Point;
|
|
131
|
+
lines: GuideLine[];
|
|
132
|
+
};
|
|
133
|
+
zoomBy: (dScale: number, originX: number, originY: number) => void;
|
|
134
|
+
zoomTo: (scale: number, originX: number, originY: number) => void;
|
|
135
|
+
panBy: (dx: number, dy: number) => void;
|
|
136
|
+
setTransform: (t: {
|
|
137
|
+
scale?: number;
|
|
138
|
+
x?: number;
|
|
139
|
+
y?: number;
|
|
140
|
+
}) => void;
|
|
141
|
+
}
|
|
142
|
+
/** 所有插件钩子上下文的基类型 */
|
|
143
|
+
export interface PluginContext {
|
|
144
|
+
api: PluginApi;
|
|
145
|
+
}
|
|
146
|
+
export interface SketchRulerPlugin {
|
|
147
|
+
name: string;
|
|
148
|
+
version?: string;
|
|
149
|
+
/** 优先级,数字越大越先执行。默认 0 */
|
|
150
|
+
priority?: number;
|
|
151
|
+
beforeZoom?: (ctx: BeforeZoomContext & PluginContext) => void | Promise<void>;
|
|
152
|
+
afterZoom?: (ctx: AfterZoomContext & PluginContext) => void;
|
|
153
|
+
beforePan?: (ctx: BeforePanContext & PluginContext) => void | Promise<void>;
|
|
154
|
+
afterPan?: (ctx: AfterPanContext & PluginContext) => void;
|
|
155
|
+
onSnap?: (ctx: OnSnapContext & PluginContext) => void;
|
|
156
|
+
onLineCreate?: (ctx: OnLineContext & PluginContext) => void;
|
|
157
|
+
onLineDelete?: (ctx: OnLineContext & PluginContext) => void;
|
|
158
|
+
onLineMove?: (ctx: OnLineMoveContext & PluginContext) => void;
|
|
159
|
+
registerRenderer?: () => {
|
|
160
|
+
name: string;
|
|
161
|
+
renderer: RulerRenderer;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-utils.d.ts","sourceRoot":"","sources":["../../src/utils/id-utils.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { GuideLine } from '../types';
|
|
2
|
+
export interface LineType {
|
|
3
|
+
h: number[];
|
|
4
|
+
v: number[];
|
|
5
|
+
}
|
|
6
|
+
export declare function importLines(lines?: LineType): GuideLine[];
|
|
7
|
+
export declare function exportLines(lines: GuideLine[]): LineType;
|
|
8
|
+
export declare function formatLineLabel(vertical: boolean, position: number): string;
|
|
9
|
+
export interface LineStyle {
|
|
10
|
+
left?: string;
|
|
11
|
+
top?: string;
|
|
12
|
+
width?: string;
|
|
13
|
+
height?: string;
|
|
14
|
+
borderLeft?: string;
|
|
15
|
+
borderBottom?: string;
|
|
16
|
+
cursor?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function computeLineStyle(line: GuideLine, scale: number, offset: number, vertical: boolean, guideLineColor: string): LineStyle;
|
|
19
|
+
export declare function screenToWorld(screenPos: number, offset: number, scale: number): number;
|
|
20
|
+
export declare function worldToScreen(worldPos: number, offset: number, scale: number): number;
|
|
21
|
+
export interface SnapToTickOptions {
|
|
22
|
+
worldPos: number;
|
|
23
|
+
majorTicks: Array<{
|
|
24
|
+
value: number;
|
|
25
|
+
}>;
|
|
26
|
+
thresholdWorld: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function snapToNearestTick(options: SnapToTickOptions): number | null;
|
|
29
|
+
export interface LineDragInput {
|
|
30
|
+
startMouse: number;
|
|
31
|
+
startPos: number;
|
|
32
|
+
currentMouse: number;
|
|
33
|
+
scale: number;
|
|
34
|
+
majorTicks: Array<{
|
|
35
|
+
value: number;
|
|
36
|
+
}>;
|
|
37
|
+
snapThresholdWorld: number;
|
|
38
|
+
}
|
|
39
|
+
export declare function computeDraggedLinePosition(input: LineDragInput): number;
|
|
40
|
+
//# sourceMappingURL=line-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-utils.d.ts","sourceRoot":"","sources":["../../src/utils/line-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,MAAM,EAAE,CAAA;IACX,CAAC,EAAE,MAAM,EAAE,CAAA;CACZ;AAED,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,EAAE,CAuBzD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,QAAQ,CAKxD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,EACjB,cAAc,EAAE,MAAM,GACrB,SAAS,CAqBX;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtF;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpC,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAgB3E;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpC,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAgBvE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sketch-ruler/core",
|
|
3
|
+
"version": "3.0.0-beta.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Framework-agnostic core for sketch-ruler: transform engine, state management, plugins, and scale computation.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"sketch-ruler",
|
|
8
|
+
"ruler",
|
|
9
|
+
"panzoom",
|
|
10
|
+
"transform",
|
|
11
|
+
"canvas",
|
|
12
|
+
"framework-agnostic"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": "kakajun <253495832@qq.com>",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/kakajun/vue3-sketch-ruler.git"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"lib",
|
|
22
|
+
"AGENTS.md"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"main": "lib/index.js",
|
|
27
|
+
"module": "lib/index.js",
|
|
28
|
+
"types": "lib/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./lib/index.d.ts",
|
|
32
|
+
"import": "./lib/index.js",
|
|
33
|
+
"require": "./lib/index.cjs"
|
|
34
|
+
},
|
|
35
|
+
"./engine": {
|
|
36
|
+
"types": "./lib/engine/index.d.ts",
|
|
37
|
+
"import": "./lib/engine/index.js",
|
|
38
|
+
"require": "./lib/engine/index.cjs"
|
|
39
|
+
},
|
|
40
|
+
"./state": {
|
|
41
|
+
"types": "./lib/state/index.d.ts",
|
|
42
|
+
"import": "./lib/state/index.js",
|
|
43
|
+
"require": "./lib/state/index.cjs"
|
|
44
|
+
},
|
|
45
|
+
"./plugins": {
|
|
46
|
+
"types": "./lib/plugins/index.d.ts",
|
|
47
|
+
"import": "./lib/plugins/index.js",
|
|
48
|
+
"require": "./lib/plugins/index.cjs"
|
|
49
|
+
},
|
|
50
|
+
"./scale": {
|
|
51
|
+
"types": "./lib/scale/index.d.ts",
|
|
52
|
+
"import": "./lib/scale/index.js",
|
|
53
|
+
"require": "./lib/scale/index.cjs"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "vite build",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"test:watch": "vitest"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"vite": "^8.0.13",
|
|
63
|
+
"vite-plugin-dts": "^5.0.0",
|
|
64
|
+
"vitest": "^4.1.6"
|
|
65
|
+
}
|
|
66
|
+
}
|