@wbiokr/arrow 0.0.4 → 0.0.5
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/bundle.cjs.js +2 -2
- package/dist/bundle.cjs.js.map +1 -1
- package/dist/bundle.esm.js +41 -33
- package/dist/bundle.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/bundle.cjs.js
CHANGED
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
color: #999;
|
|
125
125
|
text-align: right;
|
|
126
126
|
}
|
|
127
|
-
`;if(typeof document<"u"){const
|
|
127
|
+
`;if(typeof document<"u"){const w=document.createElement("style");w.textContent=S,document.head.appendChild(w)}class M{constructor(t,e={}){this.container=typeof t=="string"?document.querySelector(t):t,this.svg=null,this.arrows=[],this.drawing=!1,this.current=null,this.selected=null,this.mode=null,this.lastClickTime=0,this.lastClickPos=null,this._shouldBlockClick=!1,this._defaultColor="#2b8cff",this.isCtrl=e.isCtrl||!1,this.stopPropagation=e.stopPropagation||!1,this.preventDefault=e.preventDefault||!1,this._transformMode=null,this._transformHandle=null,this._transformStartPos=null,this._transformStartPoints=null,this._transformCenter=null,this._transformStartAngle=null,this._rotationOffset=0,this._toolbar=null,this._strokeWidth=8,this._curveRate=0,this._createSVG(),this._initKeybindings(),this._initEvents()}_createSVG(){this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.setAttribute("class","ae-d2-svg"),this.container.appendChild(this.svg);const t=document.createElementNS("http://www.w3.org/2000/svg","defs");this.svg.appendChild(t);const e=document.createElementNS("http://www.w3.org/2000/svg","marker");e.setAttribute("id","ae-arrowhead"),e.setAttribute("markerWidth","10"),e.setAttribute("markerHeight","10"),e.setAttribute("refX","9"),e.setAttribute("refY","5"),e.setAttribute("orient","auto");const o=document.createElementNS("http://www.w3.org/2000/svg","polygon");o.setAttribute("points","0,0 10,5 0,10 2,5"),o.setAttribute("fill",this._defaultColor),e.appendChild(o),t.appendChild(e)}_createToolbar(){this._toolbar&&this._toolbar.remove(),this._toolbar=document.createElement("div"),this._toolbar.className="ae-toolbar";const t=this.selected.color||this._defaultColor,e=this.selected.strokeWidth||this._strokeWidth,o=this.selected.curveRate??this.selected.cornerRoundness??0;this._toolbar.innerHTML=`
|
|
128
128
|
<div class="ae-toolbar-drag-handle">:::</div>
|
|
129
129
|
<div class="ae-toolbar-item">
|
|
130
130
|
<span class="ae-toolbar-label">颜色</span>
|
|
@@ -139,5 +139,5 @@
|
|
|
139
139
|
<span class="ae-toolbar-label">曲线率</span>
|
|
140
140
|
<input type="range" class="ae-round-input" min="0" max="1" step="0.1" value="${o}" />
|
|
141
141
|
</div>
|
|
142
|
-
`,this._toolbar.querySelector(".ae-color-input").addEventListener("input",n=>{this.selected&&(this.selected.color=n.target.value,this._defaultColor=n.target.value,this._updateMarkerColor(n.target.value),this.render())});const r=this._toolbar.querySelector(".ae-stroke-input"),i=this._toolbar.querySelector(".ae-stroke-input + .ae-toolbar-value");r.addEventListener("input",n=>{this.selected&&(this.selected.strokeWidth=parseInt(n.target.value),i.textContent=n.target.value+"px",this.render())}),this._toolbar.querySelector(".ae-round-input").addEventListener("input",n=>{this.selected&&(this.selected.curveRate=parseFloat(n.target.value),this.render())});const l=this._toolbar.querySelector(".ae-toolbar-drag-handle");this._setupToolbarDrag(l),this._toolbar.addEventListener("mousedown",n=>{n.stopPropagation()}),this._toolbar.addEventListener("mouseup",n=>{n.stopPropagation()}),this.container.appendChild(this._toolbar)}_setupToolbarDrag(t){let e=!1,o={x:0,y:0};t.addEventListener("mousedown",s=>{e=!0,this._toolbarDragging=!0;const r=this._toolbar.getBoundingClientRect();o.x=s.clientX-r.left,o.y=s.clientY-r.top,s.preventDefault(),s.stopPropagation();const i=l=>{if(!e)return;const n=this.container.getBoundingClientRect();let c=l.clientX-n.left-o.x,h=l.clientY-n.top-o.y;const d=this._toolbar.offsetWidth,u=this._toolbar.offsetHeight;c=Math.max(0,Math.min(c,n.width-d)),h=Math.max(0,Math.min(h,n.height-u)),this._toolbar.style.left=c+"px",this._toolbar.style.top=h+"px"},a=l=>{e=!1,this._toolbarDragging=!1,document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",a),this._toolbar.removeEventListener("mouseup",a),l.preventDefault(),l.stopPropagation()};document.addEventListener("mousemove",i),document.addEventListener("mouseup",a),this._toolbar.addEventListener("mouseup",a)})}_showToolbar(){if(this.selected){this._toolbar||this._createToolbar(),this._toolbar.style.display="flex";const t=this.selected.color||this._defaultColor,e=this.selected.strokeWidth||this._strokeWidth,o=this.selected.curveRate??this.selected.cornerRoundness??0,s=this._toolbar.querySelector(".ae-color-input"),r=this._toolbar.querySelector(".ae-stroke-input"),i=this._toolbar.querySelector(".ae-stroke-input + .ae-toolbar-value"),a=this._toolbar.querySelector(".ae-round-input");s&&(s.value=t),r&&(r.value=e,i.textContent=e+"px"),a&&(a.value=o);const l=this._getArrowBBox(this.selected),n=this._toolbar.offsetWidth||150,c=this._toolbar.offsetHeight||120;let h=l.maxX+20;h+n>this.container.offsetWidth&&(h=l.minX-n-20);let d=l.centerY-c/2;d<0&&(d=0),d+c>this.container.offsetHeight&&(d=this.container.offsetHeight-c),this._toolbar.style.left=h+"px",this._toolbar.style.top=d+"px"}}_hideToolbar(){this._toolbar&&(this._toolbar.style.display="none")}_updateMarkerColor(t){const e=this.svg.querySelector("#ae-arrowhead polygon");e&&e.setAttribute("fill",t)}_initKeybindings(){this._kb=new _.Keybinding("arrow-editor"),this._kb.on("enter",()=>{this._handleEnter()}),this._kb.on("esc",()=>{this._handleEsc()})}_initEvents(){this.container.onclick=t=>{if(this._toolbar&&(t.target===this._toolbar||this._toolbar.contains(t.target)))return;const e=this._mousePos(t);this._handleClick(e)},this.container.onmousemove=t=>{const e=this._mousePos(t);this._handleMouseMove(t,e)},this.container.onmousedown=t=>{if(!(this._toolbar&&(t.target===this._toolbar||this._toolbar.contains(t.target)))&&this.selected){const e=t.target.getAttribute("data-handle");if(e){this._transformMode=e,this._transformHandle=e;const o=this._mousePos(t);if(this._transformStartPos=o,this._transformStartPoints=this.selected.points.map(s=>({x:s.x,y:s.y})),this._transformCenter=this._getArrowBBox(this.selected),e==="rotate"){const s=this._transformCenter,r=o.x-s.centerX,i=o.y-s.centerY;this._transformStartAngle=Math.atan2(i,r),this._rotationOffset=0}t.stopPropagation();return}this.mode="move"}},this.container.onmouseup=()=>{this.mode=null,this._transformMode=null,this._transformHandle=null}}_mousePos(t){const e=this.container.getBoundingClientRect();return{x:t.clientX-e.left,y:t.clientY-e.top}}_generatePath(t,e=0){if(t.length<2)return"";if(e===0){let s=`M ${t[0].x} ${t[0].y}`;for(let r=1;r<t.length;r++)s+=` L ${t[r].x} ${t[r].y}`;return s}let o=`M ${t[0].x} ${t[0].y}`;for(let s=0;s<t.length-1;s++){const r=t[s],i=t[s+1],a=i.x-r.x,l=i.y-r.y,n=Math.hypot(a,l);if(n===0)continue;let c=a,h=l;if(s>0){const m=t[s-1];c=r.x-m.x,h=r.y-m.y}let d=a,u=l;if(s<t.length-2){const m=t[s+2];d=m.x-i.x,u=m.y-i.y}const p=Math.hypot(c,h)||1,f=Math.hypot(d,u)||1,k=c/p,C=h/p,x=d/f,y=u/f,b=n*e*.3,w=r.x+k*b,A=r.y+C*b,P=i.x-x*b,E=i.y-y*b;o+=` C ${w} ${A} ${P} ${E} ${i.x} ${i.y}`}return o}_generateArrowHead(t,e=8){if(t.length<2)return"";const o=t[t.length-1];let s=t[t.length-2];t.length>=3&&Math.hypot(o.x-s.x,o.y-s.y)<5&&(s=t[t.length-3]);const r=o.x-s.x,i=o.y-s.y,a=Math.hypot(r,i);if(a<1)return"";const l=r/a,n=i/a,c=o.x,h=o.y,d=e/8,u=40*d,p=20*d,f=20*d,k=o.x+l*f,C=o.y+n*f,x=o.x-l*(u-f),y=o.y-n*(u-f),b=-n,w=l,A=x+b*p,P=y+w*p,E=x-b*p,m=y-w*p;return`M ${k} ${C} L ${A} ${P} L ${c} ${h} L ${E} ${m} Z`}_createArrowGroup(t,e){const o=document.createElementNS("http://www.w3.org/2000/svg","g");o.setAttribute("data-index",e);const s=t.color||this._defaultColor,r=t.strokeWidth||this._strokeWidth,i=t.curveRate??t.cornerRoundness??0,a=document.createElementNS("http://www.w3.org/2000/svg","path");a.setAttribute("class","ae-arrow-path"),a.style.stroke=s,a.style.strokeWidth=r+"px",a.setAttribute("d",this._generatePath(t.points,i)),o.appendChild(a);const l=document.createElementNS("http://www.w3.org/2000/svg","path");if(l.setAttribute("fill",s),l.setAttribute("d",this._generateArrowHead(t.points,r)),o.appendChild(l),t===this.selected){const n=this._getArrowBBox(t),c=document.createElementNS("http://www.w3.org/2000/svg","rect");c.setAttribute("class","ae-transform-box"),c.setAttribute("x",n.minX-10),c.setAttribute("y",n.minY-10),c.setAttribute("width",n.width+20),c.setAttribute("height",n.height+20),o.appendChild(c);const h=document.createElementNS("http://www.w3.org/2000/svg","circle");h.setAttribute("class","ae-transform-handle"),h.setAttribute("cx",n.maxX+10),h.setAttribute("cy",n.maxY+10),h.setAttribute("r",6),h.setAttribute("data-handle","scale"),o.appendChild(h);const d=n.minY-30,u=n.centerX,p=document.createElementNS("http://www.w3.org/2000/svg","line");p.setAttribute("class","ae-rotate-line"),p.setAttribute("x1",n.centerX),p.setAttribute("y1",n.minY-10),p.setAttribute("x2",u),p.setAttribute("y2",d),o.appendChild(p);const f=document.createElementNS("http://www.w3.org/2000/svg","circle");f.setAttribute("class","ae-rotate-handle"),f.setAttribute("cx",u),f.setAttribute("cy",d),f.setAttribute("r",8),f.setAttribute("data-handle","rotate"),o.appendChild(f)}return o}render(){if(this.svg.querySelectorAll("g").forEach(t=>t.remove()),this.arrows.forEach((t,e)=>{const o=this._createArrowGroup(t,e);this.svg.appendChild(o)}),this.current){const t=this._createArrowGroup(this.current,this.arrows.length);this.svg.appendChild(t)}}_isDoubleClick(t){const e=Date.now(),o=e-this.lastClickTime;return this.lastClickTime=e,o<300&&this.lastClickPos&&Math.hypot(t.x-this.lastClickPos.x,t.y-this.lastClickPos.y)<10?(this.lastClickPos=null,!0):(this.lastClickPos=t,!1)}_handleClick(t){if(this._shouldBlockClick){this._shouldBlockClick=!1;return}if(this._isDoubleClick(t)){this.drawing&&this.current&&this.current.points.length>=2&&(this.drawing=!1,this.arrows.push(this.current),this.current=null,this.render());return}if(this.selected){for(const e of this.arrows)if(this._hitArrow(e,t)){this.render();return}this.selected=null,this._hideToolbar(),this.render();return}for(const e of this.arrows)if(this._hitArrow(e,t)){this.selected=e,this._showToolbar(),this.render();return}this.drawing?this.current.points.push(t):(this.drawing=!0,this.current={points:[t,t],color:this._defaultColor}),this.render()}_handleEnter(){this.drawing&&this.current&&this.current.points.length>=2&&(this.drawing=!1,this.arrows.push(this.current),this.current=null,this.render())}_handleEsc(){this.drawing&&(this.drawing=!1,this.current=null),this.selected&&(this.selected=null),this._hideColorPicker(),this._hideToolbar(),this.render()}_showColorPicker(t){if(this._showingColorPicker){this._hideColorPicker();return}this._showingColorPicker=!0;const e=document.createElement("div");e.className="ae-color-picker-popup";const o=document.createElement("span");o.textContent="选择颜色",o.style.cssText="font-size: 12px; color: #666;";const s=document.createElement("input");s.type="color",s.value=this.selected.color||this._defaultColor,s.showPicker(),e.appendChild(o),e.appendChild(s);const r=this.container.getBoundingClientRect(),i=this._getArrowBBox(this.selected),a=r.left+i.minX-50,l=r.top+i.maxY+15;e.style.left=a+"px",e.style.top=l+"px",s.addEventListener("input",c=>{this.selected.color=c.target.value,this._defaultColor=c.target.value,this.render()});const n=c=>{e.contains(c.target)||(this._hideColorPicker(),document.removeEventListener("click",n))};document.body.appendChild(e),this._colorPickerPopup=e,document.addEventListener("click",n)}_hideColorPicker(){this._colorPickerPopup&&(this._colorPickerPopup.remove(),this._colorPickerPopup=null),this._showingColorPicker=!1}deleteSelected(){this.selected&&(this.arrows=this.arrows.filter(t=>t!==this.selected),this.selected=null,this.render())}_handleMouseMove(t,e){if(!this._toolbarDragging&&!(this._toolbar&&(t.target===this._toolbar||this._toolbar.contains(t.target)))){if(this.drawing&&(this.current.points[this.current.points.length-1]=e,this.render()),this._transformMode&&this.selected){this._transformMode==="rotate"?this._handleRotate(e):this._transformMode==="scale"&&this._handleScale(e),this.render();return}if(this.selected&&this.mode==="move"){const o=t.movementX,s=t.movementY;(o!==0||s!==0)&&(this._shouldBlockClick=!0),this.selected.points.forEach(r=>{r.x+=o,r.y+=s}),this.render()}}}_getArrowBBox(t){const e=t.points;let o=1/0,s=1/0,r=-1/0,i=-1/0;for(const a of e)o=Math.min(o,a.x),s=Math.min(s,a.y),r=Math.max(r,a.x),i=Math.max(i,a.y);return{minX:o,minY:s,maxX:r,maxY:i,width:r-o,height:i-s,centerX:(o+r)/2,centerY:(s+i)/2}}_handleRotate(t){const e=this._transformCenter,o=e.centerX,s=e.centerY,r=Math.atan2(t.y-s,t.x-o),i=Math.atan2(this._transformStartPos.y-s,this._transformStartPos.x-o),a=r-i,l=Math.cos(a),n=Math.sin(a);this.selected.points.forEach((c,h)=>{const d=this._transformStartPoints[h].x-o,u=this._transformStartPoints[h].y-s;c.x=o+d*l-u*n,c.y=s+d*n+u*l})}_handleScale(t){const e=this._transformCenter,o=e.centerX,s=e.centerY,r=this._transformStartPoints,i=this._transformStartPos,a=t.x-o,l=t.y-s,n=i.x-o,c=i.y-s,h=Math.hypot(a,l),d=Math.hypot(n,c),u=h/d;this.selected.points.forEach((p,f)=>{p.x=o+(r[f].x-o)*u,p.y=s+(r[f].y-s)*u})}_hitArrow(t,e){for(let o=0;o<t.points.length-1;o++)if(this._dist(e,t.points[o],t.points[o+1])<15)return!0;return!1}_dist(t,e,o){const s=o.x-e.x,r=o.y-e.y,i=((t.x-e.x)*s+(t.y-e.y)*r)/(s*s+r*r),a=Math.max(0,Math.min(1,i)),l=e.x+a*s,n=e.y+a*r;return Math.hypot(t.x-l,t.y-n)}getData(){return this.arrows.map(t=>({points:t.points,curveRate:t.curveRate??t.cornerRoundness??0,strokeWidth:t.strokeWidth,color:t.color}))}setData(t){this.arrows=t.map(e=>({points:e.points,curveRate:e.curveRate??0,strokeWidth:e.strokeWidth??8,color:e.color})),this.render()}clear(){this.arrows=[],this.drawing=!1,this.current=null,this.selected=null,this.render()}}g.ArrowEditor=M,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})}));
|
|
142
|
+
`,this._toolbar.querySelector(".ae-color-input").addEventListener("input",i=>{this.selected&&(this.selected.color=i.target.value,this._defaultColor=i.target.value,this._updateMarkerColor(i.target.value),this.render())});const r=this._toolbar.querySelector(".ae-stroke-input"),n=this._toolbar.querySelector(".ae-stroke-input + .ae-toolbar-value");r.addEventListener("input",i=>{this.selected&&(this.selected.strokeWidth=parseInt(i.target.value),n.textContent=i.target.value+"px",this.render())}),this._toolbar.querySelector(".ae-round-input").addEventListener("input",i=>{this.selected&&(this.selected.curveRate=parseFloat(i.target.value),this.render())});const l=this._toolbar.querySelector(".ae-toolbar-drag-handle");this._setupToolbarDrag(l),this._toolbar.addEventListener("mousedown",i=>{i.stopPropagation()}),this._toolbar.addEventListener("mouseup",i=>{i.stopPropagation()}),this.container.appendChild(this._toolbar)}_setupToolbarDrag(t){let e=!1,o={x:0,y:0};t.addEventListener("mousedown",s=>{e=!0,this._toolbarDragging=!0;const r=this._toolbar.getBoundingClientRect();o.x=s.clientX-r.left,o.y=s.clientY-r.top,s.preventDefault(),s.stopPropagation();const n=l=>{if(!e)return;const i=this.container.getBoundingClientRect();let h=l.clientX-i.left-o.x,c=l.clientY-i.top-o.y;const d=this._toolbar.offsetWidth,u=this._toolbar.offsetHeight;h=Math.max(0,Math.min(h,i.width-d)),c=Math.max(0,Math.min(c,i.height-u)),this._toolbar.style.left=h+"px",this._toolbar.style.top=c+"px"},a=l=>{e=!1,this._toolbarDragging=!1,document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",a),this._toolbar.removeEventListener("mouseup",a),l.preventDefault(),l.stopPropagation()};document.addEventListener("mousemove",n),document.addEventListener("mouseup",a),this._toolbar.addEventListener("mouseup",a)})}_showToolbar(){if(this.selected){this._toolbar||this._createToolbar(),this._toolbar.style.display="flex";const t=this.selected.color||this._defaultColor,e=this.selected.strokeWidth||this._strokeWidth,o=this.selected.curveRate??this.selected.cornerRoundness??0,s=this._toolbar.querySelector(".ae-color-input"),r=this._toolbar.querySelector(".ae-stroke-input"),n=this._toolbar.querySelector(".ae-stroke-input + .ae-toolbar-value"),a=this._toolbar.querySelector(".ae-round-input");s&&(s.value=t),r&&(r.value=e,n.textContent=e+"px"),a&&(a.value=o);const l=this._getArrowBBox(this.selected),i=this._toolbar.offsetWidth||150,h=this._toolbar.offsetHeight||120;let c=l.maxX+20;c+i>this.container.offsetWidth&&(c=l.minX-i-20);let d=l.centerY-h/2;d<0&&(d=0),d+h>this.container.offsetHeight&&(d=this.container.offsetHeight-h),this._toolbar.style.left=c+"px",this._toolbar.style.top=d+"px"}}_hideToolbar(){this._toolbar&&(this._toolbar.style.display="none")}_updateMarkerColor(t){const e=this.svg.querySelector("#ae-arrowhead polygon");e&&e.setAttribute("fill",t)}_initKeybindings(){this._kb=new _.Keybinding("arrow-editor"),this._kb.on("enter",()=>{this._handleEnter()}),this._kb.on("esc",()=>{this._handleEsc()})}_initEvents(){this.container.onclick=t=>{if(this._toolbar&&(t.target===this._toolbar||this._toolbar.contains(t.target)))return;this.preventDefault&&t.preventDefault(),this.stopPropagation&&t.stopPropagation();const e=this._mousePos(t);this._handleClick(e,t)},this.container.onmousemove=t=>{this.preventDefault&&t.preventDefault(),this.stopPropagation&&t.stopPropagation();const e=this._mousePos(t);this._handleMouseMove(t,e)},this.container.onmousedown=t=>{if(!(this._toolbar&&(t.target===this._toolbar||this._toolbar.contains(t.target)))&&(this.preventDefault&&t.preventDefault(),this.stopPropagation&&t.stopPropagation(),this.selected)){const e=t.target.getAttribute("data-handle");if(e){this._transformMode=e,this._transformHandle=e;const o=this._mousePos(t);if(this._transformStartPos=o,this._transformStartPoints=this.selected.points.map(s=>({x:s.x,y:s.y})),this._transformCenter=this._getArrowBBox(this.selected),e==="rotate"){const s=this._transformCenter,r=o.x-s.centerX,n=o.y-s.centerY;this._transformStartAngle=Math.atan2(n,r),this._rotationOffset=0}t.stopPropagation();return}this.mode="move"}},this.container.onmouseup=()=>{this.mode=null,this._transformMode=null,this._transformHandle=null}}_mousePos(t){const e=this.container.getBoundingClientRect();return{x:t.clientX-e.left,y:t.clientY-e.top}}_generatePath(t,e=0){if(t.length<2)return"";if(e===0){let s=`M ${t[0].x} ${t[0].y}`;for(let r=1;r<t.length;r++)s+=` L ${t[r].x} ${t[r].y}`;return s}let o=`M ${t[0].x} ${t[0].y}`;for(let s=0;s<t.length-1;s++){const r=t[s],n=t[s+1],a=n.x-r.x,l=n.y-r.y,i=Math.hypot(a,l);if(i===0)continue;let h=a,c=l;if(s>0){const m=t[s-1];h=r.x-m.x,c=r.y-m.y}let d=a,u=l;if(s<t.length-2){const m=t[s+2];d=m.x-n.x,u=m.y-n.y}const p=Math.hypot(h,c)||1,f=Math.hypot(d,u)||1,k=h/p,C=c/p,x=d/f,y=u/f,b=i*e*.3,v=r.x+k*b,A=r.y+C*b,P=n.x-x*b,E=n.y-y*b;o+=` C ${v} ${A} ${P} ${E} ${n.x} ${n.y}`}return o}_generateArrowHead(t,e=8){if(t.length<2)return"";const o=t[t.length-1];let s=t[t.length-2];t.length>=3&&Math.hypot(o.x-s.x,o.y-s.y)<5&&(s=t[t.length-3]);const r=o.x-s.x,n=o.y-s.y,a=Math.hypot(r,n);if(a<1)return"";const l=r/a,i=n/a,h=o.x,c=o.y,d=e/8,u=40*d,p=20*d,f=20*d,k=o.x+l*f,C=o.y+i*f,x=o.x-l*(u-f),y=o.y-i*(u-f),b=-i,v=l,A=x+b*p,P=y+v*p,E=x-b*p,m=y-v*p;return`M ${k} ${C} L ${A} ${P} L ${h} ${c} L ${E} ${m} Z`}_createArrowGroup(t,e){const o=document.createElementNS("http://www.w3.org/2000/svg","g");o.setAttribute("data-index",e);const s=t.color||this._defaultColor,r=t.strokeWidth||this._strokeWidth,n=t.curveRate??t.cornerRoundness??0,a=document.createElementNS("http://www.w3.org/2000/svg","path");a.setAttribute("class","ae-arrow-path"),a.style.stroke=s,a.style.strokeWidth=r+"px",a.setAttribute("d",this._generatePath(t.points,n)),o.appendChild(a);const l=document.createElementNS("http://www.w3.org/2000/svg","path");if(l.setAttribute("fill",s),l.setAttribute("d",this._generateArrowHead(t.points,r)),o.appendChild(l),t===this.selected){const i=this._getArrowBBox(t),h=document.createElementNS("http://www.w3.org/2000/svg","rect");h.setAttribute("class","ae-transform-box"),h.setAttribute("x",i.minX-10),h.setAttribute("y",i.minY-10),h.setAttribute("width",i.width+20),h.setAttribute("height",i.height+20),o.appendChild(h);const c=document.createElementNS("http://www.w3.org/2000/svg","circle");c.setAttribute("class","ae-transform-handle"),c.setAttribute("cx",i.maxX+10),c.setAttribute("cy",i.maxY+10),c.setAttribute("r",6),c.setAttribute("data-handle","scale"),o.appendChild(c);const d=i.minY-30,u=i.centerX,p=document.createElementNS("http://www.w3.org/2000/svg","line");p.setAttribute("class","ae-rotate-line"),p.setAttribute("x1",i.centerX),p.setAttribute("y1",i.minY-10),p.setAttribute("x2",u),p.setAttribute("y2",d),o.appendChild(p);const f=document.createElementNS("http://www.w3.org/2000/svg","circle");f.setAttribute("class","ae-rotate-handle"),f.setAttribute("cx",u),f.setAttribute("cy",d),f.setAttribute("r",8),f.setAttribute("data-handle","rotate"),o.appendChild(f)}return o}render(){if(this.svg.querySelectorAll("g").forEach(t=>t.remove()),this.arrows.forEach((t,e)=>{const o=this._createArrowGroup(t,e);this.svg.appendChild(o)}),this.current){const t=this._createArrowGroup(this.current,this.arrows.length);this.svg.appendChild(t)}}_isDoubleClick(t){const e=Date.now(),o=e-this.lastClickTime;return this.lastClickTime=e,o<300&&this.lastClickPos&&Math.hypot(t.x-this.lastClickPos.x,t.y-this.lastClickPos.y)<10?(this.lastClickPos=null,!0):(this.lastClickPos=t,!1)}_handleClick(t,e){if(!(this.isCtrl&&!e.ctrlKey)){if(this._shouldBlockClick){this._shouldBlockClick=!1;return}if(this._isDoubleClick(t)){this.drawing&&this.current&&this.current.points.length>=2&&(this.drawing=!1,this.arrows.push(this.current),this.current=null,this.render());return}if(this.selected){for(const o of this.arrows)if(this._hitArrow(o,t)){this.render();return}this.selected=null,this._hideToolbar(),this.render();return}for(const o of this.arrows)if(this._hitArrow(o,t)){this.selected=o,this._showToolbar(),this.render();return}this.drawing?this.current.points.push(t):(this.drawing=!0,this.current={points:[t,t],color:this._defaultColor}),this.render()}}_handleEnter(){this.drawing&&this.current&&this.current.points.length>=2&&(this.drawing=!1,this.arrows.push(this.current),this.current=null,this.render())}_handleEsc(){this.drawing&&(this.drawing=!1,this.current=null),this.selected&&(this.selected=null),this._hideColorPicker(),this._hideToolbar(),this.render()}_showColorPicker(t){if(this._showingColorPicker){this._hideColorPicker();return}this._showingColorPicker=!0;const e=document.createElement("div");e.className="ae-color-picker-popup";const o=document.createElement("span");o.textContent="选择颜色",o.style.cssText="font-size: 12px; color: #666;";const s=document.createElement("input");s.type="color",s.value=this.selected.color||this._defaultColor,s.showPicker(),e.appendChild(o),e.appendChild(s);const r=this.container.getBoundingClientRect(),n=this._getArrowBBox(this.selected),a=r.left+n.minX-50,l=r.top+n.maxY+15;e.style.left=a+"px",e.style.top=l+"px",s.addEventListener("input",h=>{this.selected.color=h.target.value,this._defaultColor=h.target.value,this.render()});const i=h=>{e.contains(h.target)||(this._hideColorPicker(),document.removeEventListener("click",i))};document.body.appendChild(e),this._colorPickerPopup=e,document.addEventListener("click",i)}_hideColorPicker(){this._colorPickerPopup&&(this._colorPickerPopup.remove(),this._colorPickerPopup=null),this._showingColorPicker=!1}deleteSelected(){this.selected&&(this.arrows=this.arrows.filter(t=>t!==this.selected),this.selected=null,this.render())}_handleMouseMove(t,e){if(!this._toolbarDragging&&!(this._toolbar&&(t.target===this._toolbar||this._toolbar.contains(t.target)))){if(this.isCtrl&&!t.ctrlKey){this.drawing&&this.current&&this.current.points.length>=2&&(this.drawing=!1,this.arrows.push(this.current),this.current=null,this.render());return}if(this.drawing&&(this.current.points[this.current.points.length-1]=e,this.render()),this._transformMode&&this.selected){this._transformMode==="rotate"?this._handleRotate(e):this._transformMode==="scale"&&this._handleScale(e),this.render();return}if(this.selected&&this.mode==="move"){const o=t.movementX,s=t.movementY;(o!==0||s!==0)&&(this._shouldBlockClick=!0),this.selected.points.forEach(r=>{r.x+=o,r.y+=s}),this.render()}}}_getArrowBBox(t){const e=t.points;let o=1/0,s=1/0,r=-1/0,n=-1/0;for(const a of e)o=Math.min(o,a.x),s=Math.min(s,a.y),r=Math.max(r,a.x),n=Math.max(n,a.y);return{minX:o,minY:s,maxX:r,maxY:n,width:r-o,height:n-s,centerX:(o+r)/2,centerY:(s+n)/2}}_handleRotate(t){const e=this._transformCenter,o=e.centerX,s=e.centerY,r=Math.atan2(t.y-s,t.x-o),n=Math.atan2(this._transformStartPos.y-s,this._transformStartPos.x-o),a=r-n,l=Math.cos(a),i=Math.sin(a);this.selected.points.forEach((h,c)=>{const d=this._transformStartPoints[c].x-o,u=this._transformStartPoints[c].y-s;h.x=o+d*l-u*i,h.y=s+d*i+u*l})}_handleScale(t){const e=this._transformCenter,o=e.centerX,s=e.centerY,r=this._transformStartPoints,n=this._transformStartPos,a=t.x-o,l=t.y-s,i=n.x-o,h=n.y-s,c=Math.hypot(a,l),d=Math.hypot(i,h),u=c/d;this.selected.points.forEach((p,f)=>{p.x=o+(r[f].x-o)*u,p.y=s+(r[f].y-s)*u})}_hitArrow(t,e){for(let o=0;o<t.points.length-1;o++)if(this._dist(e,t.points[o],t.points[o+1])<15)return!0;return!1}_dist(t,e,o){const s=o.x-e.x,r=o.y-e.y,n=((t.x-e.x)*s+(t.y-e.y)*r)/(s*s+r*r),a=Math.max(0,Math.min(1,n)),l=e.x+a*s,i=e.y+a*r;return Math.hypot(t.x-l,t.y-i)}getData(){return this.arrows.map(t=>({points:t.points,curveRate:t.curveRate??t.cornerRoundness??0,strokeWidth:t.strokeWidth,color:t.color}))}setData(t){this.arrows=t.map(e=>({points:e.points,curveRate:e.curveRate??0,strokeWidth:e.strokeWidth??8,color:e.color})),this.render()}clear(){this.arrows=[],this.drawing=!1,this.current=null,this.selected=null,this.render()}}g.ArrowEditor=M,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})}));
|
|
143
143
|
//# sourceMappingURL=bundle.cjs.js.map
|
package/dist/bundle.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.cjs.js","sources":["../src/editor.js"],"sourcesContent":["import { Keybinding } from '@wbiokr/keybinding'\n\n// 样式注入\nconst STYLES = `\n.ae-d2-container {\n position: relative;\n width: 1000px;\n height: 600px;\n background: #fff;\n margin: auto;\n}\n\n.ae-d2-svg {\n width: 100%;\n height: 100%;\n}\n\n.ae-arrow-path {\n fill: none;\n stroke-linecap: round;\n stroke-linejoin: round;\n cursor: pointer;\n}\n\n.ae-arrow-path:hover {\n stroke: #00aaff;\n}\n\n.ae-transform-box {\n fill: none;\n stroke: #00aaff;\n stroke-width: 2;\n stroke-dasharray: 4;\n}\n\n.ae-transform-handle {\n fill: #fff;\n stroke: #00aaff;\n stroke-width: 2;\n cursor: pointer;\n}\n\n.ae-transform-handle:hover {\n fill: #00aaff;\n}\n\n.ae-rotate-handle {\n fill: #fff;\n stroke: #ff6600;\n stroke-width: 2;\n cursor: grab;\n}\n\n.ae-rotate-handle:hover {\n fill: #ff6600;\n}\n\n.ae-rotate-line {\n stroke: #ff6600;\n stroke-width: 1;\n stroke-dasharray: 4;\n}\n\n/* 工具条样式 */\n.ae-toolbar {\n position: absolute;\n display: none;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0,0,0,0.15);\n z-index: 1000;\n pointer-events: auto;\n min-width: 140px;\n}\n\n.ae-toolbar-drag-handle {\n cursor: grab;\n text-align: center;\n padding: 4px;\n color: #999;\n font-size: 14px;\n line-height: 1;\n user-select: none;\n border-bottom: 1px solid #eee;\n margin: -12px -12px 8px -12px;\n padding-top: 8px;\n padding-bottom: 8px;\n border-radius: 8px 8px 0 0;\n}\n\n.ae-toolbar-drag-handle:active {\n cursor: grabbing;\n}\n\n.ae-toolbar-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ae-toolbar-label {\n font-size: 11px;\n color: #666;\n}\n\n.ae-toolbar input[type=\"color\"] {\n width: 40px;\n height: 30px;\n border: 1px solid #ddd;\n border-radius: 4px;\n cursor: pointer;\n padding: 0;\n background: none;\n}\n\n.ae-toolbar input[type=\"range\"] {\n width: 120px;\n cursor: pointer;\n}\n\n.ae-toolbar-value {\n font-size: 10px;\n color: #999;\n text-align: right;\n}\n`\n\n// 注入样式\nif (typeof document !== 'undefined') {\n const styleEl = document.createElement('style')\n styleEl.textContent = STYLES\n document.head.appendChild(styleEl)\n}\n\nexport class ArrowEditor {\n\n constructor(container) {\n this.container = typeof container === 'string' ? document.querySelector(container) : container\n this.svg = null\n\n this.arrows = []\n this.drawing = false\n this.current = null\n this.selected = null\n this.mode = null\n this.lastClickTime = 0\n this.lastClickPos = null\n this._shouldBlockClick = false\n this._defaultColor = '#2b8cff'\n\n // 变换相关\n this._transformMode = null // 'rotate' | 'scale'\n this._transformHandle = null\n this._transformStartPos = null\n this._transformStartPoints = null\n this._transformCenter = null\n this._transformStartAngle = null\n this._rotationOffset = 0\n\n // 工具条相关\n this._toolbar = null\n this._strokeWidth = 8\n this._curveRate = 0\n\n this._createSVG()\n this._initKeybindings()\n this._initEvents()\n }\n\n _createSVG() {\n // 创建 SVG 元素\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n this.svg.setAttribute('class', 'ae-d2-svg')\n this.container.appendChild(this.svg)\n\n // 创建 defs 和 marker\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs')\n this.svg.appendChild(defs)\n\n const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker')\n marker.setAttribute('id', 'ae-arrowhead')\n marker.setAttribute('markerWidth', '10')\n marker.setAttribute('markerHeight', '10')\n marker.setAttribute('refX', '9')\n marker.setAttribute('refY', '5')\n marker.setAttribute('orient', 'auto')\n\n const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon')\n polygon.setAttribute('points', '0,0 10,5 0,10 2,5')\n polygon.setAttribute('fill', this._defaultColor)\n\n marker.appendChild(polygon)\n defs.appendChild(marker)\n }\n\n _createToolbar() {\n if (this._toolbar) {\n this._toolbar.remove()\n }\n\n this._toolbar = document.createElement('div')\n this._toolbar.className = 'ae-toolbar'\n\n const color = this.selected.color || this._defaultColor\n const strokeWidth = this.selected.strokeWidth || this._strokeWidth\n const curveRate = this.selected.curveRate ?? this.selected.cornerRoundness ?? 0\n\n this._toolbar.innerHTML = `\n <div class=\"ae-toolbar-drag-handle\">:::</div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">颜色</span>\n <input type=\"color\" class=\"ae-color-input\" value=\"${color}\" />\n </div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">粗细</span>\n <input type=\"range\" class=\"ae-stroke-input\" min=\"1\" max=\"60\" value=\"${strokeWidth}\" />\n <span class=\"ae-toolbar-value\">${strokeWidth}px</span>\n </div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">曲线率</span>\n <input type=\"range\" class=\"ae-round-input\" min=\"0\" max=\"1\" step=\"0.1\" value=\"${curveRate}\" />\n </div>\n `\n\n // 颜色选择\n const colorInput = this._toolbar.querySelector('.ae-color-input')\n colorInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.color = e.target.value\n this._defaultColor = e.target.value\n this._updateMarkerColor(e.target.value)\n this.render()\n })\n\n // 粗细调整\n const strokeInput = this._toolbar.querySelector('.ae-stroke-input')\n const strokeValue = this._toolbar.querySelector('.ae-stroke-input + .ae-toolbar-value')\n strokeInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.strokeWidth = parseInt(e.target.value)\n strokeValue.textContent = e.target.value + 'px'\n this.render()\n })\n\n // 曲线率调整\n const roundInput = this._toolbar.querySelector('.ae-round-input')\n roundInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.curveRate = parseFloat(e.target.value)\n this.render()\n })\n\n // 拖拽功能 - 使用类实例绑定\n const dragHandle = this._toolbar.querySelector('.ae-toolbar-drag-handle')\n this._setupToolbarDrag(dragHandle)\n\n // 阻止工具条上的事件触发到容器\n this._toolbar.addEventListener('mousedown', (e) => {\n e.stopPropagation()\n })\n this._toolbar.addEventListener('mouseup', (e) => {\n e.stopPropagation()\n })\n\n this.container.appendChild(this._toolbar)\n }\n\n // 工具条拖拽设置\n _setupToolbarDrag(dragHandle) {\n let isDragging = false\n let dragOffset = { x: 0, y: 0 }\n\n dragHandle.addEventListener('mousedown', (e) => {\n isDragging = true\n this._toolbarDragging = true\n const rect = this._toolbar.getBoundingClientRect()\n dragOffset.x = e.clientX - rect.left\n dragOffset.y = e.clientY - rect.top\n e.preventDefault()\n e.stopPropagation()\n\n const onMove = (moveEvent) => {\n if (!isDragging) return\n const containerRect = this.container.getBoundingClientRect()\n let newLeft = moveEvent.clientX - containerRect.left - dragOffset.x\n let newTop = moveEvent.clientY - containerRect.top - dragOffset.y\n const toolbarWidth = this._toolbar.offsetWidth\n const toolbarHeight = this._toolbar.offsetHeight\n newLeft = Math.max(0, Math.min(newLeft, containerRect.width - toolbarWidth))\n newTop = Math.max(0, Math.min(newTop, containerRect.height - toolbarHeight))\n this._toolbar.style.left = newLeft + 'px'\n this._toolbar.style.top = newTop + 'px'\n }\n\n const onUp = (e) => {\n isDragging = false\n this._toolbarDragging = false\n document.removeEventListener('mousemove', onMove)\n document.removeEventListener('mouseup', onUp)\n this._toolbar.removeEventListener('mouseup', onUp)\n \n e.preventDefault()\n e.stopPropagation()\n }\n\n document.addEventListener('mousemove', onMove)\n document.addEventListener('mouseup', onUp)\n\n this._toolbar.addEventListener('mouseup', onUp)\n })\n }\n\n _showToolbar() {\n if (this.selected) {\n if (!this._toolbar) {\n this._createToolbar()\n }\n this._toolbar.style.display = 'flex'\n\n // 更新工具条值\n const color = this.selected.color || this._defaultColor\n const strokeWidth = this.selected.strokeWidth || this._strokeWidth\n const curveRate = this.selected.curveRate ?? this.selected.cornerRoundness ?? 0\n\n const colorInput = this._toolbar.querySelector('.ae-color-input')\n const strokeInput = this._toolbar.querySelector('.ae-stroke-input')\n const strokeValue = this._toolbar.querySelector('.ae-stroke-input + .ae-toolbar-value')\n const roundInput = this._toolbar.querySelector('.ae-round-input')\n\n if (colorInput) colorInput.value = color\n if (strokeInput) {\n strokeInput.value = strokeWidth\n strokeValue.textContent = strokeWidth + 'px'\n }\n if (roundInput) roundInput.value = curveRate\n\n // 定位到所选箭头旁边\n const bbox = this._getArrowBBox(this.selected)\n const toolbarWidth = this._toolbar.offsetWidth || 150\n const toolbarHeight = this._toolbar.offsetHeight || 120\n\n // 计算位置:放在箭头右侧,如果空间不够则放左侧\n let left = bbox.maxX + 20\n if (left + toolbarWidth > this.container.offsetWidth) {\n left = bbox.minX - toolbarWidth - 20\n }\n\n // 垂直居中于箭头\n let top = bbox.centerY - toolbarHeight / 2\n if (top < 0) top = 0\n if (top + toolbarHeight > this.container.offsetHeight) {\n top = this.container.offsetHeight - toolbarHeight\n }\n\n this._toolbar.style.left = left + 'px'\n this._toolbar.style.top = top + 'px'\n }\n }\n\n _hideToolbar() {\n if (this._toolbar) {\n this._toolbar.style.display = 'none'\n }\n }\n\n _updateMarkerColor(color) {\n const marker = this.svg.querySelector('#ae-arrowhead polygon')\n if (marker) {\n marker.setAttribute('fill', color)\n }\n }\n\n _initKeybindings() {\n // 创建快捷键实例,绑定到 container 上\n this._kb = new Keybinding('arrow-editor')\n\n // Enter: 完成绘制\n this._kb.on('enter', () => {\n this._handleEnter()\n })\n\n // Esc: 结束绘制、取消选中\n this._kb.on('esc', () => {\n this._handleEsc()\n })\n }\n\n _initEvents() {\n this.container.onclick = e => {\n // 点击工具条时不处理\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n const p = this._mousePos(e)\n this._handleClick(p)\n }\n\n this.container.onmousemove = e => {\n const p = this._mousePos(e)\n this._handleMouseMove(e, p)\n }\n\n this.container.onmousedown = e => {\n // 点击工具条不触发移动\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n\n if (this.selected) {\n const handle = e.target.getAttribute('data-handle')\n if (handle) {\n this._transformMode = handle\n this._transformHandle = handle\n const p = this._mousePos(e)\n this._transformStartPos = p\n this._transformStartPoints = this.selected.points.map(pt => ({ x: pt.x, y: pt.y }))\n this._transformCenter = this._getArrowBBox(this.selected)\n\n if (handle === 'rotate') {\n const center = this._transformCenter\n const dx = p.x - center.centerX\n const dy = p.y - center.centerY\n this._transformStartAngle = Math.atan2(dy, dx)\n this._rotationOffset = 0\n }\n\n e.stopPropagation()\n return\n }\n\n this.mode = 'move'\n }\n }\n\n this.container.onmouseup = () => {\n this.mode = null\n this._transformMode = null\n this._transformHandle = null\n }\n }\n\n _mousePos(e) {\n const r = this.container.getBoundingClientRect()\n return {\n x: e.clientX - r.left,\n y: e.clientY - r.top\n }\n }\n\n _generatePath(pts, curveRate = 0) {\n if (pts.length < 2) return ''\n\n // curveRate 为 0 时画直线\n if (curveRate === 0) {\n let d = `M ${pts[0].x} ${pts[0].y}`\n for (let i = 1; i < pts.length; i++) {\n d += ` L ${pts[i].x} ${pts[i].y}`\n }\n return d\n }\n\n // 根据曲线率计算控制点位置\n // curveRate: 0 - 直线,1 - 最弯曲\n let d = `M ${pts[0].x} ${pts[0].y}`\n\n for (let i = 0; i < pts.length - 1; i++) {\n const curr = pts[i]\n const next = pts[i + 1]\n\n // 计算当前线段的向量\n const dx = next.x - curr.x\n const dy = next.y - curr.y\n const len = Math.hypot(dx, dy)\n\n if (len === 0) continue\n\n // 计算进入当前点的切线向量(前一段线段)\n let inDx = dx\n let inDy = dy\n\n if (i > 0) {\n const prev = pts[i - 1]\n inDx = curr.x - prev.x\n inDy = curr.y - prev.y\n }\n\n // 计算出当前点的切线向量(下一段线段)\n let outDx = dx\n let outDy = dy\n\n if (i < pts.length - 2) {\n const after = pts[i + 2]\n outDx = after.x - next.x\n outDy = after.y - next.y\n }\n\n // 单位向量\n const inLen = Math.hypot(inDx, inDy) || 1\n const outLen = Math.hypot(outDx, outDy) || 1\n const uxIn = inDx / inLen\n const uyIn = inDy / inLen\n const uxOut = outDx / outLen\n const uyOut = outDy / outLen\n\n // 控制点距离:曲线率 * 线段长度 * 系数\n const controlDist = len * curveRate * 0.3\n\n // 第一个控制点:从当前点沿进入方向的切线\n const cp1X = curr.x + uxIn * controlDist\n const cp1Y = curr.y + uyIn * controlDist\n\n // 第二个控制点:从下一个点沿出去方向的切线反方向\n const cp2X = next.x - uxOut * controlDist\n const cp2Y = next.y - uyOut * controlDist\n\n d += ` C ${cp1X} ${cp1Y} ${cp2X} ${cp2Y} ${next.x} ${next.y}`\n }\n\n return d\n }\n\n _generateArrowHead(pts, strokeWidth = 8) {\n if (pts.length < 2) return ''\n\n const last = pts[pts.length - 1]\n let prev = pts[pts.length - 2]\n\n if (pts.length >= 3) {\n const dist = Math.hypot(last.x - prev.x, last.y - prev.y)\n if (dist < 5) {\n prev = pts[pts.length - 3]\n }\n }\n\n const dx = last.x - prev.x\n const dy = last.y - prev.y\n const len = Math.hypot(dx, dy)\n\n if (len < 1) return ''\n\n const ux = dx / len\n const uy = dy / len\n\n const notchX = last.x\n const notchY = last.y\n\n // 根据粗细调整箭头大小\n const scale = strokeWidth / 8\n const baseLen = 40 * scale\n const baseWidth = 20 * scale\n const notchLen = 20 * scale\n\n const tipX = last.x + ux * notchLen\n const tipY = last.y + uy * notchLen\n const baseX = last.x - ux * (baseLen - notchLen)\n const baseY = last.y - uy * (baseLen - notchLen)\n\n const px = -uy\n const py = ux\n\n const leftX = baseX + px * baseWidth\n const leftY = baseY + py * baseWidth\n const rightX = baseX - px * baseWidth\n const rightY = baseY - py * baseWidth\n\n return `M ${tipX} ${tipY} L ${leftX} ${leftY} L ${notchX} ${notchY} L ${rightX} ${rightY} Z`\n }\n\n _createArrowGroup(arrow, index) {\n const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')\n g.setAttribute('data-index', index)\n\n const color = arrow.color || this._defaultColor\n const strokeWidth = arrow.strokeWidth || this._strokeWidth\n const curveRate = arrow.curveRate ?? arrow.cornerRoundness ?? 0\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('class', 'ae-arrow-path')\n path.style.stroke = color\n path.style.strokeWidth = strokeWidth + 'px'\n path.setAttribute('d', this._generatePath(arrow.points, curveRate))\n g.appendChild(path)\n\n const arrowHead = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n arrowHead.setAttribute('fill', color)\n arrowHead.setAttribute('d', this._generateArrowHead(arrow.points, strokeWidth))\n g.appendChild(arrowHead)\n\n if (arrow === this.selected) {\n const bbox = this._getArrowBBox(arrow)\n\n // 变换框\n const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\n rect.setAttribute('class', 'ae-transform-box')\n rect.setAttribute('x', bbox.minX - 10)\n rect.setAttribute('y', bbox.minY - 10)\n rect.setAttribute('width', bbox.width + 20)\n rect.setAttribute('height', bbox.height + 20)\n g.appendChild(rect)\n\n // 缩放手柄(右下角)\n const scaleHandle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n scaleHandle.setAttribute('class', 'ae-transform-handle')\n scaleHandle.setAttribute('cx', bbox.maxX + 10)\n scaleHandle.setAttribute('cy', bbox.maxY + 10)\n scaleHandle.setAttribute('r', 6)\n scaleHandle.setAttribute('data-handle', 'scale')\n g.appendChild(scaleHandle)\n\n // 旋转手柄(顶部中间)\n const rotateY = bbox.minY - 30\n const rotateX = bbox.centerX\n const rotateLine = document.createElementNS('http://www.w3.org/2000/svg', 'line')\n rotateLine.setAttribute('class', 'ae-rotate-line')\n rotateLine.setAttribute('x1', bbox.centerX)\n rotateLine.setAttribute('y1', bbox.minY - 10)\n rotateLine.setAttribute('x2', rotateX)\n rotateLine.setAttribute('y2', rotateY)\n g.appendChild(rotateLine)\n\n const rotateHandle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n rotateHandle.setAttribute('class', 'ae-rotate-handle')\n rotateHandle.setAttribute('cx', rotateX)\n rotateHandle.setAttribute('cy', rotateY)\n rotateHandle.setAttribute('r', 8)\n rotateHandle.setAttribute('data-handle', 'rotate')\n g.appendChild(rotateHandle)\n }\n\n return g\n }\n\n render() {\n this.svg.querySelectorAll('g').forEach(g => g.remove())\n\n this.arrows.forEach((arrow, index) => {\n const g = this._createArrowGroup(arrow, index)\n this.svg.appendChild(g)\n })\n\n if (this.current) {\n const g = this._createArrowGroup(this.current, this.arrows.length)\n this.svg.appendChild(g)\n }\n }\n\n _isDoubleClick(p) {\n const now = Date.now()\n const dt = now - this.lastClickTime\n this.lastClickTime = now\n\n if (dt < 300 && this.lastClickPos && Math.hypot(p.x - this.lastClickPos.x, p.y - this.lastClickPos.y) < 10) {\n this.lastClickPos = null\n return true\n }\n\n this.lastClickPos = p\n return false\n }\n\n _handleClick(p) {\n // 如果刚才有拖拽,阻止点击事件\n if (this._shouldBlockClick) {\n this._shouldBlockClick = false\n return\n }\n\n if (this._isDoubleClick(p)) {\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n return\n }\n\n // 有选中的箭头时,点击空白处取消选中\n if (this.selected) {\n for (const a of this.arrows) {\n if (this._hitArrow(a, p)) {\n this.render()\n return\n }\n }\n // 点击空白处,取消选中\n this.selected = null\n this._hideToolbar()\n this.render()\n return\n }\n\n // 没有选中时,检查是否点击到箭头\n for (const a of this.arrows) {\n if (this._hitArrow(a, p)) {\n this.selected = a\n this._showToolbar()\n this.render()\n return\n }\n }\n\n // 点击空白处\n if (this.drawing) {\n // 正在绘制中,添加点\n this.current.points.push(p)\n } else {\n // 开始绘制\n this.drawing = true\n this.current = {\n points: [p, p],\n color: this._defaultColor\n }\n }\n\n this.render()\n }\n\n _handleEnter() {\n // 正在绘制时,按 Enter 完成绘制\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n }\n\n _handleEsc() {\n // 按 Esc: 结束绘制、取消选中\n if (this.drawing) {\n this.drawing = false\n this.current = null\n }\n if (this.selected) {\n this.selected = null\n }\n this._hideColorPicker()\n this._hideToolbar()\n this.render()\n }\n\n _showColorPicker(e) {\n if (this._showingColorPicker) {\n this._hideColorPicker()\n return\n }\n\n this._showingColorPicker = true\n\n // 创建颜色选择器浮窗\n const popup = document.createElement('div')\n popup.className = 'ae-color-picker-popup'\n\n const label = document.createElement('span')\n label.textContent = '选择颜色'\n label.style.cssText = 'font-size: 12px; color: #666;'\n\n const colorInput = document.createElement('input')\n colorInput.type = 'color'\n colorInput.value = this.selected.color || this._defaultColor\n // 自动打开颜色选择器\n colorInput.showPicker()\n\n popup.appendChild(label)\n popup.appendChild(colorInput)\n\n // 定位到颜色手柄位置\n const rect = this.container.getBoundingClientRect()\n const bbox = this._getArrowBBox(this.selected)\n const x = rect.left + bbox.minX - 50\n const y = rect.top + bbox.maxY + 15\n\n popup.style.left = x + 'px'\n popup.style.top = y + 'px'\n\n // 颜色改变时实时更新\n colorInput.addEventListener('input', (ev) => {\n this.selected.color = ev.target.value\n this._defaultColor = ev.target.value\n this.render()\n })\n\n // 点击外部关闭\n const closeHandler = (ev) => {\n if (!popup.contains(ev.target)) {\n this._hideColorPicker()\n document.removeEventListener('click', closeHandler)\n }\n }\n\n document.body.appendChild(popup)\n this._colorPickerPopup = popup\n\n document.addEventListener('click', closeHandler)\n }\n\n _hideColorPicker() {\n if (this._colorPickerPopup) {\n this._colorPickerPopup.remove()\n this._colorPickerPopup = null\n }\n this._showingColorPicker = false\n }\n\n // 删除选中的箭头\n deleteSelected() {\n if (this.selected) {\n this.arrows = this.arrows.filter(a => a !== this.selected)\n this.selected = null\n this.render()\n }\n }\n\n _handleMouseMove(e, p) {\n // 如果正在拖拽工具条,不处理\n if (this._toolbarDragging) {\n return\n }\n\n // 如果鼠标在工具条上,不处理\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n\n if (this.drawing) {\n this.current.points[this.current.points.length - 1] = p\n this.render()\n }\n\n // 变换处理(旋转/缩放)\n if (this._transformMode && this.selected) {\n if (this._transformMode === 'rotate') {\n this._handleRotate(p)\n } else if (this._transformMode === 'scale') {\n this._handleScale(p)\n }\n this.render()\n return\n }\n\n if (this.selected && this.mode === 'move') {\n const dx = e.movementX\n const dy = e.movementY\n\n // 如果有移动,标记需要阻止点击\n if (dx !== 0 || dy !== 0) {\n this._shouldBlockClick = true\n }\n\n this.selected.points.forEach(pt => {\n pt.x += dx\n pt.y += dy\n })\n\n this.render()\n }\n }\n\n _getArrowBBox(arrow) {\n const points = arrow.points\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity\n\n for (const pt of points) {\n minX = Math.min(minX, pt.x)\n minY = Math.min(minY, pt.y)\n maxX = Math.max(maxX, pt.x)\n maxY = Math.max(maxY, pt.y)\n }\n\n return {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n centerX: (minX + maxX) / 2,\n centerY: (minY + maxY) / 2\n }\n }\n\n _handleRotate(p) {\n const center = this._transformCenter\n const centerX = center.centerX\n const centerY = center.centerY\n\n // 计算当前角度和起始角度\n const currentAngle = Math.atan2(p.y - centerY, p.x - centerX)\n const startAngle = Math.atan2(this._transformStartPos.y - centerY, this._transformStartPos.x - centerX)\n const angleDiff = currentAngle - startAngle\n\n // 旋转点\n const cos = Math.cos(angleDiff)\n const sin = Math.sin(angleDiff)\n\n this.selected.points.forEach((pt, i) => {\n const relX = this._transformStartPoints[i].x - centerX\n const relY = this._transformStartPoints[i].y - centerY\n pt.x = centerX + relX * cos - relY * sin\n pt.y = centerY + relX * sin + relY * cos\n })\n }\n\n _handleScale(p) {\n const center = this._transformCenter\n const centerX = center.centerX\n const centerY = center.centerY\n const startPoints = this._transformStartPoints\n const startPos = this._transformStartPos\n\n // 计算缩放比例\n const dx = p.x - centerX\n const dy = p.y - centerY\n const startDx = startPos.x - centerX\n const startDy = startPos.y - centerY\n\n const currentDist = Math.hypot(dx, dy)\n const startDist = Math.hypot(startDx, startDy)\n const scale = currentDist / startDist\n\n // 应用缩放\n this.selected.points.forEach((pt, i) => {\n pt.x = centerX + (startPoints[i].x - centerX) * scale\n pt.y = centerY + (startPoints[i].y - centerY) * scale\n })\n }\n\n _hitArrow(a, p) {\n for (let i = 0; i < a.points.length - 1; i++) {\n if (this._dist(p, a.points[i], a.points[i + 1]) < 15)\n return true\n }\n return false\n }\n\n _dist(p, a, b) {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const t = ((p.x - a.x) * dx + (p.y - a.y) * dy) / (dx * dx + dy * dy)\n const tt = Math.max(0, Math.min(1, t))\n const px = a.x + tt * dx\n const py = a.y + tt * dy\n return Math.hypot(p.x - px, p.y - py)\n }\n\n // 获取所有箭头数据\n getData() {\n return this.arrows.map(arrow => ({\n points: arrow.points,\n curveRate: arrow.curveRate ?? arrow.cornerRoundness ?? 0,\n strokeWidth: arrow.strokeWidth,\n color: arrow.color\n }))\n }\n\n // 设置箭头数据\n setData(data) {\n this.arrows = data.map(item => ({\n points: item.points,\n curveRate: item.curveRate ?? 0,\n strokeWidth: item.strokeWidth ?? 8,\n color: item.color\n }))\n this.render()\n }\n\n // 清空所有箭头\n clear() {\n this.arrows = []\n this.drawing = false\n this.current = null\n this.selected = null\n this.render()\n }\n}\n"],"names":["STYLES","styleEl","ArrowEditor","container","defs","marker","polygon","color","strokeWidth","curveRate","e","strokeInput","strokeValue","dragHandle","isDragging","dragOffset","rect","onMove","moveEvent","containerRect","newLeft","newTop","toolbarWidth","toolbarHeight","onUp","colorInput","roundInput","bbox","left","top","Keybinding","p","handle","pt","center","dx","dy","r","pts","d","i","curr","next","len","inDx","inDy","prev","outDx","outDy","after","inLen","outLen","uxIn","uyIn","uxOut","uyOut","controlDist","cp1X","cp1Y","cp2X","cp2Y","last","ux","uy","notchX","notchY","scale","baseLen","baseWidth","notchLen","tipX","tipY","baseX","baseY","px","py","leftX","leftY","rightX","rightY","arrow","index","g","path","arrowHead","scaleHandle","rotateY","rotateX","rotateLine","rotateHandle","now","dt","a","popup","label","x","y","ev","closeHandler","points","minX","minY","maxX","maxY","centerX","centerY","currentAngle","startAngle","angleDiff","cos","sin","relX","relY","startPoints","startPos","startDx","startDy","currentDist","startDist","b","t","tt","data","item"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bundle.cjs.js","sources":["../src/editor.js"],"sourcesContent":["import { Keybinding } from '@wbiokr/keybinding'\n\n// 样式注入\nconst STYLES = `\n.ae-d2-container {\n position: relative;\n width: 1000px;\n height: 600px;\n background: #fff;\n margin: auto;\n}\n\n.ae-d2-svg {\n width: 100%;\n height: 100%;\n}\n\n.ae-arrow-path {\n fill: none;\n stroke-linecap: round;\n stroke-linejoin: round;\n cursor: pointer;\n}\n\n.ae-arrow-path:hover {\n stroke: #00aaff;\n}\n\n.ae-transform-box {\n fill: none;\n stroke: #00aaff;\n stroke-width: 2;\n stroke-dasharray: 4;\n}\n\n.ae-transform-handle {\n fill: #fff;\n stroke: #00aaff;\n stroke-width: 2;\n cursor: pointer;\n}\n\n.ae-transform-handle:hover {\n fill: #00aaff;\n}\n\n.ae-rotate-handle {\n fill: #fff;\n stroke: #ff6600;\n stroke-width: 2;\n cursor: grab;\n}\n\n.ae-rotate-handle:hover {\n fill: #ff6600;\n}\n\n.ae-rotate-line {\n stroke: #ff6600;\n stroke-width: 1;\n stroke-dasharray: 4;\n}\n\n/* 工具条样式 */\n.ae-toolbar {\n position: absolute;\n display: none;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0,0,0,0.15);\n z-index: 1000;\n pointer-events: auto;\n min-width: 140px;\n}\n\n.ae-toolbar-drag-handle {\n cursor: grab;\n text-align: center;\n padding: 4px;\n color: #999;\n font-size: 14px;\n line-height: 1;\n user-select: none;\n border-bottom: 1px solid #eee;\n margin: -12px -12px 8px -12px;\n padding-top: 8px;\n padding-bottom: 8px;\n border-radius: 8px 8px 0 0;\n}\n\n.ae-toolbar-drag-handle:active {\n cursor: grabbing;\n}\n\n.ae-toolbar-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ae-toolbar-label {\n font-size: 11px;\n color: #666;\n}\n\n.ae-toolbar input[type=\"color\"] {\n width: 40px;\n height: 30px;\n border: 1px solid #ddd;\n border-radius: 4px;\n cursor: pointer;\n padding: 0;\n background: none;\n}\n\n.ae-toolbar input[type=\"range\"] {\n width: 120px;\n cursor: pointer;\n}\n\n.ae-toolbar-value {\n font-size: 10px;\n color: #999;\n text-align: right;\n}\n`\n\n// 注入样式\nif (typeof document !== 'undefined') {\n const styleEl = document.createElement('style')\n styleEl.textContent = STYLES\n document.head.appendChild(styleEl)\n}\n\nexport class ArrowEditor {\n\n constructor(container, options = {}) {\n this.container = typeof container === 'string' ? document.querySelector(container) : container\n this.svg = null\n\n this.arrows = []\n this.drawing = false\n this.current = null\n this.selected = null\n this.mode = null\n this.lastClickTime = 0\n this.lastClickPos = null\n this._shouldBlockClick = false\n this._defaultColor = '#2b8cff'\n\n // 配置选项\n this.isCtrl = options.isCtrl || false\n this.stopPropagation = options.stopPropagation || false\n this.preventDefault = options.preventDefault || false\n\n // 变换相关\n this._transformMode = null // 'rotate' | 'scale'\n this._transformHandle = null\n this._transformStartPos = null\n this._transformStartPoints = null\n this._transformCenter = null\n this._transformStartAngle = null\n this._rotationOffset = 0\n\n // 工具条相关\n this._toolbar = null\n this._strokeWidth = 8\n this._curveRate = 0\n\n this._createSVG()\n this._initKeybindings()\n this._initEvents()\n }\n\n _createSVG() {\n // 创建 SVG 元素\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n this.svg.setAttribute('class', 'ae-d2-svg')\n this.container.appendChild(this.svg)\n\n // 创建 defs 和 marker\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs')\n this.svg.appendChild(defs)\n\n const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker')\n marker.setAttribute('id', 'ae-arrowhead')\n marker.setAttribute('markerWidth', '10')\n marker.setAttribute('markerHeight', '10')\n marker.setAttribute('refX', '9')\n marker.setAttribute('refY', '5')\n marker.setAttribute('orient', 'auto')\n\n const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon')\n polygon.setAttribute('points', '0,0 10,5 0,10 2,5')\n polygon.setAttribute('fill', this._defaultColor)\n\n marker.appendChild(polygon)\n defs.appendChild(marker)\n }\n\n _createToolbar() {\n if (this._toolbar) {\n this._toolbar.remove()\n }\n\n this._toolbar = document.createElement('div')\n this._toolbar.className = 'ae-toolbar'\n\n const color = this.selected.color || this._defaultColor\n const strokeWidth = this.selected.strokeWidth || this._strokeWidth\n const curveRate = this.selected.curveRate ?? this.selected.cornerRoundness ?? 0\n\n this._toolbar.innerHTML = `\n <div class=\"ae-toolbar-drag-handle\">:::</div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">颜色</span>\n <input type=\"color\" class=\"ae-color-input\" value=\"${color}\" />\n </div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">粗细</span>\n <input type=\"range\" class=\"ae-stroke-input\" min=\"1\" max=\"60\" value=\"${strokeWidth}\" />\n <span class=\"ae-toolbar-value\">${strokeWidth}px</span>\n </div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">曲线率</span>\n <input type=\"range\" class=\"ae-round-input\" min=\"0\" max=\"1\" step=\"0.1\" value=\"${curveRate}\" />\n </div>\n `\n\n // 颜色选择\n const colorInput = this._toolbar.querySelector('.ae-color-input')\n colorInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.color = e.target.value\n this._defaultColor = e.target.value\n this._updateMarkerColor(e.target.value)\n this.render()\n })\n\n // 粗细调整\n const strokeInput = this._toolbar.querySelector('.ae-stroke-input')\n const strokeValue = this._toolbar.querySelector('.ae-stroke-input + .ae-toolbar-value')\n strokeInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.strokeWidth = parseInt(e.target.value)\n strokeValue.textContent = e.target.value + 'px'\n this.render()\n })\n\n // 曲线率调整\n const roundInput = this._toolbar.querySelector('.ae-round-input')\n roundInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.curveRate = parseFloat(e.target.value)\n this.render()\n })\n\n // 拖拽功能 - 使用类实例绑定\n const dragHandle = this._toolbar.querySelector('.ae-toolbar-drag-handle')\n this._setupToolbarDrag(dragHandle)\n\n // 阻止工具条上的事件触发到容器\n this._toolbar.addEventListener('mousedown', (e) => {\n e.stopPropagation()\n })\n this._toolbar.addEventListener('mouseup', (e) => {\n e.stopPropagation()\n })\n\n this.container.appendChild(this._toolbar)\n }\n\n // 工具条拖拽设置\n _setupToolbarDrag(dragHandle) {\n let isDragging = false\n let dragOffset = { x: 0, y: 0 }\n\n dragHandle.addEventListener('mousedown', (e) => {\n isDragging = true\n this._toolbarDragging = true\n const rect = this._toolbar.getBoundingClientRect()\n dragOffset.x = e.clientX - rect.left\n dragOffset.y = e.clientY - rect.top\n e.preventDefault()\n e.stopPropagation()\n\n const onMove = (moveEvent) => {\n if (!isDragging) return\n const containerRect = this.container.getBoundingClientRect()\n let newLeft = moveEvent.clientX - containerRect.left - dragOffset.x\n let newTop = moveEvent.clientY - containerRect.top - dragOffset.y\n const toolbarWidth = this._toolbar.offsetWidth\n const toolbarHeight = this._toolbar.offsetHeight\n newLeft = Math.max(0, Math.min(newLeft, containerRect.width - toolbarWidth))\n newTop = Math.max(0, Math.min(newTop, containerRect.height - toolbarHeight))\n this._toolbar.style.left = newLeft + 'px'\n this._toolbar.style.top = newTop + 'px'\n }\n\n const onUp = (e) => {\n isDragging = false\n this._toolbarDragging = false\n document.removeEventListener('mousemove', onMove)\n document.removeEventListener('mouseup', onUp)\n this._toolbar.removeEventListener('mouseup', onUp)\n \n e.preventDefault()\n e.stopPropagation()\n }\n\n document.addEventListener('mousemove', onMove)\n document.addEventListener('mouseup', onUp)\n\n this._toolbar.addEventListener('mouseup', onUp)\n })\n }\n\n _showToolbar() {\n if (this.selected) {\n if (!this._toolbar) {\n this._createToolbar()\n }\n this._toolbar.style.display = 'flex'\n\n // 更新工具条值\n const color = this.selected.color || this._defaultColor\n const strokeWidth = this.selected.strokeWidth || this._strokeWidth\n const curveRate = this.selected.curveRate ?? this.selected.cornerRoundness ?? 0\n\n const colorInput = this._toolbar.querySelector('.ae-color-input')\n const strokeInput = this._toolbar.querySelector('.ae-stroke-input')\n const strokeValue = this._toolbar.querySelector('.ae-stroke-input + .ae-toolbar-value')\n const roundInput = this._toolbar.querySelector('.ae-round-input')\n\n if (colorInput) colorInput.value = color\n if (strokeInput) {\n strokeInput.value = strokeWidth\n strokeValue.textContent = strokeWidth + 'px'\n }\n if (roundInput) roundInput.value = curveRate\n\n // 定位到所选箭头旁边\n const bbox = this._getArrowBBox(this.selected)\n const toolbarWidth = this._toolbar.offsetWidth || 150\n const toolbarHeight = this._toolbar.offsetHeight || 120\n\n // 计算位置:放在箭头右侧,如果空间不够则放左侧\n let left = bbox.maxX + 20\n if (left + toolbarWidth > this.container.offsetWidth) {\n left = bbox.minX - toolbarWidth - 20\n }\n\n // 垂直居中于箭头\n let top = bbox.centerY - toolbarHeight / 2\n if (top < 0) top = 0\n if (top + toolbarHeight > this.container.offsetHeight) {\n top = this.container.offsetHeight - toolbarHeight\n }\n\n this._toolbar.style.left = left + 'px'\n this._toolbar.style.top = top + 'px'\n }\n }\n\n _hideToolbar() {\n if (this._toolbar) {\n this._toolbar.style.display = 'none'\n }\n }\n\n _updateMarkerColor(color) {\n const marker = this.svg.querySelector('#ae-arrowhead polygon')\n if (marker) {\n marker.setAttribute('fill', color)\n }\n }\n\n _initKeybindings() {\n // 创建快捷键实例,绑定到 container 上\n this._kb = new Keybinding('arrow-editor')\n\n // Enter: 完成绘制\n this._kb.on('enter', () => {\n this._handleEnter()\n })\n\n // Esc: 结束绘制、取消选中\n this._kb.on('esc', () => {\n this._handleEsc()\n })\n }\n\n _initEvents() {\n this.container.onclick = e => {\n // 点击工具条时不处理\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n if (this.preventDefault) e.preventDefault()\n if (this.stopPropagation) e.stopPropagation()\n const p = this._mousePos(e)\n this._handleClick(p, e)\n }\n\n this.container.onmousemove = e => {\n if (this.preventDefault) e.preventDefault()\n if (this.stopPropagation) e.stopPropagation()\n const p = this._mousePos(e)\n this._handleMouseMove(e, p)\n }\n\n this.container.onmousedown = e => {\n // 点击工具条不触发移动\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n\n if (this.preventDefault) e.preventDefault()\n if (this.stopPropagation) e.stopPropagation()\n\n if (this.selected) {\n const handle = e.target.getAttribute('data-handle')\n if (handle) {\n this._transformMode = handle\n this._transformHandle = handle\n const p = this._mousePos(e)\n this._transformStartPos = p\n this._transformStartPoints = this.selected.points.map(pt => ({ x: pt.x, y: pt.y }))\n this._transformCenter = this._getArrowBBox(this.selected)\n\n if (handle === 'rotate') {\n const center = this._transformCenter\n const dx = p.x - center.centerX\n const dy = p.y - center.centerY\n this._transformStartAngle = Math.atan2(dy, dx)\n this._rotationOffset = 0\n }\n\n e.stopPropagation()\n return\n }\n\n this.mode = 'move'\n }\n }\n\n this.container.onmouseup = () => {\n this.mode = null\n this._transformMode = null\n this._transformHandle = null\n }\n }\n\n _mousePos(e) {\n const r = this.container.getBoundingClientRect()\n return {\n x: e.clientX - r.left,\n y: e.clientY - r.top\n }\n }\n\n _generatePath(pts, curveRate = 0) {\n if (pts.length < 2) return ''\n\n // curveRate 为 0 时画直线\n if (curveRate === 0) {\n let d = `M ${pts[0].x} ${pts[0].y}`\n for (let i = 1; i < pts.length; i++) {\n d += ` L ${pts[i].x} ${pts[i].y}`\n }\n return d\n }\n\n // 根据曲线率计算控制点位置\n // curveRate: 0 - 直线,1 - 最弯曲\n let d = `M ${pts[0].x} ${pts[0].y}`\n\n for (let i = 0; i < pts.length - 1; i++) {\n const curr = pts[i]\n const next = pts[i + 1]\n\n // 计算当前线段的向量\n const dx = next.x - curr.x\n const dy = next.y - curr.y\n const len = Math.hypot(dx, dy)\n\n if (len === 0) continue\n\n // 计算进入当前点的切线向量(前一段线段)\n let inDx = dx\n let inDy = dy\n\n if (i > 0) {\n const prev = pts[i - 1]\n inDx = curr.x - prev.x\n inDy = curr.y - prev.y\n }\n\n // 计算出当前点的切线向量(下一段线段)\n let outDx = dx\n let outDy = dy\n\n if (i < pts.length - 2) {\n const after = pts[i + 2]\n outDx = after.x - next.x\n outDy = after.y - next.y\n }\n\n // 单位向量\n const inLen = Math.hypot(inDx, inDy) || 1\n const outLen = Math.hypot(outDx, outDy) || 1\n const uxIn = inDx / inLen\n const uyIn = inDy / inLen\n const uxOut = outDx / outLen\n const uyOut = outDy / outLen\n\n // 控制点距离:曲线率 * 线段长度 * 系数\n const controlDist = len * curveRate * 0.3\n\n // 第一个控制点:从当前点沿进入方向的切线\n const cp1X = curr.x + uxIn * controlDist\n const cp1Y = curr.y + uyIn * controlDist\n\n // 第二个控制点:从下一个点沿出去方向的切线反方向\n const cp2X = next.x - uxOut * controlDist\n const cp2Y = next.y - uyOut * controlDist\n\n d += ` C ${cp1X} ${cp1Y} ${cp2X} ${cp2Y} ${next.x} ${next.y}`\n }\n\n return d\n }\n\n _generateArrowHead(pts, strokeWidth = 8) {\n if (pts.length < 2) return ''\n\n const last = pts[pts.length - 1]\n let prev = pts[pts.length - 2]\n\n if (pts.length >= 3) {\n const dist = Math.hypot(last.x - prev.x, last.y - prev.y)\n if (dist < 5) {\n prev = pts[pts.length - 3]\n }\n }\n\n const dx = last.x - prev.x\n const dy = last.y - prev.y\n const len = Math.hypot(dx, dy)\n\n if (len < 1) return ''\n\n const ux = dx / len\n const uy = dy / len\n\n const notchX = last.x\n const notchY = last.y\n\n // 根据粗细调整箭头大小\n const scale = strokeWidth / 8\n const baseLen = 40 * scale\n const baseWidth = 20 * scale\n const notchLen = 20 * scale\n\n const tipX = last.x + ux * notchLen\n const tipY = last.y + uy * notchLen\n const baseX = last.x - ux * (baseLen - notchLen)\n const baseY = last.y - uy * (baseLen - notchLen)\n\n const px = -uy\n const py = ux\n\n const leftX = baseX + px * baseWidth\n const leftY = baseY + py * baseWidth\n const rightX = baseX - px * baseWidth\n const rightY = baseY - py * baseWidth\n\n return `M ${tipX} ${tipY} L ${leftX} ${leftY} L ${notchX} ${notchY} L ${rightX} ${rightY} Z`\n }\n\n _createArrowGroup(arrow, index) {\n const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')\n g.setAttribute('data-index', index)\n\n const color = arrow.color || this._defaultColor\n const strokeWidth = arrow.strokeWidth || this._strokeWidth\n const curveRate = arrow.curveRate ?? arrow.cornerRoundness ?? 0\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('class', 'ae-arrow-path')\n path.style.stroke = color\n path.style.strokeWidth = strokeWidth + 'px'\n path.setAttribute('d', this._generatePath(arrow.points, curveRate))\n g.appendChild(path)\n\n const arrowHead = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n arrowHead.setAttribute('fill', color)\n arrowHead.setAttribute('d', this._generateArrowHead(arrow.points, strokeWidth))\n g.appendChild(arrowHead)\n\n if (arrow === this.selected) {\n const bbox = this._getArrowBBox(arrow)\n\n // 变换框\n const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\n rect.setAttribute('class', 'ae-transform-box')\n rect.setAttribute('x', bbox.minX - 10)\n rect.setAttribute('y', bbox.minY - 10)\n rect.setAttribute('width', bbox.width + 20)\n rect.setAttribute('height', bbox.height + 20)\n g.appendChild(rect)\n\n // 缩放手柄(右下角)\n const scaleHandle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n scaleHandle.setAttribute('class', 'ae-transform-handle')\n scaleHandle.setAttribute('cx', bbox.maxX + 10)\n scaleHandle.setAttribute('cy', bbox.maxY + 10)\n scaleHandle.setAttribute('r', 6)\n scaleHandle.setAttribute('data-handle', 'scale')\n g.appendChild(scaleHandle)\n\n // 旋转手柄(顶部中间)\n const rotateY = bbox.minY - 30\n const rotateX = bbox.centerX\n const rotateLine = document.createElementNS('http://www.w3.org/2000/svg', 'line')\n rotateLine.setAttribute('class', 'ae-rotate-line')\n rotateLine.setAttribute('x1', bbox.centerX)\n rotateLine.setAttribute('y1', bbox.minY - 10)\n rotateLine.setAttribute('x2', rotateX)\n rotateLine.setAttribute('y2', rotateY)\n g.appendChild(rotateLine)\n\n const rotateHandle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n rotateHandle.setAttribute('class', 'ae-rotate-handle')\n rotateHandle.setAttribute('cx', rotateX)\n rotateHandle.setAttribute('cy', rotateY)\n rotateHandle.setAttribute('r', 8)\n rotateHandle.setAttribute('data-handle', 'rotate')\n g.appendChild(rotateHandle)\n }\n\n return g\n }\n\n render() {\n this.svg.querySelectorAll('g').forEach(g => g.remove())\n\n this.arrows.forEach((arrow, index) => {\n const g = this._createArrowGroup(arrow, index)\n this.svg.appendChild(g)\n })\n\n if (this.current) {\n const g = this._createArrowGroup(this.current, this.arrows.length)\n this.svg.appendChild(g)\n }\n }\n\n _isDoubleClick(p) {\n const now = Date.now()\n const dt = now - this.lastClickTime\n this.lastClickTime = now\n\n if (dt < 300 && this.lastClickPos && Math.hypot(p.x - this.lastClickPos.x, p.y - this.lastClickPos.y) < 10) {\n this.lastClickPos = null\n return true\n }\n\n this.lastClickPos = p\n return false\n }\n\n _handleClick(p, e) {\n // 如果配置了 isCtrl,需要按着 Ctrl 键才能绘制\n if (this.isCtrl && !e.ctrlKey) {\n return\n }\n\n // 如果刚才有拖拽,阻止点击事件\n if (this._shouldBlockClick) {\n this._shouldBlockClick = false\n return\n }\n\n if (this._isDoubleClick(p)) {\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n return\n }\n\n // 有选中的箭头时,点击空白处取消选中\n if (this.selected) {\n for (const a of this.arrows) {\n if (this._hitArrow(a, p)) {\n this.render()\n return\n }\n }\n // 点击空白处,取消选中\n this.selected = null\n this._hideToolbar()\n this.render()\n return\n }\n\n // 没有选中时,检查是否点击到箭头\n for (const a of this.arrows) {\n if (this._hitArrow(a, p)) {\n this.selected = a\n this._showToolbar()\n this.render()\n return\n }\n }\n\n // 点击空白处\n if (this.drawing) {\n // 正在绘制中,添加点\n this.current.points.push(p)\n } else {\n // 开始绘制\n this.drawing = true\n this.current = {\n points: [p, p],\n color: this._defaultColor\n }\n }\n\n this.render()\n }\n\n _handleEnter() {\n // 正在绘制时,按 Enter 完成绘制\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n }\n\n _handleEsc() {\n // 按 Esc: 结束绘制、取消选中\n if (this.drawing) {\n this.drawing = false\n this.current = null\n }\n if (this.selected) {\n this.selected = null\n }\n this._hideColorPicker()\n this._hideToolbar()\n this.render()\n }\n\n _showColorPicker(e) {\n if (this._showingColorPicker) {\n this._hideColorPicker()\n return\n }\n\n this._showingColorPicker = true\n\n // 创建颜色选择器浮窗\n const popup = document.createElement('div')\n popup.className = 'ae-color-picker-popup'\n\n const label = document.createElement('span')\n label.textContent = '选择颜色'\n label.style.cssText = 'font-size: 12px; color: #666;'\n\n const colorInput = document.createElement('input')\n colorInput.type = 'color'\n colorInput.value = this.selected.color || this._defaultColor\n // 自动打开颜色选择器\n colorInput.showPicker()\n\n popup.appendChild(label)\n popup.appendChild(colorInput)\n\n // 定位到颜色手柄位置\n const rect = this.container.getBoundingClientRect()\n const bbox = this._getArrowBBox(this.selected)\n const x = rect.left + bbox.minX - 50\n const y = rect.top + bbox.maxY + 15\n\n popup.style.left = x + 'px'\n popup.style.top = y + 'px'\n\n // 颜色改变时实时更新\n colorInput.addEventListener('input', (ev) => {\n this.selected.color = ev.target.value\n this._defaultColor = ev.target.value\n this.render()\n })\n\n // 点击外部关闭\n const closeHandler = (ev) => {\n if (!popup.contains(ev.target)) {\n this._hideColorPicker()\n document.removeEventListener('click', closeHandler)\n }\n }\n\n document.body.appendChild(popup)\n this._colorPickerPopup = popup\n\n document.addEventListener('click', closeHandler)\n }\n\n _hideColorPicker() {\n if (this._colorPickerPopup) {\n this._colorPickerPopup.remove()\n this._colorPickerPopup = null\n }\n this._showingColorPicker = false\n }\n\n // 删除选中的箭头\n deleteSelected() {\n if (this.selected) {\n this.arrows = this.arrows.filter(a => a !== this.selected)\n this.selected = null\n this.render()\n }\n }\n\n _handleMouseMove(e, p) {\n // 如果正在拖拽工具条,不处理\n if (this._toolbarDragging) {\n return\n }\n\n // 如果鼠标在工具条上,不处理\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n\n // 如果配置了 isCtrl,需要按着 Ctrl 键才能绘制\n if (this.isCtrl && !e.ctrlKey) {\n // 如果正在绘制中,按 Ctrl 键松开则结束绘制\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n return\n }\n\n if (this.drawing) {\n this.current.points[this.current.points.length - 1] = p\n this.render()\n }\n\n // 变换处理(旋转/缩放)\n if (this._transformMode && this.selected) {\n if (this._transformMode === 'rotate') {\n this._handleRotate(p)\n } else if (this._transformMode === 'scale') {\n this._handleScale(p)\n }\n this.render()\n return\n }\n\n if (this.selected && this.mode === 'move') {\n const dx = e.movementX\n const dy = e.movementY\n\n // 如果有移动,标记需要阻止点击\n if (dx !== 0 || dy !== 0) {\n this._shouldBlockClick = true\n }\n\n this.selected.points.forEach(pt => {\n pt.x += dx\n pt.y += dy\n })\n\n this.render()\n }\n }\n\n _getArrowBBox(arrow) {\n const points = arrow.points\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity\n\n for (const pt of points) {\n minX = Math.min(minX, pt.x)\n minY = Math.min(minY, pt.y)\n maxX = Math.max(maxX, pt.x)\n maxY = Math.max(maxY, pt.y)\n }\n\n return {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n centerX: (minX + maxX) / 2,\n centerY: (minY + maxY) / 2\n }\n }\n\n _handleRotate(p) {\n const center = this._transformCenter\n const centerX = center.centerX\n const centerY = center.centerY\n\n // 计算当前角度和起始角度\n const currentAngle = Math.atan2(p.y - centerY, p.x - centerX)\n const startAngle = Math.atan2(this._transformStartPos.y - centerY, this._transformStartPos.x - centerX)\n const angleDiff = currentAngle - startAngle\n\n // 旋转点\n const cos = Math.cos(angleDiff)\n const sin = Math.sin(angleDiff)\n\n this.selected.points.forEach((pt, i) => {\n const relX = this._transformStartPoints[i].x - centerX\n const relY = this._transformStartPoints[i].y - centerY\n pt.x = centerX + relX * cos - relY * sin\n pt.y = centerY + relX * sin + relY * cos\n })\n }\n\n _handleScale(p) {\n const center = this._transformCenter\n const centerX = center.centerX\n const centerY = center.centerY\n const startPoints = this._transformStartPoints\n const startPos = this._transformStartPos\n\n // 计算缩放比例\n const dx = p.x - centerX\n const dy = p.y - centerY\n const startDx = startPos.x - centerX\n const startDy = startPos.y - centerY\n\n const currentDist = Math.hypot(dx, dy)\n const startDist = Math.hypot(startDx, startDy)\n const scale = currentDist / startDist\n\n // 应用缩放\n this.selected.points.forEach((pt, i) => {\n pt.x = centerX + (startPoints[i].x - centerX) * scale\n pt.y = centerY + (startPoints[i].y - centerY) * scale\n })\n }\n\n _hitArrow(a, p) {\n for (let i = 0; i < a.points.length - 1; i++) {\n if (this._dist(p, a.points[i], a.points[i + 1]) < 15)\n return true\n }\n return false\n }\n\n _dist(p, a, b) {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const t = ((p.x - a.x) * dx + (p.y - a.y) * dy) / (dx * dx + dy * dy)\n const tt = Math.max(0, Math.min(1, t))\n const px = a.x + tt * dx\n const py = a.y + tt * dy\n return Math.hypot(p.x - px, p.y - py)\n }\n\n // 获取所有箭头数据\n getData() {\n return this.arrows.map(arrow => ({\n points: arrow.points,\n curveRate: arrow.curveRate ?? arrow.cornerRoundness ?? 0,\n strokeWidth: arrow.strokeWidth,\n color: arrow.color\n }))\n }\n\n // 设置箭头数据\n setData(data) {\n this.arrows = data.map(item => ({\n points: item.points,\n curveRate: item.curveRate ?? 0,\n strokeWidth: item.strokeWidth ?? 8,\n color: item.color\n }))\n this.render()\n }\n\n // 清空所有箭头\n clear() {\n this.arrows = []\n this.drawing = false\n this.current = null\n this.selected = null\n this.render()\n }\n}\n"],"names":["STYLES","styleEl","ArrowEditor","container","options","defs","marker","polygon","color","strokeWidth","curveRate","e","strokeInput","strokeValue","dragHandle","isDragging","dragOffset","rect","onMove","moveEvent","containerRect","newLeft","newTop","toolbarWidth","toolbarHeight","onUp","colorInput","roundInput","bbox","left","top","Keybinding","p","handle","pt","center","dx","dy","r","pts","d","i","curr","next","len","inDx","inDy","prev","outDx","outDy","after","inLen","outLen","uxIn","uyIn","uxOut","uyOut","controlDist","cp1X","cp1Y","cp2X","cp2Y","last","ux","uy","notchX","notchY","scale","baseLen","baseWidth","notchLen","tipX","tipY","baseX","baseY","px","py","leftX","leftY","rightX","rightY","arrow","index","g","path","arrowHead","scaleHandle","rotateY","rotateX","rotateLine","rotateHandle","now","dt","a","popup","label","x","y","ev","closeHandler","points","minX","minY","maxX","maxY","centerX","centerY","currentAngle","startAngle","angleDiff","cos","sin","relX","relY","startPoints","startPos","startDx","startDy","currentDist","startDist","b","t","tt","data","item"],"mappings":"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"}
|
package/dist/bundle.esm.js
CHANGED
|
@@ -130,9 +130,9 @@ if (typeof document < "u") {
|
|
|
130
130
|
const y = document.createElement("style");
|
|
131
131
|
y.textContent = E, document.head.appendChild(y);
|
|
132
132
|
}
|
|
133
|
-
class
|
|
134
|
-
constructor(t) {
|
|
135
|
-
this.container = typeof t == "string" ? document.querySelector(t) : t, this.svg = null, this.arrows = [], this.drawing = !1, this.current = null, this.selected = null, this.mode = null, this.lastClickTime = 0, this.lastClickPos = null, this._shouldBlockClick = !1, this._defaultColor = "#2b8cff", this._transformMode = null, this._transformHandle = null, this._transformStartPos = null, this._transformStartPoints = null, this._transformCenter = null, this._transformStartAngle = null, this._rotationOffset = 0, this._toolbar = null, this._strokeWidth = 8, this._curveRate = 0, this._createSVG(), this._initKeybindings(), this._initEvents();
|
|
133
|
+
class D {
|
|
134
|
+
constructor(t, e = {}) {
|
|
135
|
+
this.container = typeof t == "string" ? document.querySelector(t) : t, this.svg = null, this.arrows = [], this.drawing = !1, this.current = null, this.selected = null, this.mode = null, this.lastClickTime = 0, this.lastClickPos = null, this._shouldBlockClick = !1, this._defaultColor = "#2b8cff", this.isCtrl = e.isCtrl || !1, this.stopPropagation = e.stopPropagation || !1, this.preventDefault = e.preventDefault || !1, this._transformMode = null, this._transformHandle = null, this._transformStartPos = null, this._transformStartPoints = null, this._transformCenter = null, this._transformStartAngle = null, this._rotationOffset = 0, this._toolbar = null, this._strokeWidth = 8, this._curveRate = 0, this._createSVG(), this._initKeybindings(), this._initEvents();
|
|
136
136
|
}
|
|
137
137
|
_createSVG() {
|
|
138
138
|
this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.setAttribute("class", "ae-d2-svg"), this.container.appendChild(this.svg);
|
|
@@ -226,13 +226,15 @@ class X {
|
|
|
226
226
|
this.container.onclick = (t) => {
|
|
227
227
|
if (this._toolbar && (t.target === this._toolbar || this._toolbar.contains(t.target)))
|
|
228
228
|
return;
|
|
229
|
+
this.preventDefault && t.preventDefault(), this.stopPropagation && t.stopPropagation();
|
|
229
230
|
const e = this._mousePos(t);
|
|
230
|
-
this._handleClick(e);
|
|
231
|
+
this._handleClick(e, t);
|
|
231
232
|
}, this.container.onmousemove = (t) => {
|
|
233
|
+
this.preventDefault && t.preventDefault(), this.stopPropagation && t.stopPropagation();
|
|
232
234
|
const e = this._mousePos(t);
|
|
233
235
|
this._handleMouseMove(t, e);
|
|
234
236
|
}, this.container.onmousedown = (t) => {
|
|
235
|
-
if (!(this._toolbar && (t.target === this._toolbar || this._toolbar.contains(t.target))) && this.selected) {
|
|
237
|
+
if (!(this._toolbar && (t.target === this._toolbar || this._toolbar.contains(t.target))) && (this.preventDefault && t.preventDefault(), this.stopPropagation && t.stopPropagation(), this.selected)) {
|
|
236
238
|
const e = t.target.getAttribute("data-handle");
|
|
237
239
|
if (e) {
|
|
238
240
|
this._transformMode = e, this._transformHandle = e;
|
|
@@ -279,7 +281,7 @@ class X {
|
|
|
279
281
|
const m = t[s + 2];
|
|
280
282
|
d = m.x - i.x, u = m.y - i.y;
|
|
281
283
|
}
|
|
282
|
-
const p = Math.hypot(h, c) || 1, f = Math.hypot(d, u) || 1,
|
|
284
|
+
const p = Math.hypot(h, c) || 1, f = Math.hypot(d, u) || 1, v = h / p, w = c / p, b = d / f, _ = u / f, g = n * e * 0.3, x = r.x + v * g, k = r.y + w * g, C = i.x - b * g, A = i.y - _ * g;
|
|
283
285
|
o += ` C ${x} ${k} ${C} ${A} ${i.x} ${i.y}`;
|
|
284
286
|
}
|
|
285
287
|
return o;
|
|
@@ -291,8 +293,8 @@ class X {
|
|
|
291
293
|
t.length >= 3 && Math.hypot(o.x - s.x, o.y - s.y) < 5 && (s = t[t.length - 3]);
|
|
292
294
|
const r = o.x - s.x, i = o.y - s.y, a = Math.hypot(r, i);
|
|
293
295
|
if (a < 1) return "";
|
|
294
|
-
const l = r / a, n = i / a, h = o.x, c = o.y, d = e / 8, u = 40 * d, p = 20 * d, f = 20 * d,
|
|
295
|
-
return `M ${
|
|
296
|
+
const l = r / a, n = i / a, h = o.x, c = o.y, d = e / 8, u = 40 * d, p = 20 * d, f = 20 * d, v = o.x + l * f, w = o.y + n * f, b = o.x - l * (u - f), _ = o.y - n * (u - f), g = -n, x = l, k = b + g * p, C = _ + x * p, A = b - g * p, m = _ - x * p;
|
|
297
|
+
return `M ${v} ${w} L ${k} ${C} L ${h} ${c} L ${A} ${m} Z`;
|
|
296
298
|
}
|
|
297
299
|
_createArrowGroup(t, e) {
|
|
298
300
|
const o = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
@@ -325,33 +327,35 @@ class X {
|
|
|
325
327
|
const e = Date.now(), o = e - this.lastClickTime;
|
|
326
328
|
return this.lastClickTime = e, o < 300 && this.lastClickPos && Math.hypot(t.x - this.lastClickPos.x, t.y - this.lastClickPos.y) < 10 ? (this.lastClickPos = null, !0) : (this.lastClickPos = t, !1);
|
|
327
329
|
}
|
|
328
|
-
_handleClick(t) {
|
|
329
|
-
if (this.
|
|
330
|
-
this._shouldBlockClick
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
this.
|
|
330
|
+
_handleClick(t, e) {
|
|
331
|
+
if (!(this.isCtrl && !e.ctrlKey)) {
|
|
332
|
+
if (this._shouldBlockClick) {
|
|
333
|
+
this._shouldBlockClick = !1;
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
if (this._isDoubleClick(t)) {
|
|
337
|
+
this.drawing && this.current && this.current.points.length >= 2 && (this.drawing = !1, this.arrows.push(this.current), this.current = null, this.render());
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
if (this.selected) {
|
|
341
|
+
for (const o of this.arrows)
|
|
342
|
+
if (this._hitArrow(o, t)) {
|
|
343
|
+
this.render();
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
this.selected = null, this._hideToolbar(), this.render();
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
for (const o of this.arrows)
|
|
350
|
+
if (this._hitArrow(o, t)) {
|
|
351
|
+
this.selected = o, this._showToolbar(), this.render();
|
|
341
352
|
return;
|
|
342
353
|
}
|
|
343
|
-
this.
|
|
344
|
-
|
|
354
|
+
this.drawing ? this.current.points.push(t) : (this.drawing = !0, this.current = {
|
|
355
|
+
points: [t, t],
|
|
356
|
+
color: this._defaultColor
|
|
357
|
+
}), this.render();
|
|
345
358
|
}
|
|
346
|
-
for (const e of this.arrows)
|
|
347
|
-
if (this._hitArrow(e, t)) {
|
|
348
|
-
this.selected = e, this._showToolbar(), this.render();
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
this.drawing ? this.current.points.push(t) : (this.drawing = !0, this.current = {
|
|
352
|
-
points: [t, t],
|
|
353
|
-
color: this._defaultColor
|
|
354
|
-
}), this.render();
|
|
355
359
|
}
|
|
356
360
|
_handleEnter() {
|
|
357
361
|
this.drawing && this.current && this.current.points.length >= 2 && (this.drawing = !1, this.arrows.push(this.current), this.current = null, this.render());
|
|
@@ -389,6 +393,10 @@ class X {
|
|
|
389
393
|
}
|
|
390
394
|
_handleMouseMove(t, e) {
|
|
391
395
|
if (!this._toolbarDragging && !(this._toolbar && (t.target === this._toolbar || this._toolbar.contains(t.target)))) {
|
|
396
|
+
if (this.isCtrl && !t.ctrlKey) {
|
|
397
|
+
this.drawing && this.current && this.current.points.length >= 2 && (this.drawing = !1, this.arrows.push(this.current), this.current = null, this.render());
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
392
400
|
if (this.drawing && (this.current.points[this.current.points.length - 1] = e, this.render()), this._transformMode && this.selected) {
|
|
393
401
|
this._transformMode === "rotate" ? this._handleRotate(e) : this._transformMode === "scale" && this._handleScale(e), this.render();
|
|
394
402
|
return;
|
|
@@ -464,6 +472,6 @@ class X {
|
|
|
464
472
|
}
|
|
465
473
|
}
|
|
466
474
|
export {
|
|
467
|
-
|
|
475
|
+
D as ArrowEditor
|
|
468
476
|
};
|
|
469
477
|
//# sourceMappingURL=bundle.esm.js.map
|
package/dist/bundle.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.esm.js","sources":["../src/editor.js"],"sourcesContent":["import { Keybinding } from '@wbiokr/keybinding'\n\n// 样式注入\nconst STYLES = `\n.ae-d2-container {\n position: relative;\n width: 1000px;\n height: 600px;\n background: #fff;\n margin: auto;\n}\n\n.ae-d2-svg {\n width: 100%;\n height: 100%;\n}\n\n.ae-arrow-path {\n fill: none;\n stroke-linecap: round;\n stroke-linejoin: round;\n cursor: pointer;\n}\n\n.ae-arrow-path:hover {\n stroke: #00aaff;\n}\n\n.ae-transform-box {\n fill: none;\n stroke: #00aaff;\n stroke-width: 2;\n stroke-dasharray: 4;\n}\n\n.ae-transform-handle {\n fill: #fff;\n stroke: #00aaff;\n stroke-width: 2;\n cursor: pointer;\n}\n\n.ae-transform-handle:hover {\n fill: #00aaff;\n}\n\n.ae-rotate-handle {\n fill: #fff;\n stroke: #ff6600;\n stroke-width: 2;\n cursor: grab;\n}\n\n.ae-rotate-handle:hover {\n fill: #ff6600;\n}\n\n.ae-rotate-line {\n stroke: #ff6600;\n stroke-width: 1;\n stroke-dasharray: 4;\n}\n\n/* 工具条样式 */\n.ae-toolbar {\n position: absolute;\n display: none;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0,0,0,0.15);\n z-index: 1000;\n pointer-events: auto;\n min-width: 140px;\n}\n\n.ae-toolbar-drag-handle {\n cursor: grab;\n text-align: center;\n padding: 4px;\n color: #999;\n font-size: 14px;\n line-height: 1;\n user-select: none;\n border-bottom: 1px solid #eee;\n margin: -12px -12px 8px -12px;\n padding-top: 8px;\n padding-bottom: 8px;\n border-radius: 8px 8px 0 0;\n}\n\n.ae-toolbar-drag-handle:active {\n cursor: grabbing;\n}\n\n.ae-toolbar-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ae-toolbar-label {\n font-size: 11px;\n color: #666;\n}\n\n.ae-toolbar input[type=\"color\"] {\n width: 40px;\n height: 30px;\n border: 1px solid #ddd;\n border-radius: 4px;\n cursor: pointer;\n padding: 0;\n background: none;\n}\n\n.ae-toolbar input[type=\"range\"] {\n width: 120px;\n cursor: pointer;\n}\n\n.ae-toolbar-value {\n font-size: 10px;\n color: #999;\n text-align: right;\n}\n`\n\n// 注入样式\nif (typeof document !== 'undefined') {\n const styleEl = document.createElement('style')\n styleEl.textContent = STYLES\n document.head.appendChild(styleEl)\n}\n\nexport class ArrowEditor {\n\n constructor(container) {\n this.container = typeof container === 'string' ? document.querySelector(container) : container\n this.svg = null\n\n this.arrows = []\n this.drawing = false\n this.current = null\n this.selected = null\n this.mode = null\n this.lastClickTime = 0\n this.lastClickPos = null\n this._shouldBlockClick = false\n this._defaultColor = '#2b8cff'\n\n // 变换相关\n this._transformMode = null // 'rotate' | 'scale'\n this._transformHandle = null\n this._transformStartPos = null\n this._transformStartPoints = null\n this._transformCenter = null\n this._transformStartAngle = null\n this._rotationOffset = 0\n\n // 工具条相关\n this._toolbar = null\n this._strokeWidth = 8\n this._curveRate = 0\n\n this._createSVG()\n this._initKeybindings()\n this._initEvents()\n }\n\n _createSVG() {\n // 创建 SVG 元素\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n this.svg.setAttribute('class', 'ae-d2-svg')\n this.container.appendChild(this.svg)\n\n // 创建 defs 和 marker\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs')\n this.svg.appendChild(defs)\n\n const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker')\n marker.setAttribute('id', 'ae-arrowhead')\n marker.setAttribute('markerWidth', '10')\n marker.setAttribute('markerHeight', '10')\n marker.setAttribute('refX', '9')\n marker.setAttribute('refY', '5')\n marker.setAttribute('orient', 'auto')\n\n const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon')\n polygon.setAttribute('points', '0,0 10,5 0,10 2,5')\n polygon.setAttribute('fill', this._defaultColor)\n\n marker.appendChild(polygon)\n defs.appendChild(marker)\n }\n\n _createToolbar() {\n if (this._toolbar) {\n this._toolbar.remove()\n }\n\n this._toolbar = document.createElement('div')\n this._toolbar.className = 'ae-toolbar'\n\n const color = this.selected.color || this._defaultColor\n const strokeWidth = this.selected.strokeWidth || this._strokeWidth\n const curveRate = this.selected.curveRate ?? this.selected.cornerRoundness ?? 0\n\n this._toolbar.innerHTML = `\n <div class=\"ae-toolbar-drag-handle\">:::</div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">颜色</span>\n <input type=\"color\" class=\"ae-color-input\" value=\"${color}\" />\n </div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">粗细</span>\n <input type=\"range\" class=\"ae-stroke-input\" min=\"1\" max=\"60\" value=\"${strokeWidth}\" />\n <span class=\"ae-toolbar-value\">${strokeWidth}px</span>\n </div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">曲线率</span>\n <input type=\"range\" class=\"ae-round-input\" min=\"0\" max=\"1\" step=\"0.1\" value=\"${curveRate}\" />\n </div>\n `\n\n // 颜色选择\n const colorInput = this._toolbar.querySelector('.ae-color-input')\n colorInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.color = e.target.value\n this._defaultColor = e.target.value\n this._updateMarkerColor(e.target.value)\n this.render()\n })\n\n // 粗细调整\n const strokeInput = this._toolbar.querySelector('.ae-stroke-input')\n const strokeValue = this._toolbar.querySelector('.ae-stroke-input + .ae-toolbar-value')\n strokeInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.strokeWidth = parseInt(e.target.value)\n strokeValue.textContent = e.target.value + 'px'\n this.render()\n })\n\n // 曲线率调整\n const roundInput = this._toolbar.querySelector('.ae-round-input')\n roundInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.curveRate = parseFloat(e.target.value)\n this.render()\n })\n\n // 拖拽功能 - 使用类实例绑定\n const dragHandle = this._toolbar.querySelector('.ae-toolbar-drag-handle')\n this._setupToolbarDrag(dragHandle)\n\n // 阻止工具条上的事件触发到容器\n this._toolbar.addEventListener('mousedown', (e) => {\n e.stopPropagation()\n })\n this._toolbar.addEventListener('mouseup', (e) => {\n e.stopPropagation()\n })\n\n this.container.appendChild(this._toolbar)\n }\n\n // 工具条拖拽设置\n _setupToolbarDrag(dragHandle) {\n let isDragging = false\n let dragOffset = { x: 0, y: 0 }\n\n dragHandle.addEventListener('mousedown', (e) => {\n isDragging = true\n this._toolbarDragging = true\n const rect = this._toolbar.getBoundingClientRect()\n dragOffset.x = e.clientX - rect.left\n dragOffset.y = e.clientY - rect.top\n e.preventDefault()\n e.stopPropagation()\n\n const onMove = (moveEvent) => {\n if (!isDragging) return\n const containerRect = this.container.getBoundingClientRect()\n let newLeft = moveEvent.clientX - containerRect.left - dragOffset.x\n let newTop = moveEvent.clientY - containerRect.top - dragOffset.y\n const toolbarWidth = this._toolbar.offsetWidth\n const toolbarHeight = this._toolbar.offsetHeight\n newLeft = Math.max(0, Math.min(newLeft, containerRect.width - toolbarWidth))\n newTop = Math.max(0, Math.min(newTop, containerRect.height - toolbarHeight))\n this._toolbar.style.left = newLeft + 'px'\n this._toolbar.style.top = newTop + 'px'\n }\n\n const onUp = (e) => {\n isDragging = false\n this._toolbarDragging = false\n document.removeEventListener('mousemove', onMove)\n document.removeEventListener('mouseup', onUp)\n this._toolbar.removeEventListener('mouseup', onUp)\n \n e.preventDefault()\n e.stopPropagation()\n }\n\n document.addEventListener('mousemove', onMove)\n document.addEventListener('mouseup', onUp)\n\n this._toolbar.addEventListener('mouseup', onUp)\n })\n }\n\n _showToolbar() {\n if (this.selected) {\n if (!this._toolbar) {\n this._createToolbar()\n }\n this._toolbar.style.display = 'flex'\n\n // 更新工具条值\n const color = this.selected.color || this._defaultColor\n const strokeWidth = this.selected.strokeWidth || this._strokeWidth\n const curveRate = this.selected.curveRate ?? this.selected.cornerRoundness ?? 0\n\n const colorInput = this._toolbar.querySelector('.ae-color-input')\n const strokeInput = this._toolbar.querySelector('.ae-stroke-input')\n const strokeValue = this._toolbar.querySelector('.ae-stroke-input + .ae-toolbar-value')\n const roundInput = this._toolbar.querySelector('.ae-round-input')\n\n if (colorInput) colorInput.value = color\n if (strokeInput) {\n strokeInput.value = strokeWidth\n strokeValue.textContent = strokeWidth + 'px'\n }\n if (roundInput) roundInput.value = curveRate\n\n // 定位到所选箭头旁边\n const bbox = this._getArrowBBox(this.selected)\n const toolbarWidth = this._toolbar.offsetWidth || 150\n const toolbarHeight = this._toolbar.offsetHeight || 120\n\n // 计算位置:放在箭头右侧,如果空间不够则放左侧\n let left = bbox.maxX + 20\n if (left + toolbarWidth > this.container.offsetWidth) {\n left = bbox.minX - toolbarWidth - 20\n }\n\n // 垂直居中于箭头\n let top = bbox.centerY - toolbarHeight / 2\n if (top < 0) top = 0\n if (top + toolbarHeight > this.container.offsetHeight) {\n top = this.container.offsetHeight - toolbarHeight\n }\n\n this._toolbar.style.left = left + 'px'\n this._toolbar.style.top = top + 'px'\n }\n }\n\n _hideToolbar() {\n if (this._toolbar) {\n this._toolbar.style.display = 'none'\n }\n }\n\n _updateMarkerColor(color) {\n const marker = this.svg.querySelector('#ae-arrowhead polygon')\n if (marker) {\n marker.setAttribute('fill', color)\n }\n }\n\n _initKeybindings() {\n // 创建快捷键实例,绑定到 container 上\n this._kb = new Keybinding('arrow-editor')\n\n // Enter: 完成绘制\n this._kb.on('enter', () => {\n this._handleEnter()\n })\n\n // Esc: 结束绘制、取消选中\n this._kb.on('esc', () => {\n this._handleEsc()\n })\n }\n\n _initEvents() {\n this.container.onclick = e => {\n // 点击工具条时不处理\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n const p = this._mousePos(e)\n this._handleClick(p)\n }\n\n this.container.onmousemove = e => {\n const p = this._mousePos(e)\n this._handleMouseMove(e, p)\n }\n\n this.container.onmousedown = e => {\n // 点击工具条不触发移动\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n\n if (this.selected) {\n const handle = e.target.getAttribute('data-handle')\n if (handle) {\n this._transformMode = handle\n this._transformHandle = handle\n const p = this._mousePos(e)\n this._transformStartPos = p\n this._transformStartPoints = this.selected.points.map(pt => ({ x: pt.x, y: pt.y }))\n this._transformCenter = this._getArrowBBox(this.selected)\n\n if (handle === 'rotate') {\n const center = this._transformCenter\n const dx = p.x - center.centerX\n const dy = p.y - center.centerY\n this._transformStartAngle = Math.atan2(dy, dx)\n this._rotationOffset = 0\n }\n\n e.stopPropagation()\n return\n }\n\n this.mode = 'move'\n }\n }\n\n this.container.onmouseup = () => {\n this.mode = null\n this._transformMode = null\n this._transformHandle = null\n }\n }\n\n _mousePos(e) {\n const r = this.container.getBoundingClientRect()\n return {\n x: e.clientX - r.left,\n y: e.clientY - r.top\n }\n }\n\n _generatePath(pts, curveRate = 0) {\n if (pts.length < 2) return ''\n\n // curveRate 为 0 时画直线\n if (curveRate === 0) {\n let d = `M ${pts[0].x} ${pts[0].y}`\n for (let i = 1; i < pts.length; i++) {\n d += ` L ${pts[i].x} ${pts[i].y}`\n }\n return d\n }\n\n // 根据曲线率计算控制点位置\n // curveRate: 0 - 直线,1 - 最弯曲\n let d = `M ${pts[0].x} ${pts[0].y}`\n\n for (let i = 0; i < pts.length - 1; i++) {\n const curr = pts[i]\n const next = pts[i + 1]\n\n // 计算当前线段的向量\n const dx = next.x - curr.x\n const dy = next.y - curr.y\n const len = Math.hypot(dx, dy)\n\n if (len === 0) continue\n\n // 计算进入当前点的切线向量(前一段线段)\n let inDx = dx\n let inDy = dy\n\n if (i > 0) {\n const prev = pts[i - 1]\n inDx = curr.x - prev.x\n inDy = curr.y - prev.y\n }\n\n // 计算出当前点的切线向量(下一段线段)\n let outDx = dx\n let outDy = dy\n\n if (i < pts.length - 2) {\n const after = pts[i + 2]\n outDx = after.x - next.x\n outDy = after.y - next.y\n }\n\n // 单位向量\n const inLen = Math.hypot(inDx, inDy) || 1\n const outLen = Math.hypot(outDx, outDy) || 1\n const uxIn = inDx / inLen\n const uyIn = inDy / inLen\n const uxOut = outDx / outLen\n const uyOut = outDy / outLen\n\n // 控制点距离:曲线率 * 线段长度 * 系数\n const controlDist = len * curveRate * 0.3\n\n // 第一个控制点:从当前点沿进入方向的切线\n const cp1X = curr.x + uxIn * controlDist\n const cp1Y = curr.y + uyIn * controlDist\n\n // 第二个控制点:从下一个点沿出去方向的切线反方向\n const cp2X = next.x - uxOut * controlDist\n const cp2Y = next.y - uyOut * controlDist\n\n d += ` C ${cp1X} ${cp1Y} ${cp2X} ${cp2Y} ${next.x} ${next.y}`\n }\n\n return d\n }\n\n _generateArrowHead(pts, strokeWidth = 8) {\n if (pts.length < 2) return ''\n\n const last = pts[pts.length - 1]\n let prev = pts[pts.length - 2]\n\n if (pts.length >= 3) {\n const dist = Math.hypot(last.x - prev.x, last.y - prev.y)\n if (dist < 5) {\n prev = pts[pts.length - 3]\n }\n }\n\n const dx = last.x - prev.x\n const dy = last.y - prev.y\n const len = Math.hypot(dx, dy)\n\n if (len < 1) return ''\n\n const ux = dx / len\n const uy = dy / len\n\n const notchX = last.x\n const notchY = last.y\n\n // 根据粗细调整箭头大小\n const scale = strokeWidth / 8\n const baseLen = 40 * scale\n const baseWidth = 20 * scale\n const notchLen = 20 * scale\n\n const tipX = last.x + ux * notchLen\n const tipY = last.y + uy * notchLen\n const baseX = last.x - ux * (baseLen - notchLen)\n const baseY = last.y - uy * (baseLen - notchLen)\n\n const px = -uy\n const py = ux\n\n const leftX = baseX + px * baseWidth\n const leftY = baseY + py * baseWidth\n const rightX = baseX - px * baseWidth\n const rightY = baseY - py * baseWidth\n\n return `M ${tipX} ${tipY} L ${leftX} ${leftY} L ${notchX} ${notchY} L ${rightX} ${rightY} Z`\n }\n\n _createArrowGroup(arrow, index) {\n const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')\n g.setAttribute('data-index', index)\n\n const color = arrow.color || this._defaultColor\n const strokeWidth = arrow.strokeWidth || this._strokeWidth\n const curveRate = arrow.curveRate ?? arrow.cornerRoundness ?? 0\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('class', 'ae-arrow-path')\n path.style.stroke = color\n path.style.strokeWidth = strokeWidth + 'px'\n path.setAttribute('d', this._generatePath(arrow.points, curveRate))\n g.appendChild(path)\n\n const arrowHead = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n arrowHead.setAttribute('fill', color)\n arrowHead.setAttribute('d', this._generateArrowHead(arrow.points, strokeWidth))\n g.appendChild(arrowHead)\n\n if (arrow === this.selected) {\n const bbox = this._getArrowBBox(arrow)\n\n // 变换框\n const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\n rect.setAttribute('class', 'ae-transform-box')\n rect.setAttribute('x', bbox.minX - 10)\n rect.setAttribute('y', bbox.minY - 10)\n rect.setAttribute('width', bbox.width + 20)\n rect.setAttribute('height', bbox.height + 20)\n g.appendChild(rect)\n\n // 缩放手柄(右下角)\n const scaleHandle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n scaleHandle.setAttribute('class', 'ae-transform-handle')\n scaleHandle.setAttribute('cx', bbox.maxX + 10)\n scaleHandle.setAttribute('cy', bbox.maxY + 10)\n scaleHandle.setAttribute('r', 6)\n scaleHandle.setAttribute('data-handle', 'scale')\n g.appendChild(scaleHandle)\n\n // 旋转手柄(顶部中间)\n const rotateY = bbox.minY - 30\n const rotateX = bbox.centerX\n const rotateLine = document.createElementNS('http://www.w3.org/2000/svg', 'line')\n rotateLine.setAttribute('class', 'ae-rotate-line')\n rotateLine.setAttribute('x1', bbox.centerX)\n rotateLine.setAttribute('y1', bbox.minY - 10)\n rotateLine.setAttribute('x2', rotateX)\n rotateLine.setAttribute('y2', rotateY)\n g.appendChild(rotateLine)\n\n const rotateHandle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n rotateHandle.setAttribute('class', 'ae-rotate-handle')\n rotateHandle.setAttribute('cx', rotateX)\n rotateHandle.setAttribute('cy', rotateY)\n rotateHandle.setAttribute('r', 8)\n rotateHandle.setAttribute('data-handle', 'rotate')\n g.appendChild(rotateHandle)\n }\n\n return g\n }\n\n render() {\n this.svg.querySelectorAll('g').forEach(g => g.remove())\n\n this.arrows.forEach((arrow, index) => {\n const g = this._createArrowGroup(arrow, index)\n this.svg.appendChild(g)\n })\n\n if (this.current) {\n const g = this._createArrowGroup(this.current, this.arrows.length)\n this.svg.appendChild(g)\n }\n }\n\n _isDoubleClick(p) {\n const now = Date.now()\n const dt = now - this.lastClickTime\n this.lastClickTime = now\n\n if (dt < 300 && this.lastClickPos && Math.hypot(p.x - this.lastClickPos.x, p.y - this.lastClickPos.y) < 10) {\n this.lastClickPos = null\n return true\n }\n\n this.lastClickPos = p\n return false\n }\n\n _handleClick(p) {\n // 如果刚才有拖拽,阻止点击事件\n if (this._shouldBlockClick) {\n this._shouldBlockClick = false\n return\n }\n\n if (this._isDoubleClick(p)) {\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n return\n }\n\n // 有选中的箭头时,点击空白处取消选中\n if (this.selected) {\n for (const a of this.arrows) {\n if (this._hitArrow(a, p)) {\n this.render()\n return\n }\n }\n // 点击空白处,取消选中\n this.selected = null\n this._hideToolbar()\n this.render()\n return\n }\n\n // 没有选中时,检查是否点击到箭头\n for (const a of this.arrows) {\n if (this._hitArrow(a, p)) {\n this.selected = a\n this._showToolbar()\n this.render()\n return\n }\n }\n\n // 点击空白处\n if (this.drawing) {\n // 正在绘制中,添加点\n this.current.points.push(p)\n } else {\n // 开始绘制\n this.drawing = true\n this.current = {\n points: [p, p],\n color: this._defaultColor\n }\n }\n\n this.render()\n }\n\n _handleEnter() {\n // 正在绘制时,按 Enter 完成绘制\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n }\n\n _handleEsc() {\n // 按 Esc: 结束绘制、取消选中\n if (this.drawing) {\n this.drawing = false\n this.current = null\n }\n if (this.selected) {\n this.selected = null\n }\n this._hideColorPicker()\n this._hideToolbar()\n this.render()\n }\n\n _showColorPicker(e) {\n if (this._showingColorPicker) {\n this._hideColorPicker()\n return\n }\n\n this._showingColorPicker = true\n\n // 创建颜色选择器浮窗\n const popup = document.createElement('div')\n popup.className = 'ae-color-picker-popup'\n\n const label = document.createElement('span')\n label.textContent = '选择颜色'\n label.style.cssText = 'font-size: 12px; color: #666;'\n\n const colorInput = document.createElement('input')\n colorInput.type = 'color'\n colorInput.value = this.selected.color || this._defaultColor\n // 自动打开颜色选择器\n colorInput.showPicker()\n\n popup.appendChild(label)\n popup.appendChild(colorInput)\n\n // 定位到颜色手柄位置\n const rect = this.container.getBoundingClientRect()\n const bbox = this._getArrowBBox(this.selected)\n const x = rect.left + bbox.minX - 50\n const y = rect.top + bbox.maxY + 15\n\n popup.style.left = x + 'px'\n popup.style.top = y + 'px'\n\n // 颜色改变时实时更新\n colorInput.addEventListener('input', (ev) => {\n this.selected.color = ev.target.value\n this._defaultColor = ev.target.value\n this.render()\n })\n\n // 点击外部关闭\n const closeHandler = (ev) => {\n if (!popup.contains(ev.target)) {\n this._hideColorPicker()\n document.removeEventListener('click', closeHandler)\n }\n }\n\n document.body.appendChild(popup)\n this._colorPickerPopup = popup\n\n document.addEventListener('click', closeHandler)\n }\n\n _hideColorPicker() {\n if (this._colorPickerPopup) {\n this._colorPickerPopup.remove()\n this._colorPickerPopup = null\n }\n this._showingColorPicker = false\n }\n\n // 删除选中的箭头\n deleteSelected() {\n if (this.selected) {\n this.arrows = this.arrows.filter(a => a !== this.selected)\n this.selected = null\n this.render()\n }\n }\n\n _handleMouseMove(e, p) {\n // 如果正在拖拽工具条,不处理\n if (this._toolbarDragging) {\n return\n }\n\n // 如果鼠标在工具条上,不处理\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n\n if (this.drawing) {\n this.current.points[this.current.points.length - 1] = p\n this.render()\n }\n\n // 变换处理(旋转/缩放)\n if (this._transformMode && this.selected) {\n if (this._transformMode === 'rotate') {\n this._handleRotate(p)\n } else if (this._transformMode === 'scale') {\n this._handleScale(p)\n }\n this.render()\n return\n }\n\n if (this.selected && this.mode === 'move') {\n const dx = e.movementX\n const dy = e.movementY\n\n // 如果有移动,标记需要阻止点击\n if (dx !== 0 || dy !== 0) {\n this._shouldBlockClick = true\n }\n\n this.selected.points.forEach(pt => {\n pt.x += dx\n pt.y += dy\n })\n\n this.render()\n }\n }\n\n _getArrowBBox(arrow) {\n const points = arrow.points\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity\n\n for (const pt of points) {\n minX = Math.min(minX, pt.x)\n minY = Math.min(minY, pt.y)\n maxX = Math.max(maxX, pt.x)\n maxY = Math.max(maxY, pt.y)\n }\n\n return {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n centerX: (minX + maxX) / 2,\n centerY: (minY + maxY) / 2\n }\n }\n\n _handleRotate(p) {\n const center = this._transformCenter\n const centerX = center.centerX\n const centerY = center.centerY\n\n // 计算当前角度和起始角度\n const currentAngle = Math.atan2(p.y - centerY, p.x - centerX)\n const startAngle = Math.atan2(this._transformStartPos.y - centerY, this._transformStartPos.x - centerX)\n const angleDiff = currentAngle - startAngle\n\n // 旋转点\n const cos = Math.cos(angleDiff)\n const sin = Math.sin(angleDiff)\n\n this.selected.points.forEach((pt, i) => {\n const relX = this._transformStartPoints[i].x - centerX\n const relY = this._transformStartPoints[i].y - centerY\n pt.x = centerX + relX * cos - relY * sin\n pt.y = centerY + relX * sin + relY * cos\n })\n }\n\n _handleScale(p) {\n const center = this._transformCenter\n const centerX = center.centerX\n const centerY = center.centerY\n const startPoints = this._transformStartPoints\n const startPos = this._transformStartPos\n\n // 计算缩放比例\n const dx = p.x - centerX\n const dy = p.y - centerY\n const startDx = startPos.x - centerX\n const startDy = startPos.y - centerY\n\n const currentDist = Math.hypot(dx, dy)\n const startDist = Math.hypot(startDx, startDy)\n const scale = currentDist / startDist\n\n // 应用缩放\n this.selected.points.forEach((pt, i) => {\n pt.x = centerX + (startPoints[i].x - centerX) * scale\n pt.y = centerY + (startPoints[i].y - centerY) * scale\n })\n }\n\n _hitArrow(a, p) {\n for (let i = 0; i < a.points.length - 1; i++) {\n if (this._dist(p, a.points[i], a.points[i + 1]) < 15)\n return true\n }\n return false\n }\n\n _dist(p, a, b) {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const t = ((p.x - a.x) * dx + (p.y - a.y) * dy) / (dx * dx + dy * dy)\n const tt = Math.max(0, Math.min(1, t))\n const px = a.x + tt * dx\n const py = a.y + tt * dy\n return Math.hypot(p.x - px, p.y - py)\n }\n\n // 获取所有箭头数据\n getData() {\n return this.arrows.map(arrow => ({\n points: arrow.points,\n curveRate: arrow.curveRate ?? arrow.cornerRoundness ?? 0,\n strokeWidth: arrow.strokeWidth,\n color: arrow.color\n }))\n }\n\n // 设置箭头数据\n setData(data) {\n this.arrows = data.map(item => ({\n points: item.points,\n curveRate: item.curveRate ?? 0,\n strokeWidth: item.strokeWidth ?? 8,\n color: item.color\n }))\n this.render()\n }\n\n // 清空所有箭头\n clear() {\n this.arrows = []\n this.drawing = false\n this.current = null\n this.selected = null\n this.render()\n }\n}\n"],"names":["STYLES","styleEl","ArrowEditor","container","defs","marker","polygon","color","strokeWidth","curveRate","e","strokeInput","strokeValue","dragHandle","isDragging","dragOffset","rect","onMove","moveEvent","containerRect","newLeft","newTop","toolbarWidth","toolbarHeight","onUp","colorInput","roundInput","bbox","left","top","Keybinding","p","handle","pt","center","dx","dy","r","pts","d","i","curr","next","len","inDx","inDy","prev","outDx","outDy","after","inLen","outLen","uxIn","uyIn","uxOut","uyOut","controlDist","cp1X","cp1Y","cp2X","cp2Y","last","ux","uy","notchX","notchY","scale","baseLen","baseWidth","notchLen","tipX","tipY","baseX","baseY","px","py","leftX","leftY","rightX","rightY","arrow","index","g","path","arrowHead","scaleHandle","rotateY","rotateX","rotateLine","rotateHandle","now","dt","a","popup","label","x","y","ev","closeHandler","points","minX","minY","maxX","maxY","centerX","centerY","currentAngle","startAngle","angleDiff","cos","sin","relX","relY","startPoints","startPos","startDx","startDy","currentDist","startDist","b","t","tt","data","item"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bundle.esm.js","sources":["../src/editor.js"],"sourcesContent":["import { Keybinding } from '@wbiokr/keybinding'\n\n// 样式注入\nconst STYLES = `\n.ae-d2-container {\n position: relative;\n width: 1000px;\n height: 600px;\n background: #fff;\n margin: auto;\n}\n\n.ae-d2-svg {\n width: 100%;\n height: 100%;\n}\n\n.ae-arrow-path {\n fill: none;\n stroke-linecap: round;\n stroke-linejoin: round;\n cursor: pointer;\n}\n\n.ae-arrow-path:hover {\n stroke: #00aaff;\n}\n\n.ae-transform-box {\n fill: none;\n stroke: #00aaff;\n stroke-width: 2;\n stroke-dasharray: 4;\n}\n\n.ae-transform-handle {\n fill: #fff;\n stroke: #00aaff;\n stroke-width: 2;\n cursor: pointer;\n}\n\n.ae-transform-handle:hover {\n fill: #00aaff;\n}\n\n.ae-rotate-handle {\n fill: #fff;\n stroke: #ff6600;\n stroke-width: 2;\n cursor: grab;\n}\n\n.ae-rotate-handle:hover {\n fill: #ff6600;\n}\n\n.ae-rotate-line {\n stroke: #ff6600;\n stroke-width: 1;\n stroke-dasharray: 4;\n}\n\n/* 工具条样式 */\n.ae-toolbar {\n position: absolute;\n display: none;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n background: #fff;\n border: 1px solid #ddd;\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0,0,0,0.15);\n z-index: 1000;\n pointer-events: auto;\n min-width: 140px;\n}\n\n.ae-toolbar-drag-handle {\n cursor: grab;\n text-align: center;\n padding: 4px;\n color: #999;\n font-size: 14px;\n line-height: 1;\n user-select: none;\n border-bottom: 1px solid #eee;\n margin: -12px -12px 8px -12px;\n padding-top: 8px;\n padding-bottom: 8px;\n border-radius: 8px 8px 0 0;\n}\n\n.ae-toolbar-drag-handle:active {\n cursor: grabbing;\n}\n\n.ae-toolbar-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ae-toolbar-label {\n font-size: 11px;\n color: #666;\n}\n\n.ae-toolbar input[type=\"color\"] {\n width: 40px;\n height: 30px;\n border: 1px solid #ddd;\n border-radius: 4px;\n cursor: pointer;\n padding: 0;\n background: none;\n}\n\n.ae-toolbar input[type=\"range\"] {\n width: 120px;\n cursor: pointer;\n}\n\n.ae-toolbar-value {\n font-size: 10px;\n color: #999;\n text-align: right;\n}\n`\n\n// 注入样式\nif (typeof document !== 'undefined') {\n const styleEl = document.createElement('style')\n styleEl.textContent = STYLES\n document.head.appendChild(styleEl)\n}\n\nexport class ArrowEditor {\n\n constructor(container, options = {}) {\n this.container = typeof container === 'string' ? document.querySelector(container) : container\n this.svg = null\n\n this.arrows = []\n this.drawing = false\n this.current = null\n this.selected = null\n this.mode = null\n this.lastClickTime = 0\n this.lastClickPos = null\n this._shouldBlockClick = false\n this._defaultColor = '#2b8cff'\n\n // 配置选项\n this.isCtrl = options.isCtrl || false\n this.stopPropagation = options.stopPropagation || false\n this.preventDefault = options.preventDefault || false\n\n // 变换相关\n this._transformMode = null // 'rotate' | 'scale'\n this._transformHandle = null\n this._transformStartPos = null\n this._transformStartPoints = null\n this._transformCenter = null\n this._transformStartAngle = null\n this._rotationOffset = 0\n\n // 工具条相关\n this._toolbar = null\n this._strokeWidth = 8\n this._curveRate = 0\n\n this._createSVG()\n this._initKeybindings()\n this._initEvents()\n }\n\n _createSVG() {\n // 创建 SVG 元素\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n this.svg.setAttribute('class', 'ae-d2-svg')\n this.container.appendChild(this.svg)\n\n // 创建 defs 和 marker\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs')\n this.svg.appendChild(defs)\n\n const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker')\n marker.setAttribute('id', 'ae-arrowhead')\n marker.setAttribute('markerWidth', '10')\n marker.setAttribute('markerHeight', '10')\n marker.setAttribute('refX', '9')\n marker.setAttribute('refY', '5')\n marker.setAttribute('orient', 'auto')\n\n const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon')\n polygon.setAttribute('points', '0,0 10,5 0,10 2,5')\n polygon.setAttribute('fill', this._defaultColor)\n\n marker.appendChild(polygon)\n defs.appendChild(marker)\n }\n\n _createToolbar() {\n if (this._toolbar) {\n this._toolbar.remove()\n }\n\n this._toolbar = document.createElement('div')\n this._toolbar.className = 'ae-toolbar'\n\n const color = this.selected.color || this._defaultColor\n const strokeWidth = this.selected.strokeWidth || this._strokeWidth\n const curveRate = this.selected.curveRate ?? this.selected.cornerRoundness ?? 0\n\n this._toolbar.innerHTML = `\n <div class=\"ae-toolbar-drag-handle\">:::</div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">颜色</span>\n <input type=\"color\" class=\"ae-color-input\" value=\"${color}\" />\n </div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">粗细</span>\n <input type=\"range\" class=\"ae-stroke-input\" min=\"1\" max=\"60\" value=\"${strokeWidth}\" />\n <span class=\"ae-toolbar-value\">${strokeWidth}px</span>\n </div>\n <div class=\"ae-toolbar-item\">\n <span class=\"ae-toolbar-label\">曲线率</span>\n <input type=\"range\" class=\"ae-round-input\" min=\"0\" max=\"1\" step=\"0.1\" value=\"${curveRate}\" />\n </div>\n `\n\n // 颜色选择\n const colorInput = this._toolbar.querySelector('.ae-color-input')\n colorInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.color = e.target.value\n this._defaultColor = e.target.value\n this._updateMarkerColor(e.target.value)\n this.render()\n })\n\n // 粗细调整\n const strokeInput = this._toolbar.querySelector('.ae-stroke-input')\n const strokeValue = this._toolbar.querySelector('.ae-stroke-input + .ae-toolbar-value')\n strokeInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.strokeWidth = parseInt(e.target.value)\n strokeValue.textContent = e.target.value + 'px'\n this.render()\n })\n\n // 曲线率调整\n const roundInput = this._toolbar.querySelector('.ae-round-input')\n roundInput.addEventListener('input', (e) => {\n if (!this.selected) return\n this.selected.curveRate = parseFloat(e.target.value)\n this.render()\n })\n\n // 拖拽功能 - 使用类实例绑定\n const dragHandle = this._toolbar.querySelector('.ae-toolbar-drag-handle')\n this._setupToolbarDrag(dragHandle)\n\n // 阻止工具条上的事件触发到容器\n this._toolbar.addEventListener('mousedown', (e) => {\n e.stopPropagation()\n })\n this._toolbar.addEventListener('mouseup', (e) => {\n e.stopPropagation()\n })\n\n this.container.appendChild(this._toolbar)\n }\n\n // 工具条拖拽设置\n _setupToolbarDrag(dragHandle) {\n let isDragging = false\n let dragOffset = { x: 0, y: 0 }\n\n dragHandle.addEventListener('mousedown', (e) => {\n isDragging = true\n this._toolbarDragging = true\n const rect = this._toolbar.getBoundingClientRect()\n dragOffset.x = e.clientX - rect.left\n dragOffset.y = e.clientY - rect.top\n e.preventDefault()\n e.stopPropagation()\n\n const onMove = (moveEvent) => {\n if (!isDragging) return\n const containerRect = this.container.getBoundingClientRect()\n let newLeft = moveEvent.clientX - containerRect.left - dragOffset.x\n let newTop = moveEvent.clientY - containerRect.top - dragOffset.y\n const toolbarWidth = this._toolbar.offsetWidth\n const toolbarHeight = this._toolbar.offsetHeight\n newLeft = Math.max(0, Math.min(newLeft, containerRect.width - toolbarWidth))\n newTop = Math.max(0, Math.min(newTop, containerRect.height - toolbarHeight))\n this._toolbar.style.left = newLeft + 'px'\n this._toolbar.style.top = newTop + 'px'\n }\n\n const onUp = (e) => {\n isDragging = false\n this._toolbarDragging = false\n document.removeEventListener('mousemove', onMove)\n document.removeEventListener('mouseup', onUp)\n this._toolbar.removeEventListener('mouseup', onUp)\n \n e.preventDefault()\n e.stopPropagation()\n }\n\n document.addEventListener('mousemove', onMove)\n document.addEventListener('mouseup', onUp)\n\n this._toolbar.addEventListener('mouseup', onUp)\n })\n }\n\n _showToolbar() {\n if (this.selected) {\n if (!this._toolbar) {\n this._createToolbar()\n }\n this._toolbar.style.display = 'flex'\n\n // 更新工具条值\n const color = this.selected.color || this._defaultColor\n const strokeWidth = this.selected.strokeWidth || this._strokeWidth\n const curveRate = this.selected.curveRate ?? this.selected.cornerRoundness ?? 0\n\n const colorInput = this._toolbar.querySelector('.ae-color-input')\n const strokeInput = this._toolbar.querySelector('.ae-stroke-input')\n const strokeValue = this._toolbar.querySelector('.ae-stroke-input + .ae-toolbar-value')\n const roundInput = this._toolbar.querySelector('.ae-round-input')\n\n if (colorInput) colorInput.value = color\n if (strokeInput) {\n strokeInput.value = strokeWidth\n strokeValue.textContent = strokeWidth + 'px'\n }\n if (roundInput) roundInput.value = curveRate\n\n // 定位到所选箭头旁边\n const bbox = this._getArrowBBox(this.selected)\n const toolbarWidth = this._toolbar.offsetWidth || 150\n const toolbarHeight = this._toolbar.offsetHeight || 120\n\n // 计算位置:放在箭头右侧,如果空间不够则放左侧\n let left = bbox.maxX + 20\n if (left + toolbarWidth > this.container.offsetWidth) {\n left = bbox.minX - toolbarWidth - 20\n }\n\n // 垂直居中于箭头\n let top = bbox.centerY - toolbarHeight / 2\n if (top < 0) top = 0\n if (top + toolbarHeight > this.container.offsetHeight) {\n top = this.container.offsetHeight - toolbarHeight\n }\n\n this._toolbar.style.left = left + 'px'\n this._toolbar.style.top = top + 'px'\n }\n }\n\n _hideToolbar() {\n if (this._toolbar) {\n this._toolbar.style.display = 'none'\n }\n }\n\n _updateMarkerColor(color) {\n const marker = this.svg.querySelector('#ae-arrowhead polygon')\n if (marker) {\n marker.setAttribute('fill', color)\n }\n }\n\n _initKeybindings() {\n // 创建快捷键实例,绑定到 container 上\n this._kb = new Keybinding('arrow-editor')\n\n // Enter: 完成绘制\n this._kb.on('enter', () => {\n this._handleEnter()\n })\n\n // Esc: 结束绘制、取消选中\n this._kb.on('esc', () => {\n this._handleEsc()\n })\n }\n\n _initEvents() {\n this.container.onclick = e => {\n // 点击工具条时不处理\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n if (this.preventDefault) e.preventDefault()\n if (this.stopPropagation) e.stopPropagation()\n const p = this._mousePos(e)\n this._handleClick(p, e)\n }\n\n this.container.onmousemove = e => {\n if (this.preventDefault) e.preventDefault()\n if (this.stopPropagation) e.stopPropagation()\n const p = this._mousePos(e)\n this._handleMouseMove(e, p)\n }\n\n this.container.onmousedown = e => {\n // 点击工具条不触发移动\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n\n if (this.preventDefault) e.preventDefault()\n if (this.stopPropagation) e.stopPropagation()\n\n if (this.selected) {\n const handle = e.target.getAttribute('data-handle')\n if (handle) {\n this._transformMode = handle\n this._transformHandle = handle\n const p = this._mousePos(e)\n this._transformStartPos = p\n this._transformStartPoints = this.selected.points.map(pt => ({ x: pt.x, y: pt.y }))\n this._transformCenter = this._getArrowBBox(this.selected)\n\n if (handle === 'rotate') {\n const center = this._transformCenter\n const dx = p.x - center.centerX\n const dy = p.y - center.centerY\n this._transformStartAngle = Math.atan2(dy, dx)\n this._rotationOffset = 0\n }\n\n e.stopPropagation()\n return\n }\n\n this.mode = 'move'\n }\n }\n\n this.container.onmouseup = () => {\n this.mode = null\n this._transformMode = null\n this._transformHandle = null\n }\n }\n\n _mousePos(e) {\n const r = this.container.getBoundingClientRect()\n return {\n x: e.clientX - r.left,\n y: e.clientY - r.top\n }\n }\n\n _generatePath(pts, curveRate = 0) {\n if (pts.length < 2) return ''\n\n // curveRate 为 0 时画直线\n if (curveRate === 0) {\n let d = `M ${pts[0].x} ${pts[0].y}`\n for (let i = 1; i < pts.length; i++) {\n d += ` L ${pts[i].x} ${pts[i].y}`\n }\n return d\n }\n\n // 根据曲线率计算控制点位置\n // curveRate: 0 - 直线,1 - 最弯曲\n let d = `M ${pts[0].x} ${pts[0].y}`\n\n for (let i = 0; i < pts.length - 1; i++) {\n const curr = pts[i]\n const next = pts[i + 1]\n\n // 计算当前线段的向量\n const dx = next.x - curr.x\n const dy = next.y - curr.y\n const len = Math.hypot(dx, dy)\n\n if (len === 0) continue\n\n // 计算进入当前点的切线向量(前一段线段)\n let inDx = dx\n let inDy = dy\n\n if (i > 0) {\n const prev = pts[i - 1]\n inDx = curr.x - prev.x\n inDy = curr.y - prev.y\n }\n\n // 计算出当前点的切线向量(下一段线段)\n let outDx = dx\n let outDy = dy\n\n if (i < pts.length - 2) {\n const after = pts[i + 2]\n outDx = after.x - next.x\n outDy = after.y - next.y\n }\n\n // 单位向量\n const inLen = Math.hypot(inDx, inDy) || 1\n const outLen = Math.hypot(outDx, outDy) || 1\n const uxIn = inDx / inLen\n const uyIn = inDy / inLen\n const uxOut = outDx / outLen\n const uyOut = outDy / outLen\n\n // 控制点距离:曲线率 * 线段长度 * 系数\n const controlDist = len * curveRate * 0.3\n\n // 第一个控制点:从当前点沿进入方向的切线\n const cp1X = curr.x + uxIn * controlDist\n const cp1Y = curr.y + uyIn * controlDist\n\n // 第二个控制点:从下一个点沿出去方向的切线反方向\n const cp2X = next.x - uxOut * controlDist\n const cp2Y = next.y - uyOut * controlDist\n\n d += ` C ${cp1X} ${cp1Y} ${cp2X} ${cp2Y} ${next.x} ${next.y}`\n }\n\n return d\n }\n\n _generateArrowHead(pts, strokeWidth = 8) {\n if (pts.length < 2) return ''\n\n const last = pts[pts.length - 1]\n let prev = pts[pts.length - 2]\n\n if (pts.length >= 3) {\n const dist = Math.hypot(last.x - prev.x, last.y - prev.y)\n if (dist < 5) {\n prev = pts[pts.length - 3]\n }\n }\n\n const dx = last.x - prev.x\n const dy = last.y - prev.y\n const len = Math.hypot(dx, dy)\n\n if (len < 1) return ''\n\n const ux = dx / len\n const uy = dy / len\n\n const notchX = last.x\n const notchY = last.y\n\n // 根据粗细调整箭头大小\n const scale = strokeWidth / 8\n const baseLen = 40 * scale\n const baseWidth = 20 * scale\n const notchLen = 20 * scale\n\n const tipX = last.x + ux * notchLen\n const tipY = last.y + uy * notchLen\n const baseX = last.x - ux * (baseLen - notchLen)\n const baseY = last.y - uy * (baseLen - notchLen)\n\n const px = -uy\n const py = ux\n\n const leftX = baseX + px * baseWidth\n const leftY = baseY + py * baseWidth\n const rightX = baseX - px * baseWidth\n const rightY = baseY - py * baseWidth\n\n return `M ${tipX} ${tipY} L ${leftX} ${leftY} L ${notchX} ${notchY} L ${rightX} ${rightY} Z`\n }\n\n _createArrowGroup(arrow, index) {\n const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')\n g.setAttribute('data-index', index)\n\n const color = arrow.color || this._defaultColor\n const strokeWidth = arrow.strokeWidth || this._strokeWidth\n const curveRate = arrow.curveRate ?? arrow.cornerRoundness ?? 0\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('class', 'ae-arrow-path')\n path.style.stroke = color\n path.style.strokeWidth = strokeWidth + 'px'\n path.setAttribute('d', this._generatePath(arrow.points, curveRate))\n g.appendChild(path)\n\n const arrowHead = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n arrowHead.setAttribute('fill', color)\n arrowHead.setAttribute('d', this._generateArrowHead(arrow.points, strokeWidth))\n g.appendChild(arrowHead)\n\n if (arrow === this.selected) {\n const bbox = this._getArrowBBox(arrow)\n\n // 变换框\n const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\n rect.setAttribute('class', 'ae-transform-box')\n rect.setAttribute('x', bbox.minX - 10)\n rect.setAttribute('y', bbox.minY - 10)\n rect.setAttribute('width', bbox.width + 20)\n rect.setAttribute('height', bbox.height + 20)\n g.appendChild(rect)\n\n // 缩放手柄(右下角)\n const scaleHandle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n scaleHandle.setAttribute('class', 'ae-transform-handle')\n scaleHandle.setAttribute('cx', bbox.maxX + 10)\n scaleHandle.setAttribute('cy', bbox.maxY + 10)\n scaleHandle.setAttribute('r', 6)\n scaleHandle.setAttribute('data-handle', 'scale')\n g.appendChild(scaleHandle)\n\n // 旋转手柄(顶部中间)\n const rotateY = bbox.minY - 30\n const rotateX = bbox.centerX\n const rotateLine = document.createElementNS('http://www.w3.org/2000/svg', 'line')\n rotateLine.setAttribute('class', 'ae-rotate-line')\n rotateLine.setAttribute('x1', bbox.centerX)\n rotateLine.setAttribute('y1', bbox.minY - 10)\n rotateLine.setAttribute('x2', rotateX)\n rotateLine.setAttribute('y2', rotateY)\n g.appendChild(rotateLine)\n\n const rotateHandle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n rotateHandle.setAttribute('class', 'ae-rotate-handle')\n rotateHandle.setAttribute('cx', rotateX)\n rotateHandle.setAttribute('cy', rotateY)\n rotateHandle.setAttribute('r', 8)\n rotateHandle.setAttribute('data-handle', 'rotate')\n g.appendChild(rotateHandle)\n }\n\n return g\n }\n\n render() {\n this.svg.querySelectorAll('g').forEach(g => g.remove())\n\n this.arrows.forEach((arrow, index) => {\n const g = this._createArrowGroup(arrow, index)\n this.svg.appendChild(g)\n })\n\n if (this.current) {\n const g = this._createArrowGroup(this.current, this.arrows.length)\n this.svg.appendChild(g)\n }\n }\n\n _isDoubleClick(p) {\n const now = Date.now()\n const dt = now - this.lastClickTime\n this.lastClickTime = now\n\n if (dt < 300 && this.lastClickPos && Math.hypot(p.x - this.lastClickPos.x, p.y - this.lastClickPos.y) < 10) {\n this.lastClickPos = null\n return true\n }\n\n this.lastClickPos = p\n return false\n }\n\n _handleClick(p, e) {\n // 如果配置了 isCtrl,需要按着 Ctrl 键才能绘制\n if (this.isCtrl && !e.ctrlKey) {\n return\n }\n\n // 如果刚才有拖拽,阻止点击事件\n if (this._shouldBlockClick) {\n this._shouldBlockClick = false\n return\n }\n\n if (this._isDoubleClick(p)) {\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n return\n }\n\n // 有选中的箭头时,点击空白处取消选中\n if (this.selected) {\n for (const a of this.arrows) {\n if (this._hitArrow(a, p)) {\n this.render()\n return\n }\n }\n // 点击空白处,取消选中\n this.selected = null\n this._hideToolbar()\n this.render()\n return\n }\n\n // 没有选中时,检查是否点击到箭头\n for (const a of this.arrows) {\n if (this._hitArrow(a, p)) {\n this.selected = a\n this._showToolbar()\n this.render()\n return\n }\n }\n\n // 点击空白处\n if (this.drawing) {\n // 正在绘制中,添加点\n this.current.points.push(p)\n } else {\n // 开始绘制\n this.drawing = true\n this.current = {\n points: [p, p],\n color: this._defaultColor\n }\n }\n\n this.render()\n }\n\n _handleEnter() {\n // 正在绘制时,按 Enter 完成绘制\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n }\n\n _handleEsc() {\n // 按 Esc: 结束绘制、取消选中\n if (this.drawing) {\n this.drawing = false\n this.current = null\n }\n if (this.selected) {\n this.selected = null\n }\n this._hideColorPicker()\n this._hideToolbar()\n this.render()\n }\n\n _showColorPicker(e) {\n if (this._showingColorPicker) {\n this._hideColorPicker()\n return\n }\n\n this._showingColorPicker = true\n\n // 创建颜色选择器浮窗\n const popup = document.createElement('div')\n popup.className = 'ae-color-picker-popup'\n\n const label = document.createElement('span')\n label.textContent = '选择颜色'\n label.style.cssText = 'font-size: 12px; color: #666;'\n\n const colorInput = document.createElement('input')\n colorInput.type = 'color'\n colorInput.value = this.selected.color || this._defaultColor\n // 自动打开颜色选择器\n colorInput.showPicker()\n\n popup.appendChild(label)\n popup.appendChild(colorInput)\n\n // 定位到颜色手柄位置\n const rect = this.container.getBoundingClientRect()\n const bbox = this._getArrowBBox(this.selected)\n const x = rect.left + bbox.minX - 50\n const y = rect.top + bbox.maxY + 15\n\n popup.style.left = x + 'px'\n popup.style.top = y + 'px'\n\n // 颜色改变时实时更新\n colorInput.addEventListener('input', (ev) => {\n this.selected.color = ev.target.value\n this._defaultColor = ev.target.value\n this.render()\n })\n\n // 点击外部关闭\n const closeHandler = (ev) => {\n if (!popup.contains(ev.target)) {\n this._hideColorPicker()\n document.removeEventListener('click', closeHandler)\n }\n }\n\n document.body.appendChild(popup)\n this._colorPickerPopup = popup\n\n document.addEventListener('click', closeHandler)\n }\n\n _hideColorPicker() {\n if (this._colorPickerPopup) {\n this._colorPickerPopup.remove()\n this._colorPickerPopup = null\n }\n this._showingColorPicker = false\n }\n\n // 删除选中的箭头\n deleteSelected() {\n if (this.selected) {\n this.arrows = this.arrows.filter(a => a !== this.selected)\n this.selected = null\n this.render()\n }\n }\n\n _handleMouseMove(e, p) {\n // 如果正在拖拽工具条,不处理\n if (this._toolbarDragging) {\n return\n }\n\n // 如果鼠标在工具条上,不处理\n if (this._toolbar && (e.target === this._toolbar || this._toolbar.contains(e.target))) {\n return\n }\n\n // 如果配置了 isCtrl,需要按着 Ctrl 键才能绘制\n if (this.isCtrl && !e.ctrlKey) {\n // 如果正在绘制中,按 Ctrl 键松开则结束绘制\n if (this.drawing && this.current && this.current.points.length >= 2) {\n this.drawing = false\n this.arrows.push(this.current)\n this.current = null\n this.render()\n }\n return\n }\n\n if (this.drawing) {\n this.current.points[this.current.points.length - 1] = p\n this.render()\n }\n\n // 变换处理(旋转/缩放)\n if (this._transformMode && this.selected) {\n if (this._transformMode === 'rotate') {\n this._handleRotate(p)\n } else if (this._transformMode === 'scale') {\n this._handleScale(p)\n }\n this.render()\n return\n }\n\n if (this.selected && this.mode === 'move') {\n const dx = e.movementX\n const dy = e.movementY\n\n // 如果有移动,标记需要阻止点击\n if (dx !== 0 || dy !== 0) {\n this._shouldBlockClick = true\n }\n\n this.selected.points.forEach(pt => {\n pt.x += dx\n pt.y += dy\n })\n\n this.render()\n }\n }\n\n _getArrowBBox(arrow) {\n const points = arrow.points\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity\n\n for (const pt of points) {\n minX = Math.min(minX, pt.x)\n minY = Math.min(minY, pt.y)\n maxX = Math.max(maxX, pt.x)\n maxY = Math.max(maxY, pt.y)\n }\n\n return {\n minX,\n minY,\n maxX,\n maxY,\n width: maxX - minX,\n height: maxY - minY,\n centerX: (minX + maxX) / 2,\n centerY: (minY + maxY) / 2\n }\n }\n\n _handleRotate(p) {\n const center = this._transformCenter\n const centerX = center.centerX\n const centerY = center.centerY\n\n // 计算当前角度和起始角度\n const currentAngle = Math.atan2(p.y - centerY, p.x - centerX)\n const startAngle = Math.atan2(this._transformStartPos.y - centerY, this._transformStartPos.x - centerX)\n const angleDiff = currentAngle - startAngle\n\n // 旋转点\n const cos = Math.cos(angleDiff)\n const sin = Math.sin(angleDiff)\n\n this.selected.points.forEach((pt, i) => {\n const relX = this._transformStartPoints[i].x - centerX\n const relY = this._transformStartPoints[i].y - centerY\n pt.x = centerX + relX * cos - relY * sin\n pt.y = centerY + relX * sin + relY * cos\n })\n }\n\n _handleScale(p) {\n const center = this._transformCenter\n const centerX = center.centerX\n const centerY = center.centerY\n const startPoints = this._transformStartPoints\n const startPos = this._transformStartPos\n\n // 计算缩放比例\n const dx = p.x - centerX\n const dy = p.y - centerY\n const startDx = startPos.x - centerX\n const startDy = startPos.y - centerY\n\n const currentDist = Math.hypot(dx, dy)\n const startDist = Math.hypot(startDx, startDy)\n const scale = currentDist / startDist\n\n // 应用缩放\n this.selected.points.forEach((pt, i) => {\n pt.x = centerX + (startPoints[i].x - centerX) * scale\n pt.y = centerY + (startPoints[i].y - centerY) * scale\n })\n }\n\n _hitArrow(a, p) {\n for (let i = 0; i < a.points.length - 1; i++) {\n if (this._dist(p, a.points[i], a.points[i + 1]) < 15)\n return true\n }\n return false\n }\n\n _dist(p, a, b) {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const t = ((p.x - a.x) * dx + (p.y - a.y) * dy) / (dx * dx + dy * dy)\n const tt = Math.max(0, Math.min(1, t))\n const px = a.x + tt * dx\n const py = a.y + tt * dy\n return Math.hypot(p.x - px, p.y - py)\n }\n\n // 获取所有箭头数据\n getData() {\n return this.arrows.map(arrow => ({\n points: arrow.points,\n curveRate: arrow.curveRate ?? arrow.cornerRoundness ?? 0,\n strokeWidth: arrow.strokeWidth,\n color: arrow.color\n }))\n }\n\n // 设置箭头数据\n setData(data) {\n this.arrows = data.map(item => ({\n points: item.points,\n curveRate: item.curveRate ?? 0,\n strokeWidth: item.strokeWidth ?? 8,\n color: item.color\n }))\n this.render()\n }\n\n // 清空所有箭头\n clear() {\n this.arrows = []\n this.drawing = false\n this.current = null\n this.selected = null\n this.render()\n }\n}\n"],"names":["STYLES","styleEl","ArrowEditor","container","options","defs","marker","polygon","color","strokeWidth","curveRate","e","strokeInput","strokeValue","dragHandle","isDragging","dragOffset","rect","onMove","moveEvent","containerRect","newLeft","newTop","toolbarWidth","toolbarHeight","onUp","colorInput","roundInput","bbox","left","top","Keybinding","p","handle","pt","center","dx","dy","r","pts","d","i","curr","next","len","inDx","inDy","prev","outDx","outDy","after","inLen","outLen","uxIn","uyIn","uxOut","uyOut","controlDist","cp1X","cp1Y","cp2X","cp2Y","last","ux","uy","notchX","notchY","scale","baseLen","baseWidth","notchLen","tipX","tipY","baseX","baseY","px","py","leftX","leftY","rightX","rightY","arrow","index","g","path","arrowHead","scaleHandle","rotateY","rotateX","rotateLine","rotateHandle","now","dt","a","popup","label","x","y","ev","closeHandler","points","minX","minY","maxX","maxY","centerX","centerY","currentAngle","startAngle","angleDiff","cos","sin","relX","relY","startPoints","startPos","startDx","startDy","currentDist","startDist","b","t","tt","data","item"],"mappings":"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"}
|