fabric-warpvas
Version:
This JavaScript library helps you efficiently build image warping tools on Fabric.js
3 lines (2 loc) • 9.98 kB
JavaScript
import{fabric as t}from"fabric";import{B as e,T as o,S as r,d as n,I as s}from"./base.class-_LMTQ4WF.js";import{c as i,r as l,a}from"./register-limit-move-event-MAdqicvl.js";const{calcMatrix:c}=s;var u;!function(t){t.TOP_LEFT="tl",t.TOP_RIGHT="tr",t.BOTTOM_LEFT="bl",t.BOTTOM_RIGHT="br"}(u||(u={}));class f extends e{constructor(t={}){super(t),this.name="warp",this.options={themeColor:o,subThemeColor:r,enableConstraintKey:"None",enableGridSplit:!0},this._styleSetters={image:()=>{},path:()=>{},control:t=>t,curveControl:t=>t,insertControl:t=>t,line:t=>{}},this._positionControlMap=new Map([]),this._insertControlObject=null,this.options=n(t,this.options)}static execute(t){if(!t.regionCurves)return[];const e=[];return t.regionBoundaryCurves.forEach(((o,r)=>{const n=[];o.forEach(((e,o)=>{const s=[],{vertical:i,horizontal:l}=t.regionCurves[r][o];for(let t=0;t<l.length;t++)for(let e=0;e<i.length;e++){const o=i[e].get(t/(l.length-1)),r=l[t].get(e/(i.length-1));s.push({x:(o.x+r.x)/2,y:(o.y+r.y)/2})}n.push(s)})),e.push(n)})),e}get controlObjects(){return Array.from(this._positionControlMap.values()).map((t=>t.majorControl))}get subControlObjects(){return Array.from(this._positionControlMap.values()).map((t=>t.subControls.map((t=>t.object)))).flat(1)}get insertControlObject(){return this._insertControlObject}get lineObjects(){return Array.from(this._positionControlMap.values()).map((t=>t.subControls.map((t=>t.line)))).flat(1)}execute(t){return f.execute(t)}dirtyRender(e){var o;const r=e.canvas;if(!r)return;const n=null===(o=e.warpvas)||void 0===o?void 0:o.regionBoundaryCurves;if(!n)return;const s=[],f=new Map;this._insertControlObject=this._styleSetters.insertControl(this._createDefaultInsertControl(this.options.themeColor));const p=()=>{var t,e;r.renderOnAddRemove=!1,this._positionControlMap.forEach((t=>{t.subControls.forEach((t=>{var e;return null===(e=t.line.canvas)||void 0===e?void 0:e.bringToFront(t.line)}))})),this._positionControlMap.forEach((t=>{t.subControls.forEach((t=>{var e;return null===(e=t.object.canvas)||void 0===e?void 0:e.bringToFront(t.object)}))})),this._positionControlMap.forEach((t=>{var e;null===(e=t.majorControl.canvas)||void 0===e||e.bringToFront(t.majorControl)})),null===(e=null===(t=this._insertControlObject)||void 0===t?void 0:t.canvas)||void 0===e||e.bringToFront(this._insertControlObject),r.renderOnAddRemove=!0,r.requestRenderAll()};n.forEach(((o,n)=>{o.forEach(((o,i)=>{const l=o;Object.entries(l).forEach((([o])=>{const a=l[o],c=e.curvePathMap.get(a),p=a.points.map((e=>t.util.transformPoint(new t.Point(e.x-c.pathOffset.x,e.y-c.pathOffset.y),c.calcOwnMatrix())));p.forEach(((e,l)=>{if(0===l||3===l)return;const c=[0,0,3,3][l],h=p[c],d={top:[u.TOP_LEFT,u.TOP_RIGHT],bottom:[u.BOTTOM_LEFT,u.BOTTOM_RIGHT],right:[u.TOP_RIGHT,u.BOTTOM_RIGHT],left:[u.TOP_LEFT,u.BOTTOM_LEFT]}[o][Math.sign(c)],v=n+(d.startsWith("b")?1:0),b=i+(d.endsWith("r")?1:0),C=`${v}-${b}`;let m=this._positionControlMap.get(C);if(!m){const t=this._styleSetters.control(this._createDefaultControl(this.options.themeColor));t.set({left:h.x,top:h.y}),r.add(t),s.push(t),m={majorControl:t,curve:a,rowIndex:n,colIndex:i,splitDotRowIndex:v,splitDotColIndex:b,vertexIndex:c,vertexType:d,subControls:[]}}if(!m.subControls.find((t=>t.attach[0]===a&&t.attach[1]===c))){const o=this._styleSetters.curveControl(this._createDefaultCurveControl());o.set({left:e.x,top:e.y});const n=new t.Line([e.x,e.y,h.x,h.y],{stroke:"rgba(200, 200, 200, 0.8)",strokeWidth:1,strokeUniform:!0,visible:!1,evented:!1,selectable:!1,originX:"center",originY:"center"});this._styleSetters.line(n),r.add(n,o),s.push(n,o),m.subControls.push({attach:[a,c],object:o,line:n,index:l})}this._positionControlMap.set(C,m),f.set(m.majorControl,C)}))}))}))})),p(),this._positionControlMap.forEach((t=>{const{majorControl:o,subControls:n}=t;n.forEach((({attach:[t],object:r,line:n,index:s})=>{r.on("moving",(()=>{const l=e.curvePathMap.get(t),a=i(r,l),c=t.points[s],u=a.x-c.x,f=a.y-c.y;r.set({angle:90+180*Math.atan2(r.top-o.top,r.left-o.left)/Math.PI}).setCoords(),t.points[s].x+=u,t.points[s].y+=f,n.set({x1:r.left,y1:r.top,x2:o.left,y2:o.top}),e.requestRender(!1,p,{skipHistoryRecording:!0})}))})),o.on("selected",(()=>{r.getActiveObject()===o&&n.forEach((({object:t,line:e})=>{var r;t.set("visible",!0),e.set("visible",!0),null===(r=o.canvas)||void 0===r||r.requestRenderAll()}))})),o.on("deselected",(()=>{n.forEach((({object:t,line:e})=>{var r;t.set("visible",!1),e.set("visible",!1),null===(r=o.canvas)||void 0===r||r.requestRenderAll()}))})),n.forEach((({object:t})=>{t.on("selected",(()=>{n.forEach((({object:t,line:e})=>{var o;t.set("visible",!0),e.set("visible",!0),null===(o=t.canvas)||void 0===o||o.requestRenderAll()}))})),t.on("deselected",(()=>{n.forEach((({object:t,line:e})=>{var o;t.set("visible",!1),e.set("visible",!1),null===(o=t.canvas)||void 0===o||o.requestRenderAll()}))}))}))}));const{enableConstraintKey:h,enableGridSplit:d}=this.options,v=[["NONE"!==h.toUpperCase(),l(r,h)],[!0,()=>{const o=()=>{const o=r.getActiveObjects(),n=new Set;for(const t of o){const e=f.get(t);if(!e)continue;this._positionControlMap.get(e)&&n.add(t)}Array.from(this._positionControlMap.values()).forEach((o=>{if(!n.has(o.majorControl))return;const{curve:r,majorControl:s,rowIndex:l,colIndex:a,vertexType:c,vertexIndex:u,subControls:f}=o,p=e.curvePathMap.get(r),h=t.util.qrDecompose(s.calcTransformMatrix(!1)),d={left:h.translateX,top:h.translateY},v=i(d,p),b=r.points[u],C=t.util.transformPoint(new t.Point(b.x-p.pathOffset.x,b.y-p.pathOffset.y),p.calcOwnMatrix()),m=v.x-b.x,g=v.y-b.y,O=d.left-C.x,x=d.top-C.y;e.warpvas.updateVertexCoord(l,a,c,v,!1),f.forEach((({attach:t,object:e,line:o,index:r})=>{t[0].points[r].x+=m,t[0].points[r].y+=g,e.set({left:e.left+O,top:e.top+x}).setCoords(),o.set({x1:e.left,y1:e.top,x2:d.left,y2:d.top})}))})),n.size&&(e.requestRender(!1,p,{skipHistoryRecording:!0}),n.clear())},n=t=>{const o=t.target;o&&"drag"===t.action&&("activeSelection"===o.type&&o.getObjects().some(this.controlObjects.includes.bind(this.controlObjects))||this.controlObjects.includes(o)||this.subControlObjects.includes(o))&&e.record()};return r.on("object:moving",o),r.on("object:modified",n),()=>{r.off("object:moving",o),r.off("object:modified",n)}}],[!0,()=>{const t=()=>{var t;const e=r.getActiveObjects(),o=new Set;for(const t of e){const e=f.get(t);if(!e)continue;this._positionControlMap.get(e)&&o.add(t)}Array.from(f.keys()).forEach((t=>{t.set({opacity:1,fill:o.has(t)?this.options.subThemeColor:this.options.themeColor})})),o.size&&(null===(t=r.getActiveObject())||void 0===t||t.set({perPixelTargetFind:!0,hasControls:!1,hasBorders:!1}),o.clear()),r.requestRenderAll()};return r.on("selection:created",t),r.on("selection:updated",t),r.on("selection:cleared",t),()=>{r.off("selection:created",t),r.off("selection:updated",t),r.off("selection:cleared",t)}}],[d,()=>{let o=null,n=null,l=null;const u=u=>{if(1!==u.e.buttons)return;const f=performance.now(),h=u.target===this._insertControlObject,d=u.target===e.warpvasObject;if(u.pointer&&this._insertControlObject&&(h?r.selection=!1:(o=null,n=null,l=null,r.remove(this._insertControlObject)),d)){const s=a(r,u.pointer),f=i({left:s.x,top:s.y},e.paths[0]);if(l=e.warpvas.getHitInfo(f),l){const{before:e,after:r,clickPart:i}=l,a=c([[r[0],r[1],r[3]],[r[2],r[1],r[3]]][i],[[e[0],e[1],e[3]],[e[2],e[1],e[3]]][i]);o=s,n=t.util.transformPoint(f,t.util.invertTransform(a))}}const v=o=>{var n;if(!o.pointer)return;if(r.selection)return;if(!this._insertControlObject)return;if(!h)return;const i=e.warpvas;if(!i)return;const l=a(r,o.pointer),c={x:l.x-this._insertControlObject.left,y:l.y-this._insertControlObject.top},u=new WeakSet([]);i.forEachRegionBoundCoords(((o,r,n,s)=>{if(u.has(s))return s.points;u.add(s);const i=e.curvePathMap.get(s),l=t.util.transformPoint(new t.Point(c.x,c.y),t.util.invertTransform(i.calcOwnMatrix()),!0);return s.points.map((t=>(t.x+=l.x,t.y+=l.y,t)))})),[this._insertControlObject,e.warpvasObject,...null!==(n=e.paths)&&void 0!==n?n:[],...s].forEach((t=>{t.set({left:t.left+c.x,top:t.top+c.y}).setCoords()})),e.requestRender(!1,p,{skipHistoryRecording:!0})},b=t=>{var s;performance.now()-f<200&&t.pointer&&this._insertControlObject&&(h?(r.remove(this._insertControlObject),null===(s=e.warpvas)||void 0===s||s.splitRegionByPoint(l.rowIndex,l.colIndex,n),e.render(!0)):o&&(this._insertControlObject.set({left:o.x,top:o.y}).setCoords(),r.add(this._insertControlObject),r.requestRenderAll())),h&&e.record(),r.selection=!0,r.off("mouse:up",b),r.off("mouse:move",v)};r.on("mouse:move",v),r.on("mouse:up",b)};return r.on("mouse:down",u),()=>{r.off("mouse:down",u)}}],[d,()=>{const t=t=>{var o;const r=[];for(const e of t){const t=f.get(e);if(!t)continue;const o=this._positionControlMap.get(t);o&&r.push(o)}r&&(null===(o=e.warpvas)||void 0===o||o.removeRegion(...r.map((t=>({row:t.splitDotRowIndex,column:t.splitDotColIndex})))),e.render(!0))},o=e=>{if(["Delete","Backspace"].includes(e.key)){const e=r.getActiveObjects();if(!e)return;t(e)}};return window.addEventListener("keydown",o),()=>{window.removeEventListener("keydown",o)}}]],b=v.map((([t,e])=>t&&e()));return()=>{b.forEach((t=>{"function"==typeof t&&t()})),this._insertControlObject&&r.remove(this._insertControlObject),r.remove(...s),this._positionControlMap.clear(),f.clear()}}_createDefaultControl(e){return new t.Circle({radius:4,fill:e,stroke:"#ffffff",paintFirst:"fill",strokeWidth:1,originX:"center",originY:"center",hasControls:!1,hasBorders:!1})}_createDefaultCurveControl(){return new t.Rect({width:6,height:6,fill:"rgba(255, 255, 255, 1)",stroke:"rgba(200, 200, 200, 0.8)",strokeWidth:1,strokeUniform:!0,visible:!1,hasControls:!1,hasBorders:!1,originX:"center",originY:"center"})}_createDefaultInsertControl(e){return new t.Circle({radius:4,fill:"rgba(255, 255, 255, 0.2)",stroke:e,strokeWidth:1,originX:"center",originY:"center",selectable:!1,hasControls:!1,hasBorders:!1})}}export{u as VertexType,f as default};
//# sourceMappingURL=warp.esm.js.map