UNPKG

mini-canvas-editor

Version:

Canvas editor component for JavaScript application. Easy to integrate and use.

2 lines (1 loc) 30.2 kB
"use strict";var e,t=require("mini-canvas-core");function s(e,t,s,i){return new(s||(s=Promise))((function(n,o){function a(e){try{c(i.next(e))}catch(e){o(e)}}function r(e){try{c(i.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(a,r)}c((i=i.apply(e,t||[])).next())}))}exports.EditorMode=void 0,(e=exports.EditorMode||(exports.EditorMode={})).select="select",e.rect="rect",e.brush="brush",e.textbox="textbox","function"==typeof SuppressedError&&SuppressedError;class i{static attrs(e,t){Object.keys(t).forEach((s=>{const i=t[s];e.setAttribute(s,"string"==typeof i?i:i.toString())}))}static element(e,t){const s=document.createElement(e);return t&&i.attrs(s,t),s}static div(e){return i.element("div",e)}}const n="http://www.w3.org/2000/svg";class o{static createSvg(e,t){const s=document.createElementNS(n,"svg");s.setAttribute("viewBox","0 -960 960 960"),s.classList.add(t);const i=document.createElementNS(n,"path");return i.setAttribute("d",e),s.appendChild(i),s}}o.cursor="m320-410 79-110h170L320-716v306ZM551-80 406-392 240-160v-720l560 440H516l144 309-109 51ZM399-520Z",o.rect="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm0 0v-560 560Z",o.eye="M480-320q75 0 127.5-52.5T660-500q0-75-52.5-127.5T480-680q-75 0-127.5 52.5T300-500q0 75 52.5 127.5T480-320Zm0-72q-45 0-76.5-31.5T372-500q0-45 31.5-76.5T480-608q45 0 76.5 31.5T588-500q0 45-31.5 76.5T480-392Zm0 192q-146 0-266-81.5T40-500q54-137 174-218.5T480-800q146 0 266 81.5T920-500q-54 137-174 218.5T480-200Zm0-300Zm0 220q113 0 207.5-59.5T832-500q-50-101-144.5-160.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280Z",o.eyeOff="m644-428-58-58q9-47-27-88t-93-32l-58-58q17-8 34.5-12t37.5-4q75 0 127.5 52.5T660-500q0 20-4 37.5T644-428Zm128 126-58-56q38-29 67.5-63.5T832-500q-50-101-143.5-160.5T480-720q-29 0-57 4t-55 12l-62-62q41-17 84-25.5t90-8.5q151 0 269 83.5T920-500q-23 59-60.5 109.5T772-302Zm20 246L624-222q-35 11-70.5 16.5T480-200q-151 0-269-83.5T40-500q21-53 53-98.5t73-81.5L56-792l56-56 736 736-56 56ZM222-624q-29 26-53 57t-41 67q50 101 143.5 160.5T480-280q20 0 39-2.5t39-5.5l-36-38q-11 3-21 4.5t-21 1.5q-75 0-127.5-52.5T300-500q0-11 1.5-21t4.5-21l-84-82Zm319 93Zm-151 75Z",o.locked="M240-80q-33 0-56.5-23.5T160-160v-400q0-33 23.5-56.5T240-640h40v-80q0-83 58.5-141.5T480-920q83 0 141.5 58.5T680-720v80h40q33 0 56.5 23.5T800-560v400q0 33-23.5 56.5T720-80H240Zm0-80h480v-400H240v400Zm240-120q33 0 56.5-23.5T560-360q0-33-23.5-56.5T480-440q-33 0-56.5 23.5T400-360q0 33 23.5 56.5T480-280ZM360-640h240v-80q0-50-35-85t-85-35q-50 0-85 35t-35 85v80ZM240-160v-400 400Z",o.close="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z",o.text="M420-160v-520H200v-120h560v120H540v520H420Z",o.image="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z",o.brush="M240-120q-45 0-89-22t-71-58q26 0 53-20.5t27-59.5q0-50 35-85t85-35q50 0 85 35t35 85q0 66-47 113t-113 47Zm0-80q33 0 56.5-23.5T320-280q0-17-11.5-28.5T280-320q-17 0-28.5 11.5T240-280q0 23-5.5 42T220-202q5 2 10 2h10Zm230-160L360-470l358-358q11-11 27.5-11.5T774-828l54 54q12 12 12 28t-12 28L470-360Zm-190 80Z",o.erase="M690-240h190v80H610l80-80Zm-500 80-85-85q-23-23-23.5-57t22.5-58l440-456q23-24 56.5-24t56.5 23l199 199q23 23 23 57t-23 57L520-160H190Zm296-80 314-322-198-198-442 456 64 64h262Zm-6-240Z",o.arrowUp="M440-160v-487L216-423l-56-57 320-320 320 320-56 57-224-224v487h-80Z",o.arrowDown="M440-800v487L216-537l-56 57 320 320 320-320-56-57-224 224v-487h-80Z",o.menu="M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z";class a{constructor(){this.listeners=[],this.forward=e=>{this.listeners.length>0&&this.listeners.forEach((t=>t(e)))}}subscribe(e){this.listeners.push(e)}unsubscribe(e){const t=this.listeners.indexOf(e);if(!(t>=0))throw new Error("Unknown listener");this.listeners.splice(t,1)}count(){return this.listeners.length}}function r(e,t,s){const n=new a,r=i.element("span",{class:`mce-icon-button mce-icon-button-${s}`,title:t}),c=o.createSvg(e,"mce-icon-button-icon"),h=c.querySelector("path");return r.appendChild(c),r.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),n.forward()}),!1),{view:r,onClicked:n,setIcon(e){h.setAttribute("d",e)}}}class c{static create(e,t,s,n){var a;const l=document.createElement("div");l.className="mce-layers-panel-item";const d=r(h(t),"Toggle visibility","sm"),u=r(o.close,"Delete layer","sm");let v,p;const b=i.div({class:"mce-layers-panel-item-label"}),m=i.element("input",{class:"mce-layers-panel-item-label-input"});m.readOnly=!0,m.value=null!==(a=t.get("label"))&&void 0!==a?a:t.type,b.appendChild(m),l.appendChild(d.view),l.appendChild(b),n||(v=r(o.arrowUp,"Move layer up","sm"),l.appendChild(v.view)),s||(p=r(o.arrowDown,"Move layer down","sm"),l.appendChild(p.view)),l.appendChild(u.view);const g=new c(l,e,t,m,d);return l.addEventListener("click",g.onItemClicked,!1),m.addEventListener("input",g.onLabelChanged,!1),d.onClicked.subscribe(g.onVisibilityClicked),null==v||v.onClicked.subscribe(g.onMoveUpClicked),null==p||p.onClicked.subscribe(g.onMoveDownClicked),u.onClicked.subscribe(g.onDeleteClicked),g}constructor(e,t,s,i,n){this.view=e,this.state=t,this.object=s,this.labelInput=i,this.visibilityButton=n,this.isSelected=!1,this.onItemClicked=e=>{e.preventDefault(),e.stopPropagation(),this.state.selectObject(this.object)},this.onVisibilityClicked=()=>{this.object.selectable&&this.object.visible?(this.object.visible=!0,this.object.selectable=!1,this.state.canvas.getActiveObject()===this.object&&this.state.canvas.discardActiveObject()):this.object.visible&&!this.object.selectable?(this.object.visible=!1,this.object.selectable=!0):(this.object.visible=!0,this.object.selectable=!0),this.visibilityButton.setIcon(h(this.object)),this.state.canvas.requestRenderAll(),this.state.onPropertiesChanged.forward(this.object)},this.onMoveUpClicked=()=>{this.state.canvas.bringObjectForward(this.object),this.state.onLayerOrderChanged.forward()},this.onMoveDownClicked=()=>{this.state.canvas.sendObjectBackwards(this.object),this.state.onLayerOrderChanged.forward()},this.onDeleteClicked=()=>{this.state.canvas.remove(this.object)},this.onLabelChanged=()=>{this.object.set("label",this.labelInput.value),this.state.onPropertiesChanged.forward(this.object)}}setIsSelected(e){this.isSelected=e,this.labelInput.readOnly=!e,this.view.classList.toggle("mce-selected",e)}}function h(e){if(!e.selectable){if(!e.visible)throw new Error("Unsupported state");return o.locked}return e.visible?o.eye:o.eyeOff}function l(e,t){const s=i.div({class:"mce-panel"}),n=i.div({class:"mce-panel-tabs"}),o=i.div({class:"mce-panel-tab"});o.innerText=e,n.appendChild(o);const a=i.div({class:"mce-panel-body"});return a.className="mce-panel-body",a.appendChild(t),s.appendChild(n),s.appendChild(a),{view:s}}class d{static create(e){const t=document.createElement("div");t.className="mce-layers-list";const s=l("Layers",t),i=new d(s.view,e,t);return e.canvas.on("object:added",i.reloadList),e.canvas.on("object:removed",i.reloadList),e.canvas.on("selection:cleared",i.reloadSelection),e.canvas.on("selection:created",i.reloadSelection),e.canvas.on("selection:updated",i.reloadSelection),e.onLayerOrderChanged.subscribe(i.reloadList),i.reloadList(),i}constructor(e,t,s){this.view=e,this.state=t,this.list=s,this.layers=[],this.reloadList=()=>{for(;this.list.firstChild;)this.list.removeChild(this.list.firstChild);this.state.forEachObject(((e,t,s)=>{const i=0===t,n=c.create(this.state,e,i,s);this.layers.push(n),this.list.firstChild?this.list.insertBefore(n.view,this.list.firstChild):this.list.appendChild(n.view)})),this.reloadSelection()},this.reloadSelection=()=>{const e=this.state.canvas.getActiveObjects();for(const t of this.layers)t.setIsSelected(e.includes(t.object))}}}class u{static create(e,t,s){const i=new u(e,s,t);for(const e of t)s.on(e,i.onExternalChanged);return i}constructor(e,t,s){this.state=e,this.object=t,this.events=s,this.accessors=[],this.onChanged=new a,this.onExternalChanged=()=>{for(const e of this.accessors){const t=e.getValue();t!==e.lastValue&&e.onExternalChanged.forward(t)}}}bind(e,t){const s={onExternalChanged:new a,lastValue:e(this.object),getValue:()=>e(this.object),setValue:e=>{t(this.object,e),s.lastValue=e,this.state.canvas.requestRenderAll(),this.onChanged.forward()}};return this.accessors.push(s),s}destroy(){for(const e of this.events)this.object.off(e,this.onExternalChanged)}}function v(e,t){const s=i.div({class:"mce-prop-simple"}),n=i.div({class:"mce-prop-simple-label"});n.innerText=e;const o=i.div({class:"mce-prop-simple-body"});return s.appendChild(n),s.appendChild(o),o.appendChild(t),{view:s}}function p(e,t,s){var n;const o=null!==(n=null==s?void 0:s.decimals)&&void 0!==n?n:1,a=i.element("input",{class:"mce-prop-number-input",type:"number",value:t.getValue().toFixed(o)});return s&&(s.step&&(a.step=s.step.toString()),"number"==typeof s.min&&a.setAttribute("min",String(s.min)),"number"==typeof s.max&&a.setAttribute("max",String(s.max))),a.addEventListener("input",(function(){const e=Number(a.value);t.setValue(e)}),!1),t.onExternalChanged.subscribe((function(e){a.value=e.toFixed(o)})),{view:v(e,a).view,destroy:function(){}}}function b(e){const t=i.div({class:"mce-prop-row"});for(const s of e){const e=i.div({class:"mce-prop-col"});e.appendChild(s.view),t.appendChild(e)}return{view:t,destroy:function(){e.forEach((e=>e.destroy()))}}}function m(e){const t=i.div({class:"mce-prop-rows"});for(const s of e)t.appendChild(s.view);return{view:t,destroy:function(){e.forEach((e=>e.destroy()))}}}function g(e,t){const s=[...t,b([p("X",e.bind((e=>e.left),((e,t)=>e.set("left",t)))),p("Y",e.bind((e=>e.top),((e,t)=>e.set("top",t))))]),b([p("Angle",e.bind((e=>e.angle),((e,t)=>e.set("angle",t))))]),b([p("Opacity",e.bind((e=>Math.round(100*e.opacity)),((e,t)=>e.set("opacity",Math.min(100,Math.max(t,0))/100))),{step:2,decimals:0,min:0,max:100})])];return{view:m(s).view,destroy:function(){s.forEach((e=>e.destroy()))}}}function w(e,t,s){const n=s.getValue(),o=i.element("select",{class:"mce-prop-choice"});o.addEventListener("change",(function(){const e=a[o.selectedIndex];s.setValue(e)}),!1);const a=Object.values(t),r=Object.keys(t).map((e=>{const s=i.element("option",{value:e});return s.text=e,t[e]===n&&(s.selected=!0),o.appendChild(s),s}));return s.onExternalChanged.subscribe((function(e){const t=a.indexOf(e);if(t>=0)for(let e=0;e<r.length;e++)r[e].selected=e===t})),{view:v(e,o).view,destroy:function(){}}}function f(e,t){const s=i.element("input",{class:"mce-prop-color-input",type:"color",value:t.getValue()||"#000"});return s.addEventListener("input",(function(){t.setValue(s.value)}),!1),t.onExternalChanged.subscribe((function(e){s.value=e})),{view:v(e,s).view,destroy:function(){}}}class C{static create(e,s){switch(e){case"rect":return function(e){const t=b([p("W",e.bind((e=>e.getScaledWidth()),((e,t)=>{e.set("width",t),e.set("scaleX",1)}))),p("H",e.bind((e=>e.getScaledHeight()),((e,t)=>{e.set("height",t),e.set("scaleY",1)})))]),s=b([p("Radius",e.bind((e=>e.rx),((e,t)=>{e.set("rx",t),e.set("ry",t)})))]),i=b([f("Fill",e.bind((e=>e.fill),((e,t)=>e.set("fill",t))))]),n=b([p("SW",e.bind((e=>e.strokeWidth),((e,t)=>e.set("strokeWidth",t)))),f("SC",e.bind((e=>e.stroke),((e,t)=>e.set("stroke",t))))]);return g(e,[t,s,i,n])}(s);case"circle":default:return function(e){return g(e,[])}(s);case"textbox":return function(e){const s=b([p("Font size",e.bind((e=>e.fontSize),((e,t)=>e.set("fontSize",t))))]),i=b([p("Line height",e.bind((e=>e.lineHeight),((e,t)=>e.set("lineHeight",t))),{step:.05,decimals:2})]),n=b([f("Color",e.bind((e=>e.fill),((e,t)=>e.set("fill",t))))]),o=b([w("Text align",{Left:"left",Center:"center",Right:"right",Justify:"justify"},e.bind((e=>e.textAlign),((e,t)=>e.set("textAlign",t))))]),a=b([w("Vertical align",{Top:t.MceVerticalAlign.top,Middle:t.MceVerticalAlign.middle,Bottom:t.MceVerticalAlign.bottom},e.bind((e=>e.verticalAlign),((e,t)=>e.set("verticalAlign",t))))]),r=b([w("Font",{Arial:"arial",Verdana:"verdana",Tahoma:"tahoma",Georgia:"georgia","Courier New":"courier new",Serif:"serif"},e.bind((e=>e.fontFamily),((e,t)=>e.set("fontFamily",t))))]),c=b([w("Weight",{Bold:"bold",Normal:"normal"},e.bind((e=>e.fontWeight),((e,t)=>e.set("fontWeight",t))))]),h=b([w("Bg",{Off:t.MceTextBackground.none,Behind:t.MceTextBackground.behind},e.bind((e=>e.textBackground),((e,t)=>e.set("textBackground",t)))),f("Color",e.bind((e=>e.textBackgroundFill),((e,t)=>e.set("textBackgroundFill",t))))]),l=b([p("SW",e.bind((e=>e.strokeWidth),((e,t)=>e.set("strokeWidth",t))),{min:0}),f("SC",e.bind((e=>e.stroke),((e,t)=>e.set("stroke",t))))]);return g(e,[s,i,n,o,a,r,c,h,l])}(s);case"image":return function(e){const t=b([p("W",e.bind((e=>e.getScaledWidth()),((e,t)=>{const s=t/e.getOriginalSize().width;e.set("scaleX",s)}))),p("H",e.bind((e=>e.getScaledHeight()),((e,t)=>{const s=t/e.getOriginalSize().height;e.set("scaleY",s)})))]);return g(e,[t])}(s)}}}class y{static create(e,t){const s=i.div({class:"mce-properties-editor"}),n=u.create(e,["modified","scaling"],t);n.onChanged.subscribe((()=>e.onPropertiesChanged.forward(t)));const o=C.create(t.type,n);return s.appendChild(o.view),new y(s,n,o)}constructor(e,t,s){this.view=e,this.manager=t,this.editor=s}destroy(){this.manager.destroy(),this.editor.destroy()}}class k{static create(e){const t=u.create(e,[],e.canvas);t.onChanged.subscribe((()=>e.onPropertiesChanged.forward(e.canvas)));const s=i.div({class:"mce-properties-editor"}),n=m([b([p("Width",t.bind((e=>e.workspaceWidth),((e,t)=>{e.workspaceBackground.set("width",t),e.workspaceWidth=t})),{decimals:0})]),b([p("Height",t.bind((e=>e.workspaceHeight),((e,t)=>{e.workspaceBackground.set("height",t),e.workspaceHeight=t})),{decimals:0})])]);return s.appendChild(n.view),new k(s)}constructor(e){this.view=e}destroy(){}}class M{static create(e){const t=document.createElement("div"),s=l("Properties",t),i=new M(s.view,e,t);return e.canvas.on("selection:cleared",i.onSelectionUpdated),e.canvas.on("selection:updated",i.onSelectionUpdated),e.canvas.on("selection:created",i.onSelectionUpdated),i.refresh(),i}constructor(e,t,s){this.view=e,this.state=t,this.container=s,this.onSelectionUpdated=()=>{this.refresh()}}refresh(){const e=this.state.canvas.getActiveObjects();if(this.component&&this.container.removeChild(this.component.view),1===e.length){const t=e[0];this.component=y.create(this.state,t)}else this.component=k.create(this.state);this.container.appendChild(this.component.view)}}class x{static create(e,t){const s=i.div({class:"mce-sidebar"}),n=i.div({class:"mce-sidebar-switch"});n.appendChild(o.createSvg(o.menu,"mce-sidebar-switch-icon"));const a=i.div({class:"mce-sidebar-body"});if(!1!==t.properties){const t=M.create(e);a.appendChild(t.view)}if(!1!==t.layers){const t=d.create(e);a.appendChild(t.view)}s.appendChild(n),s.appendChild(a);const r=new x(s);return n.addEventListener("click",r.onSwitchClicked,!1),r}constructor(e){this.view=e,this.onSwitchClicked=()=>{this.view.classList.toggle("mce-visible")}}}class j{constructor(e,t,s,i){this.canvas=e,this.mode=t,this.configuration=s,this.container=i,this.onModeChanged=new a,this.onZoomChanged=new a,this.onLayerOrderChanged=new a,this.onPropertiesChanged=new a,this.onBrushConfigurationChanged=new a,this.brush=Object.assign({brushSize:10,brushColor:"#ff0000"},this.configuration.brush||{}),this.rect=Object.assign({fillColor:"#ff0000"},this.configuration.rect||{})}center(){const e=Math.min(1,this.container.clientWidth/this.canvas.workspaceWidth,this.container.clientHeight/this.canvas.workspaceHeight),s=this.canvas.workspaceWidth*e,i=this.canvas.workspaceHeight*e,n=this.container.clientWidth/2-s/2,o=this.container.clientHeight/2-i/2;this.canvas.setZoom(e),this.canvas.absolutePan(new t.Point(-n,-o)),this.onZoomChanged.forward()}add(e){this.canvas.add(e),this.canvas.requestRenderAll()}selectObject(e){this.canvas.discardActiveObject(),this.canvas.setActiveObject(e),this.canvas.renderAll()}forEachObject(e){const t=this.canvas.getWorkspaceObjects();for(let s=0;s<t.length;s++)e(t[s],s,s+1===t.length)}disableSelection(){this.canvas.selection=!1;const e=new Map;return this.forEachObject((t=>{e.set(t,t.selectable),t.selectable&&t.set("selectable",!1)})),new q(e)}setMode(e){this.mode=e,this.onModeChanged.forward(e)}}class q{constructor(e){this.map=e}revert(){this.map.forEach(((e,t)=>t.set("selectable",e)))}}class S{constructor(e){this.state=e}init(){this.state.canvas.setCursor("move"),this.state.canvas.selection=!0}destroy(){}}class E{static create(e,t){const s=e.disableSelection(),i=new E(e,s,t);return e.canvas.on("mouse:down",i.onDown),e.canvas.on("mouse:move",i.onMove),e.canvas.on("mouse:up",i.onUp),e.canvas.setCursor("crosshair"),i}constructor(e,t,s){this.state=e,this.selectionReverter=t,this.objectFactory=s,this.object=null,this.origX=0,this.origY=0,this.onFinished=new a,this.onDown=e=>{e.e.preventDefault(),e.e.stopPropagation(),this.state.canvas.discardActiveObject();const t=this.state.canvas.getPointer(e.e);this.origX=Math.floor(t.x),this.origY=Math.floor(t.y),this.object=this.objectFactory(),this.object.set("left",this.origX),this.object.set("top",this.origX),this.state.add(this.object)},this.onMove=e=>{if(!this.object)return;const t=this.state.canvas.getPointer(e.e),s=Math.floor(t.x-this.origX),i=Math.floor(t.y-this.origY),n=Math.abs(s),o=Math.abs(i);this.object.set({left:s>0?this.origX:this.origX+s,top:i>0?this.origY:this.origY+i,width:n,height:o}),this.state.canvas.renderAll()},this.onUp=()=>{this.object&&(this.onFinished.forward(this.object),this.object=null)}}destroy(){this.state.canvas.off("mouse:down",this.onDown),this.state.canvas.off("mouse:move",this.onMove),this.state.canvas.off("mouse:up",this.onUp),this.selectionReverter.revert()}}class T{constructor(e){this.state=e}init(){this.painter=E.create(this.state,(()=>new t.MceRect({fill:this.state.rect.fillColor,stroke:this.state.rect.fillColor,strokeWidth:0}))),this.painter.onFinished.subscribe((e=>{this.state.canvas.setActiveObject(e),this.state.setMode(exports.EditorMode.select)}))}destroy(){this.painter&&(this.painter.destroy(),this.painter=void 0)}}class Z{constructor(e){this.state=e}init(){this.painter=E.create(this.state,(()=>new t.Rect({fill:"transparent",stroke:"#26aa5a",strokeWidth:1}))),this.painter.onFinished.subscribe((e=>{const s=Math.max(e.getScaledHeight(),10),i=Math.min(s,20),n=new t.MceTextbox("Text",{left:e.left,top:e.top,width:e.getScaledWidth(),maxHeight:s,fontSize:i,fill:"#000000"});this.state.canvas.remove(e),this.state.add(n),this.state.canvas.setActiveObject(n),this.state.setMode(exports.EditorMode.select)}))}destroy(){this.painter&&(this.painter.destroy(),this.painter=void 0)}}class L{constructor(e){this.state=e,this.brush=new t.PencilBrush(this.state.canvas),this.reloadBrush=()=>{this.brush.width=this.state.brush.brushSize,this.brush.color=this.state.brush.brushColor}}init(){this.reloadBrush(),this.state.canvas.freeDrawingBrush=this.brush,this.state.canvas.isDrawingMode=!0,this.state.canvas.on("path:created",(e=>{const s=e.path;this.state.canvas.remove(s);const i=new t.McePath(s.path,s);this.state.canvas.add(i)})),this.state.onBrushConfigurationChanged.subscribe(this.reloadBrush)}destroy(){this.state.canvas.freeDrawingBrush=void 0,this.state.canvas.isDrawingMode=!1,this.state.onBrushConfigurationChanged.unsubscribe(this.reloadBrush)}}class O{static get(e,t){switch(e){case exports.EditorMode.select:return new S(t);case exports.EditorMode.rect:return new T(t);case exports.EditorMode.brush:return new L(t);case exports.EditorMode.textbox:return new Z(t)}}}function A(){const e=i.div({class:"mce-workspace"}),t=document.createElement("canvas");return t.width=1,t.height=1,e.appendChild(t),{view:e,nativeCanvas:t}}const B={imageSmoothingEnabled:!0,preserveObjectStacking:!0,controlsAboveOverlay:!0,enableRetinaScaling:!0,skipOffscreen:!0};class W{static createBlank(e,s,i){const{view:n,nativeCanvas:o}=A(),a=t.MceCanvas.createBlank(e,s,o,B);return W.create(n,a,i)}static createFromJSON(e,i){return s(this,void 0,void 0,(function*(){const{view:s,nativeCanvas:n}=A(),o=yield t.MceCanvas.createFromJSON(e,n,B);return W.create(s,o,i)}))}static create(e,t,s){const i=s.initialMode||exports.EditorMode.select,n=new j(t,i,s,e),o=new W(e,t,n);return t.on("mouse:wheel",o.onWheel),n.onModeChanged.subscribe(o.reloadMode),o.reloadMode(),o}constructor(e,s,i){this.view=e,this.canvas=s,this.state=i,this.reloadLayout=()=>{if(!this.view.parentElement)throw new Error("Workspace is not attached to the DOM");this.canvas.setWidth(this.view.clientWidth),this.canvas.setHeight(this.view.clientHeight)},this.onWheel=e=>{e.e.preventDefault(),e.e.stopPropagation();const s=e.e.deltaY;let i=this.canvas.getZoom();i*=Math.pow(.999,s),i>20&&(i=20),i<.01&&(i=.01),this.canvas.zoomToPoint(new t.Point(e.e.offsetX,e.e.offsetY),i),this.state.onZoomChanged.forward()},this.reloadMode=()=>{this.currentMode&&this.currentMode.destroy(),this.currentMode=O.get(this.state.mode,this.state),this.currentMode.init()}}startAutoLayout(e){setTimeout((()=>{this.reloadLayout(),e&&this.state.center()})),window.addEventListener("resize",this.reloadLayout,!1)}destroy(){return s(this,void 0,void 0,(function*(){this.currentMode&&this.currentMode.destroy(),window.removeEventListener("resize",this.reloadLayout,!1),yield this.canvas.dispose()}))}}class H{static create(e,t,s){const n=i.div({class:"mce-toolbox-item",title:t});n.appendChild(o.createSvg(e,"mce-toolbox-item-icon"));const a=new H(n,s);return n.addEventListener("click",(e=>{e.preventDefault(),a.onClicked.forward(a)}),!1),a}constructor(e,t){this.view=e,this.mode=t,this.onClicked=new a}setIsSelected(e){this.view.classList.toggle("mce-selected",e)}}class F{static create(e){const t=i.div({class:"mce-toolbox-item",title:"Zoom / Center"}),s=i.div({class:"mce-toolbox-item-zoom"});t.appendChild(s);const n=new F(t,s,e);return t.addEventListener("click",n.onClick,!1),n.reloadZoom(),e.onZoomChanged.subscribe(n.reloadZoom),n}constructor(e,t,s){this.view=e,this.text=t,this.state=s,this.reloadZoom=()=>{const e=Math.round(100*this.state.canvas.getZoom());this.text.innerText=`${e}%`},this.onClick=()=>{this.state.center(),this.reloadZoom()}}}function P(e){return s(this,void 0,void 0,(function*(){const s=yield new Promise((e=>{const t=document.createElement("input");t.type="file",t.accept="image/*",t.addEventListener("change",(()=>{if(t.files&&t.files.length>0){const s=t.files[0],i=new FileReader;i.onload=()=>{const t=new Image;t.onload=()=>{e(t)},t.src=i.result},i.readAsDataURL(s)}else e(null)})),t.click()}));if(s){const i=Math.max(s.width/e.canvas.workspaceWidth,s.height/e.canvas.workspaceHeight),n=new t.MceImage(s,{left:0,top:0,width:s.width,height:s.height,scaleX:1/i,scaleY:1/i});e.add(n)}}))}class I{static create(e,t){const s=i.div({class:"mce-toolbox"}),n=i.div({class:"mce-toolbox-top"}),a=i.div({class:"mce-toolbox-bottom"});s.appendChild(n),s.appendChild(a);let r=null;const c=[H.create(o.cursor,"Select",exports.EditorMode.select),!1!==t.rect&&H.create(o.rect,"Rect",exports.EditorMode.rect),!1!==t.textbox&&H.create(o.text,"Textbox",exports.EditorMode.textbox),!1!==t.brush&&H.create(o.brush,"Brush",exports.EditorMode.brush),!1!==t.image&&(r=H.create(o.image,"Image",null))].filter(Boolean),h=new I(s,e,c);for(const e of c)n.appendChild(e.view),e.mode&&e.onClicked.subscribe(h.onItemClicked);r&&r.onClicked.subscribe(h.onOpenImageClicked);const l=F.create(e);return a.appendChild(l.view),h.reloadSelection(),e.onModeChanged.subscribe(h.reloadSelection),h}constructor(e,t,i){this.view=e,this.state=t,this.items=i,this.onItemClicked=e=>{e.mode&&this.state.setMode(e.mode)},this.onOpenImageClicked=()=>s(this,void 0,void 0,(function*(){P(this.state)})),this.reloadSelection=()=>{this.items.forEach((e=>{e.setIsSelected(e.mode===this.state.mode)}))}}}class D{static create(e){const t=new D(e);return window.addEventListener("resize",t.reload,!1),t.reload(),t}constructor(e){this.root=e,this.reload=()=>{this.root.clientWidth<400?this.root.classList.add("mce-mobile"):this.root.classList.remove("mce-mobile")}}destroy(){window.removeEventListener("resize",this.reload,!1)}}function z(e,t){const s=new a,n=i.element("span",{class:"mce-toolbar-label"});n.textContent=e;const o=i.element("input",{class:"mce-toolbar-color-input",type:"color",value:t});o.addEventListener("change",(function(){s.forward(o.value)}),!1);const r=i.div({class:"mce-toolbar-item"});return r.appendChild(n),r.appendChild(o),{view:r,onChanged:s}}class V{static create(e){const t=i.div({class:"mce-toolbar-brush"}),s=z("Fill",e.rect.fillColor);t.appendChild(s.view);const n=new V(t,e);return s.onChanged.subscribe(n.onFillColorChanged),n}constructor(e,t){this.view=e,this.state=t,this.onFillColorChanged=e=>{this.state.brush.brushColor=e,this.state.onBrushConfigurationChanged.forward()}}destroy(){}}class N{static create(e){const t=i.div({class:"mce-toolbar-brush"}),s=function(e,t){const s=new a,n=i.element("span",{class:"mce-toolbar-label"});n.textContent=e;const o=i.element("input",{class:"mce-toolbar-number-input",type:"number",min:"0.5",step:"0.5",value:String(t)});o.addEventListener("change",(function(){const e=Number(o.value);s.forward(e)}),!1);const r=i.div({class:"mce-toolbar-item"});return r.appendChild(n),r.appendChild(o),{view:r,onChanged:s}}("Size",e.brush.brushSize),n=z("Color",e.brush.brushColor);t.appendChild(s.view),t.appendChild(n.view);const o=new N(t,e);return s.onChanged.subscribe(o.onBrushSizeChanged),n.onChanged.subscribe(o.onBrushColorChanged),o}constructor(e,t){this.view=e,this.state=t,this.onBrushSizeChanged=e=>{this.state.brush.brushSize=e,this.state.onBrushConfigurationChanged.forward()},this.onBrushColorChanged=e=>{this.state.brush.brushColor=e,this.state.onBrushConfigurationChanged.forward()}}destroy(){}}class U{static create(e,t){switch(e){case exports.EditorMode.rect:return V.create(t);case exports.EditorMode.brush:return N.create(t)}return null}}class R{static create(e){const t=i.div({class:"mce-toolbar"}),s=new R(t,e);return e.onModeChanged.subscribe(s.reload),s.reload(),s}constructor(e,t){this.view=e,this.state=t,this.current=null,this.reload=()=>{this.current&&(this.view.removeChild(this.current.view),this.current=null);const e=U.create(this.state.mode,this.state);e?(this.current=e,this.view.appendChild(this.current.view),this.view.classList.remove("mce-hidden")):this.view.classList.add("mce-hidden")}}destroy(){this.current&&this.current.destroy()}}class X{static createBlank(e,t,s,i){const n=W.createBlank(t,s,i);return X.create(e,n,i)}static createFromImage(e,s,i,n){var o,a,r;const c=null!==(o=i.workspaceWidth)&&void 0!==o?o:s.width,h=null!==(a=i.workspaceHeight)&&void 0!==a?a:s.height,l=X.createBlank(e,c,h,n),d={width:s.width,height:s.height,selectable:null===(r=i.selectable)||void 0===r||r};if(i.fitToWorkspace){const e=Math.max(c/s.width,h/s.height);d.left=(c-s.width*e)/2,d.top=(h-s.height*e)/2,d.scaleX=e,d.scaleY=e}const u=new t.MceImage(s,d);if(l.add(u),!1===i.selectable&&i.select)throw new Error("Cannot select an image that is not selectable");return!1!==i.selectable&&i.select&&l.state.canvas.setActiveObject(u),l}static createFromJSON(e,t,i){return s(this,void 0,void 0,(function*(){const s=yield W.createFromJSON(e,i);return X.create(t,s,i)}))}static create(e,t,s){const n=i.div({class:"mce-editor"}),o=t.state,a=I.create(o,s),r=R.create(o);if(n.appendChild(a.view),n.appendChild(r.view),n.appendChild(t.view),!1!==s.sidebar){const e=x.create(o,"object"==typeof s.sidebar?s.sidebar:{});n.appendChild(e.view)}e.appendChild(n),t.startAutoLayout(!0);const c=D.create(n),h=new X(n,t,o,c);return o.canvas.on("object:added",h.onAnyChange),o.canvas.on("object:modified",h.onAnyChange),o.canvas.on("object:moving",h.onAnyChange),o.canvas.on("object:removed",h.onAnyChange),o.canvas.on("object:resizing",h.onAnyChange),o.canvas.on("object:rotating",h.onAnyChange),o.canvas.on("object:scaling",h.onAnyChange),o.canvas.on("object:skewing",h.onAnyChange),o.canvas.on("text:changed",h.onAnyChange),o.canvas.on("text:editing:exited",h.onAnyChange),o.canvas.on("selection:cleared",h.onAnyChange),o.canvas.on("selection:created",h.onAnyChange),o.canvas.on("selection:updated",h.onAnyChange),o.onLayerOrderChanged.subscribe(h.onAnyChange),o.onPropertiesChanged.subscribe(h.onAnyChange),h}constructor(e,t,s,i){this.view=e,this.workspace=t,this.state=s,this.layoutController=i,this.onChanged=new a,this.onAnyChange=()=>{this.onChanged.forward()}}getWidth(){return this.state.canvas.workspaceWidth}getHeight(){return this.state.canvas.workspaceHeight}getWorkspaceObjects(){return this.state.canvas.getWorkspaceObjects()}add(e){this.state.add(e)}toJSON(){return this.state.canvas.toImageJSON()}cloneToStaticCanvas(){return t.MceStaticCanvas.createFromJSON(this.toJSON())}render(){const e=this.state.canvas.getZoom(),s=this.state.canvas.width,i=this.state.canvas.height,n=this.state.canvas.viewportTransform,o=this.state.canvas.getActiveObjects().map((e=>{const t=e.controls,s=e.hasBorders;return e.controls={},e.hasBorders=!1,{object:e,controls:t,hasBorders:s}}));this.state.canvas.setWidth(this.state.canvas.workspaceWidth),this.state.canvas.setHeight(this.state.canvas.workspaceHeight),this.state.canvas.setZoom(1),this.state.canvas.absolutePan(new t.Point(0,0)),this.state.canvas.workspaceBackground.visible=!1;const a=this.state.canvas.toCanvasElement(1,{left:0,top:0,width:this.state.canvas.workspaceWidth,height:this.state.canvas.workspaceHeight});return this.state.canvas.setZoom(e),this.state.canvas.setWidth(s),this.state.canvas.setHeight(i),this.state.canvas.setViewportTransform(n),this.state.canvas.workspaceBackground.visible=!0,o.forEach((({object:e,controls:t,hasBorders:s})=>{e.controls=t,e.hasBorders=s})),a}destroy(){var e;return s(this,void 0,void 0,(function*(){yield this.workspace.destroy(),this.layoutController.destroy(),null===(e=this.view.parentElement)||void 0===e||e.removeChild(this.view)}))}}exports.Editor=X;