polotno 2.28.0 → 2.28.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,4 +12,4 @@ import t from"react";import{observer as e}from"mobx-react-lite";import{Image as
12
12
  .ql-direction-rtl {
13
13
  direction: rtl;
14
14
  }
15
- `;let A=["bold","color","font","italic","size","strike","underline","indent","list","direction"];export const setQuillFormats=t=>{A=t};export const createQuill=t=>new a(t,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:A});export const setQuillContent=(t,e)=>{var o=t.clipboard.convert("<div class='ql-editor' style='outline: none;'>"+e+"<p><br></p></div>");t.setContents(o),t.history.clear()};const X=({html:e,onBlur:o,onChange:n,element:i,clickCoords:r})=>{const l=t.useRef(null);t.useEffect(()=>{if(!l.current){return}const t=(i=l.current,new a(i,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:A}));var i;return s.runInAction(()=>{quillRef.editor.instance=t}),window.__polotnoQuill=t,t.on("text-change",()=>{t.getSelection()&&s.runInAction(()=>{quillRef.currentFormat=t.getFormat(t.getSelection())}),setTimeout(()=>{var t;const e=null===(t=l.current)||void 0===t?void 0:t.childNodes[0];if(!e){return}const o=e.innerHTML;n(T(o))},10)}),setQuillContent(t,e),r?setCursorFromCoords(t,r):t.setSelection(0,0,"api"),t.on("selection-change",(e,o,n)=>{e&&s.runInAction(()=>{quillRef.currentFormat=t.getFormat(t.getSelection())})}),l.current.childNodes[0].addEventListener("blur",t=>{var e;if(null===(e=t.relatedTarget)||void 0===e?void 0:e.classList.contains("ql-clipboard")){return}const n=function(t){return!!t&&!!t.closest(".sketch-picker")}(t.relatedTarget);n||o()}),()=>{s.runInAction(()=>{quillRef.editor.instance=null,quillRef.currentFormat={}}),delete window.__polotnoQuill}},[]),t.useEffect(()=>c(()=>i.text,()=>{var t;const o=quillRef.editor.instance;if(!o){return}const n=o.getSelection();T(null===(t=l.current)||void 0===t?void 0:t.childNodes[0].innerHTML)===i.text||(setQuillContent(o,e),n&&(o.setSelection(n.index,n.length),s.runInAction(()=>{quillRef.currentFormat=o.getFormat(o.getSelection())})))},{fireImmediately:!0}),[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=l.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]);const f={color:i.fill};i.fill.indexOf("gradient")>=0&&(f.backgroundColor=i.fill,f.backgroundImage=i.fill,f.backgroundSize="100% 100%",f.backgroundRepeat="repeat",f.webkitBackgroundClip="text",f.MozBackgroundClip="text",f.WebkitTextFillColor="transparent",f.MozTextFillColor="transparent");const d=M(i);return t.createElement(W,{ref:l,style:Object.assign(Object.assign({},f),{fontSize:i.fontSize,fontWeight:i.fontWeight,textTransform:i.textTransform,width:i.a.width,fontFamily:'"'+i.fontFamily+'"',lineHeight:i.lineHeight,letterSpacing:i.letterSpacing*i.fontSize+"px",textAlign:i.align,opacity:Math.max(i.a.opacity,.2),textShadow:i.shadowEnabled?`${i.shadowOffsetX}px ${i.shadowOffsetY}px ${i.shadowBlur}px ${i.shadowColor}`:void 0,caretColor:d}),dir:h($(i.text))})};function Y(t){return!function(t){const e=t.getContext("2d").getImageData(0,0,t.width,t.height).data;for(let o=0;o<e.length;o+=4){if(0!==e[o+3]){return!0}}return!1}(t)}function I(t,{fontFamily:e="",color:o="black"}={}){let n=`color: ${o||t.fill}`;t.fill.indexOf("gradient")>=0&&(n=`\n background-color: ${o};\n background-image: ${t.fill};\n background-size: 100% 100%;\n background-repeat: repeat;\n -webkit-background-clip: text;\n -moz-background-clip: text;\n -webkit-text-fill-color: transparent;\n -moz-text-fill-color: transparent;\n `);const i=["white-space: pre-wrap","word-break: break-word",`width: ${Math.round(t.width||100)}px`,n,`font-size: ${t.fontSize}px`,`font-family: '${e}'`,`text-align: ${t.align}`,`text-transform: ${t.textTransform}`,t.textDecoration?`text-decoration: ${t.textDecoration}; text-decoration-color: ${o||t.fill}; text-decoration-layer: over`:"",t.lineHeight?`line-height: ${t.lineHeight}`:"",t.letterSpacing?`letter-spacing: ${t.letterSpacing*t.fontSize}px`:"",t.fontStyle?`font-style: ${t.fontStyle}`:"",t.fontWeight?`font-weight: ${t.fontWeight}`:"",t.strokeWidth?`-webkit-text-stroke: ${t.strokeWidth}px ${t.stroke}`:"",t.strokeWidth?"paint-order: stroke fill":""].filter(Boolean).join("; ");if(t.curveEnabled){const n=function(t){const e=new l.TextPath({data:P(t.a.width,t.a.height,t.curvePower,t.a.fontSize),align:"center",textBaseline:"middle",text:$(t.text),fontSize:t.a.fontSize,fontFamily:t.fontFamily,fontWeight:t.fontWeight,fontStyle:t.fontStyle,letterSpacing:t.letterSpacing*t.a.fontSize,fill:t.fill}),o=e.getSelfRect().height;return e.destroy(),o}(t),i=Math.round(t.width||100);return`\n <svg xmlns="http://www.w3.org/2000/svg" width="${i}" height="${n}">\n <defs><path id="curve" d="${P(i,n,t.curvePower,t.fontSize)}" fill="none" /></defs>\n <text\n font-family="'${e}'"\n font-size="${t.fontSize}"\n font-weight="${t.fontWeight}"\n font-style="${t.fontStyle}"\n fill="${o}"\n text-anchor="middle"\n dominant-baseline="middle"${t.strokeWidth?` stroke="${t.stroke}" stroke-width="${t.strokeWidth}" paint-order="stroke fill"`:""}>\n <textPath href="#curve" startOffset="50%">\n ${$(t.text).replace(/\\n/g," ")}\n </textPath>\n </text>\n </svg>`}return`<div style="${i}" contentEditable dir="${h($(t.text))}">${F(t.text).replace(/\n/g,"</br>")}</div>`}const q=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);export const HTMLElement=e(({element:e,store:a})=>{const c=t.useRef(null),[h,b]=t.useState(),[k,F]=t.useState(!1),[M,T]=t.useState(!1),A=t.useRef(e.height),B=a.selectedShapes.indexOf(e)>=0&&e.selectable,L=e.fontSize/3,{textVerticalResizeEnabled:H}=f,_=m(e.fontFamily),[D]=g(a,e.fontFamily),N=e._editModeEnabled;v(c);const Q=D?e.fontFamily:_!==e.fontFamily?_:"Arial",V=p(e).fill,J=I(e,{fontFamily:Q,color:V});let{width:G,height:K}=function(e,o,n){return t.useMemo(()=>x(e),[e,o.width,n])}(J,e,D);t.useEffect(()=>{if(!D){return}if(!e.height){return void a.history.ignore(()=>{e.set({height:K})})}const{textOverflow:t}=f;if("change-font-size"!==t||k){"resize"===t&&(H&&e.height<K&&!k&&a.history.ignore(()=>{e.set({height:K})}),H||e.height===K||a.history.ignore(()=>{e.set({height:K})}))}else{const t=(t=>{let e=t.fontSize;for(let o=1;o<50;o++){const o=I(Object.assign(Object.assign({},t.toJSON()),{fontSize:e}),{fontFamily:t.fontFamily}),{height:n}=x(o);if(!(t.height&&n>t.height||!f.textSplitAllowed&&y({html:o}))){break}e-=.5}return e})(e);t!==e.fontSize?a.history.ignore(()=>{e.set({fontSize:t})}):e.height!==K&&(H&&e.height<K?a.history.ignore(()=>{e.set({height:K})}):H||a.history.ignore(()=>{e.set({height:K})}))}});const U=t.useMemo(()=>{const t={lastArgs:null,lastResult:null};return async function(e){return t.lastArgs&&t.lastResult&&(o=t.lastArgs,n=e,JSON.stringify(o)===JSON.stringify(n))||(t.lastResult=await w(e),t.lastArgs=Object.assign({},e)),t.lastResult;var o,n}},[]),Z=t.useRef(0),tt=t.useRef(null);t.useEffect(()=>{k||N||(async()=>{Z.current++;const t=Z.current;let o=E(`text ${e.id} ${t}`);tt.current&&tt.current(),tt.current=o,T(!0);let n=null;const i=q?5:1;for(let l=0;l<i;l++){const o=l>0?U:w;try{if(n=await o({skipCache:l>0,html:J,width:e.width||1,height:e.height||K||1,fontFamily:Q,padding:L,pixelRatio:a._elementsPixelRatio,font:a.fonts.find(t=>t.fontFamily===Q)||O.globalFonts.find(t=>t.fontFamily===Q)}),t!==Z.current){return}if(q&&Y(n)){await new Promise(t=>setTimeout(t,50*(l+1)));continue}break}catch(r){console.error(r),z(`Error rendering rich text with id ${e.id}`);break}}n?b(n):o?(o(),o=null):console.error("Finish function is called twice!"),T(!1)})()},[J,k,K,N,Q,e.height,a._elementsPixelRatio,D]);const[et,ot]=j(M,300),[nt]=j(k,300,!0),it=nt||et;t.useEffect(()=>{var t;if(!it){return s.autorun(()=>{const t=c.current;d(t,e)})}null===(t=c.current)||void 0===t||t.clearCache()},[h,it,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]),t.useEffect(()=>{h&&!M&&tt.current&&(tt.current(),tt.current=null)},[h,M]),t.useLayoutEffect(()=>{if(!D){return}if(!e.curveEnabled){return}const t=new l.TextPath({data:P(e.a.width,e.a.height,e.curvePower,e.a.fontSize),text:$(e.text),letterSpacing:e.letterSpacing*e.a.fontSize,fontSize:e.a.fontSize,fontFamily:e.fontFamily,fontWeight:e.fontWeight,fontStyle:e.fontStyle,align:"center",textBaseline:"middle",fill:e.fill}),o=t.getSelfRect().width;if(o){const t=o-e.a.width,n=e.a.rotation*Math.PI/180,i=-t/2*Math.cos(n),r=-t/2*Math.sin(n);e.set({width:o,x:e.a.x+i,y:e.a.y+r})}t.destroy()},[D,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useEffect(()=>()=>{tt.current&&tt.current()},[]),t.useEffect(()=>{B||""!==$(e.text)||!e.removable||e.placeholder||a.deleteElements([e.id])},[B]);let rt=0;"middle"===e.verticalAlign&&(rt=(e.height-K)/2),"bottom"===e.verticalAlign&&(rt=e.height-K);const at=u({fontLoaded:D,fontFamily:e.fontFamily,fontSize:e.fontSize,lineHeight:e.lineHeight}),lt=R(),st=P(e.a.width,K,e.curvePower,e.fontSize),ct=t.useRef(null),ft=t.useRef(null),dt=N&&e.strokeWidth>0;return t.createElement(t.Fragment,null,t.createElement(i,{x:e.a.x,y:e.a.y,offsetX:e.backgroundPadding*(e.fontSize*at*.5),offsetY:e.backgroundPadding*(e.fontSize*at*.5),rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*e.a.opacity,fill:e.backgroundColor,width:e.a.width+e.backgroundPadding*(e.fontSize*at),height:e.a.height+e.backgroundPadding*(e.fontSize*at),cornerRadius:e.backgroundCornerRadius*(e.fontSize*at*.5)}),t.createElement(r,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,data:st,stroke:"red",strokeWidth:1,visible:!1}),t.createElement(i,{ref:c,name:"element",x:e.a.x,y:e.a.y,listening:e.selectable,rotation:e.a.rotation,width:e.a.width,height:e.a.height,visible:!it,draggable:lt?e.draggable&&B:e.draggable,preventDefault:!lt||B,opacity:N?0:e.a.opacity,hideInExport:!e.showInExport,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},id:e.id,onDblClick:t=>{e.contentEditable&&(ft.current={x:t.evt.clientX,y:t.evt.clientY},e.toggleEditMode(!0))},onDblTap:t=>{var o;if(e.contentEditable){const n=null===(o=t.evt.changedTouches)||void 0===o?void 0:o[0];ft.current=n?{x:n.clientX,y:n.clientY}:null,e.toggleEditMode(!0)}},onTransformStart:t=>{F(!0),A.current=e.height},onTransform:t=>{var o;const n=t.target,i=(null===(o=n.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor(),r="middle-left"===i||"middle-right"===i,a="top-center"===i||"bottom-center"===i,l=n.scaleX();if(r){const t=n.scaleX(),o=n.width()*t,i=e.fontSize;let r=o;if(o<i&&(r=i,ct.current&&n.position(ct.current)),n.width(r),n.scaleX(1),f.textVerticalResizeEnabled){const t=Math.max(K,A.current);e.set({height:t})}e.set({width:n.width(),x:n.x(),y:n.y()})}else if(a){let o="resize"===f.textOverflow?K:e.lineHeight*e.fontSize;const i=Math.max(o,t.target.height()*t.target.scaleY());n.scaleY(1),e.set({x:n.x(),y:n.y(),height:i,rotation:n.rotation()})}else{n.scaleX(1),n.scaleY(1),e.set({fontSize:e.fontSize*l,letterSpacing:e.letterSpacing,width:n.width()*l,x:n.x(),y:n.y(),rotation:n.rotation(),height:n.height()*l})}ct.current=t.target.position()},onTransformEnd:t=>{F(!1),T(!0);const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.fontSize*o,width:t.target.width()*o,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o})}}),t.createElement(o,{ref:c,image:h,x:e.a.x,y:e.a.y,offsetX:L,offsetY:L-rt,listening:!1,rotation:e.a.rotation,width:e.a.width+2*L,height:(e.a.width+2*L)*((null==h?void 0:h.height)/(null==h?void 0:h.width)||1),visible:!it&&!N,opacity:e.a.opacity,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled||k||it}),(it||dt)&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-rt},t.createElement(S,{divProps:{style:{pointerEvents:"none"}}},t.createElement(W,{dangerouslySetInnerHTML:{__html:J},style:{pointerEvents:"none",opacity:e.a.opacity,textShadow:e.shadowEnabled?`${e.shadowOffsetX}px ${e.shadowOffsetY}px ${e.shadowBlur}px ${e.shadowColor}`:void 0}}))),N&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-rt},t.createElement(S,null,t.createElement(X,{html:J,element:e,onChange:t=>{const o=C({oldText:$(e.text),newText:$(t),element:e});e.set({text:t,fontSize:o})},onBlur:t=>{e.toggleEditMode(!1),ot(!0)},clickCoords:ft.current}))))});export function setCursorFromCoords(t,e){if(!t||!e){return}const{x:o,y:n}=e;try{let e=null;if(document.caretRangeFromPoint){e=document.caretRangeFromPoint(o,n)}else if(document.caretPositionFromPoint){const t=document.caretPositionFromPoint(o,n);t&&(e=document.createRange(),e.setStart(t.offsetNode,t.offset))}if(e){const o=a.find(e.startContainer,!0);if(o){const n=o.offset(t.scroll)+e.startOffset;return void t.setSelection(n,0,"api")}}}catch(i){}t.setSelection(0,0,"api")}
15
+ `;let A=["bold","color","font","italic","size","strike","underline","indent","list","direction"];export const setQuillFormats=t=>{A=t};export const createQuill=t=>new a(t,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:A});export const setQuillContent=(t,e)=>{var o=t.clipboard.convert("<div class='ql-editor' style='outline: none;'>"+e+"<p><br></p></div>");t.setContents(o),t.history.clear()};const X=({html:e,onBlur:o,onChange:n,element:i,clickCoords:r})=>{const l=t.useRef(null);t.useEffect(()=>{if(!l.current){return}const t=(i=l.current,new a(i,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:A}));var i;return s.runInAction(()=>{quillRef.editor.instance=t}),window.__polotnoQuill=t,t.on("text-change",()=>{t.getSelection()&&s.runInAction(()=>{quillRef.currentFormat=t.getFormat(t.getSelection())}),setTimeout(()=>{var t;const e=null===(t=l.current)||void 0===t?void 0:t.childNodes[0];if(!e){return}const o=e.innerHTML;n(T(o))},10)}),setQuillContent(t,e),r?setCursorFromCoords(t,r):t.setSelection(0,0,"api"),t.on("selection-change",(e,o,n)=>{e&&s.runInAction(()=>{quillRef.currentFormat=t.getFormat(t.getSelection())})}),l.current.childNodes[0].addEventListener("blur",t=>{var e;if(null===(e=t.relatedTarget)||void 0===e?void 0:e.classList.contains("ql-clipboard")){return}const n=function(t){return!!t&&!!t.closest(".sketch-picker")}(t.relatedTarget);n||o()}),()=>{s.runInAction(()=>{quillRef.editor.instance=null,quillRef.currentFormat={}}),delete window.__polotnoQuill}},[]),t.useEffect(()=>c(()=>i.text,()=>{var t;const o=quillRef.editor.instance;if(!o){return}const n=o.getSelection();T(null===(t=l.current)||void 0===t?void 0:t.childNodes[0].innerHTML)===i.text||(setQuillContent(o,e),n&&(o.setSelection(n.index,n.length),s.runInAction(()=>{quillRef.currentFormat=o.getFormat(o.getSelection())})))},{fireImmediately:!0}),[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=l.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]);const f={color:i.fill};i.fill.indexOf("gradient")>=0&&(f.backgroundColor=i.fill,f.backgroundImage=i.fill,f.backgroundSize="100% 100%",f.backgroundRepeat="repeat",f.webkitBackgroundClip="text",f.MozBackgroundClip="text",f.WebkitTextFillColor="transparent",f.MozTextFillColor="transparent");const d=M(i);return t.createElement(W,{ref:l,style:Object.assign(Object.assign({},f),{fontSize:i.fontSize,fontWeight:i.fontWeight,textTransform:i.textTransform,width:i.a.width,fontFamily:'"'+i.fontFamily+'"',lineHeight:i.lineHeight,letterSpacing:i.letterSpacing*i.fontSize+"px",textAlign:i.align,opacity:Math.max(i.a.opacity,.2),textShadow:i.shadowEnabled?`${i.shadowOffsetX}px ${i.shadowOffsetY}px ${i.shadowBlur}px ${i.shadowColor}`:void 0,caretColor:d}),dir:h($(i.text))})};function Y(t){return!function(t){const e=t.getContext("2d").getImageData(0,0,t.width,t.height).data;for(let o=0;o<e.length;o+=4){if(0!==e[o+3]){return!0}}return!1}(t)}function I(t,{fontFamily:e="",color:o="black"}={}){let n=`color: ${o||t.fill}`;t.fill.indexOf("gradient")>=0&&(n=`\n background-color: ${o};\n background-image: ${t.fill};\n background-size: 100% 100%;\n background-repeat: repeat;\n -webkit-background-clip: text;\n -moz-background-clip: text;\n -webkit-text-fill-color: transparent;\n -moz-text-fill-color: transparent;\n `);const i=["white-space: pre-wrap","word-break: break-word",`width: ${Math.round(t.width||100)}px`,n,`font-size: ${t.fontSize}px`,`font-family: '${e}'`,`text-align: ${t.align}`,`text-transform: ${t.textTransform}`,t.textDecoration?`text-decoration: ${t.textDecoration}; text-decoration-color: ${o||t.fill}; text-decoration-layer: over`:"",t.lineHeight?`line-height: ${t.lineHeight}`:"",t.letterSpacing?`letter-spacing: ${t.letterSpacing*t.fontSize}px`:"",t.fontStyle?`font-style: ${t.fontStyle}`:"",t.fontWeight?`font-weight: ${t.fontWeight}`:"",t.strokeWidth?`-webkit-text-stroke: ${t.strokeWidth}px ${t.stroke}`:"",t.strokeWidth?"paint-order: stroke fill":""].filter(Boolean).join("; ");if(t.curveEnabled){const n=function(t){const e=t.a?t.a:t,o=new l.TextPath({data:P(e.width,e.height,t.curvePower,e.fontSize),align:"center",textBaseline:"middle",text:$(t.text),fontSize:e.fontSize,fontFamily:t.fontFamily,fontWeight:t.fontWeight,fontStyle:t.fontStyle,letterSpacing:t.letterSpacing*e.fontSize,fill:t.fill}),n=o.getSelfRect().height;return o.destroy(),n}(t),i=Math.round(t.width||100);return`\n <svg xmlns="http://www.w3.org/2000/svg" width="${i}" height="${n}">\n <defs><path id="curve" d="${P(i,n,t.curvePower,t.fontSize)}" fill="none" /></defs>\n <text\n font-family="'${e}'"\n font-size="${t.fontSize}"\n font-weight="${t.fontWeight}"\n font-style="${t.fontStyle}"\n fill="${o}"\n text-anchor="middle"\n dominant-baseline="central"${t.strokeWidth?` stroke="${t.stroke}" stroke-width="${t.strokeWidth}" paint-order="stroke fill"`:""}>\n <textPath href="#curve" startOffset="50%">\n ${$(t.text).replace(/\\n/g," ")}\n </textPath>\n </text>\n </svg>`}return`<div style="${i}" contentEditable dir="${h($(t.text))}">${F(t.text).replace(/\n/g,"</br>")}</div>`}const q=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);export const HTMLElement=e(({element:e,store:a})=>{const c=t.useRef(null),[h,b]=t.useState(),[k,F]=t.useState(!1),[M,T]=t.useState(!1),A=t.useRef(e.height),B=a.selectedShapes.indexOf(e)>=0&&e.selectable,L=e.fontSize/3,{textVerticalResizeEnabled:H}=f,_=m(e.fontFamily),[D]=g(a,e.fontFamily),N=e._editModeEnabled;v(c);const Q=D?e.fontFamily:_!==e.fontFamily?_:"Arial",V=p(e).fill,J=I(e,{fontFamily:Q,color:V});let{width:G,height:K}=function(e,o,n){return t.useMemo(()=>x(e),[e,o.width,n])}(J,e,D);t.useEffect(()=>{if(!D){return}if(!e.height){return void a.history.ignore(()=>{e.set({height:K})})}const{textOverflow:t}=f;if("change-font-size"!==t||k){"resize"===t&&(H&&e.height<K&&!k&&a.history.ignore(()=>{e.set({height:K})}),H||e.height===K||a.history.ignore(()=>{e.set({height:K})}))}else{const t=(t=>{let e=t.fontSize;for(let o=1;o<50;o++){const o=I(Object.assign(Object.assign({},t.toJSON()),{fontSize:e}),{fontFamily:t.fontFamily}),{height:n}=x(o);if(!(t.height&&n>t.height||!f.textSplitAllowed&&!t.curveEnabled&&y({html:o}))){break}e-=.5}return e})(e);t!==e.fontSize?a.history.ignore(()=>{e.set({fontSize:t})}):e.height!==K&&(H&&e.height<K?a.history.ignore(()=>{e.set({height:K})}):H||a.history.ignore(()=>{e.set({height:K})}))}});const U=t.useMemo(()=>{const t={lastArgs:null,lastResult:null};return async function(e){return t.lastArgs&&t.lastResult&&(o=t.lastArgs,n=e,JSON.stringify(o)===JSON.stringify(n))||(t.lastResult=await w(e),t.lastArgs=Object.assign({},e)),t.lastResult;var o,n}},[]),Z=t.useRef(0),tt=t.useRef(null);t.useEffect(()=>{k||N||(async()=>{Z.current++;const t=Z.current;let o=E(`text ${e.id} ${t}`);tt.current&&tt.current(),tt.current=o,T(!0);let n=null;const i=q?5:1;for(let l=0;l<i;l++){const o=l>0?U:w;try{if(n=await o({skipCache:l>0,html:J,width:e.width||1,height:e.height||K||1,fontFamily:Q,padding:L,pixelRatio:a._elementsPixelRatio,font:a.fonts.find(t=>t.fontFamily===Q)||O.globalFonts.find(t=>t.fontFamily===Q)}),t!==Z.current){return}if(q&&Y(n)){await new Promise(t=>setTimeout(t,50*(l+1)));continue}break}catch(r){console.error(r),z(`Error rendering rich text with id ${e.id}`);break}}n?b(n):o?(o(),o=null):console.error("Finish function is called twice!"),T(!1)})()},[J,k,K,N,Q,e.height,a._elementsPixelRatio,D]);const[et,ot]=j(M,300),[nt]=j(k,300,!0),it=nt||et;t.useEffect(()=>{var t;if(!it){return s.autorun(()=>{const t=c.current;d(t,e)})}null===(t=c.current)||void 0===t||t.clearCache()},[h,it,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]),t.useEffect(()=>{h&&!M&&tt.current&&(tt.current(),tt.current=null)},[h,M]),t.useLayoutEffect(()=>{if(!D){return}if(!e.curveEnabled){return}const t=new l.TextPath({data:P(e.a.width,e.a.height,e.curvePower,e.a.fontSize),text:$(e.text),letterSpacing:e.letterSpacing*e.a.fontSize,fontSize:e.a.fontSize,fontFamily:e.fontFamily,fontWeight:e.fontWeight,fontStyle:e.fontStyle,align:"center",textBaseline:"middle",fill:e.fill}),o=t.getSelfRect().width;if(o){const t=o-e.a.width,n=e.a.rotation*Math.PI/180,i=-t/2*Math.cos(n),r=-t/2*Math.sin(n);e.set({width:o,x:e.a.x+i,y:e.a.y+r})}t.destroy()},[D,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useEffect(()=>()=>{tt.current&&tt.current()},[]),t.useEffect(()=>{B||""!==$(e.text)||!e.removable||e.placeholder||a.deleteElements([e.id])},[B]);let rt=0;"middle"===e.verticalAlign&&(rt=(e.height-K)/2),"bottom"===e.verticalAlign&&(rt=e.height-K);const at=u({fontLoaded:D,fontFamily:e.fontFamily,fontSize:e.fontSize,lineHeight:e.lineHeight}),lt=R(),st=P(e.a.width,K,e.curvePower,e.fontSize),ct=t.useRef(null),ft=t.useRef(null),dt=N&&e.strokeWidth>0;return t.createElement(t.Fragment,null,t.createElement(i,{x:e.a.x,y:e.a.y,offsetX:e.backgroundPadding*(e.fontSize*at*.5),offsetY:e.backgroundPadding*(e.fontSize*at*.5),rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*e.a.opacity,fill:e.backgroundColor,width:e.a.width+e.backgroundPadding*(e.fontSize*at),height:e.a.height+e.backgroundPadding*(e.fontSize*at),cornerRadius:e.backgroundCornerRadius*(e.fontSize*at*.5)}),t.createElement(r,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,data:st,stroke:"red",strokeWidth:1,visible:!1}),t.createElement(i,{ref:c,name:"element",x:e.a.x,y:e.a.y,listening:e.selectable,rotation:e.a.rotation,width:e.a.width,height:e.a.height,visible:!it,draggable:lt?e.draggable&&B:e.draggable,preventDefault:!lt||B,opacity:N?0:e.a.opacity,hideInExport:!e.showInExport,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},id:e.id,onDblClick:t=>{e.contentEditable&&(ft.current={x:t.evt.clientX,y:t.evt.clientY},e.toggleEditMode(!0))},onDblTap:t=>{var o;if(e.contentEditable){const n=null===(o=t.evt.changedTouches)||void 0===o?void 0:o[0];ft.current=n?{x:n.clientX,y:n.clientY}:null,e.toggleEditMode(!0)}},onTransformStart:t=>{F(!0),A.current=e.height},onTransform:t=>{var o;const n=t.target,i=(null===(o=n.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor(),r="middle-left"===i||"middle-right"===i,a="top-center"===i||"bottom-center"===i,l=n.scaleX();if(r){const t=n.scaleX(),o=n.width()*t,i=e.fontSize;let r=o;if(o<i&&(r=i,ct.current&&n.position(ct.current)),n.width(r),n.scaleX(1),f.textVerticalResizeEnabled){const t=Math.max(K,A.current);e.set({height:t})}e.set({width:n.width(),x:n.x(),y:n.y()})}else if(a){let o="resize"===f.textOverflow?K:e.lineHeight*e.fontSize;const i=Math.max(o,t.target.height()*t.target.scaleY());n.scaleY(1),e.set({x:n.x(),y:n.y(),height:i,rotation:n.rotation()})}else{n.scaleX(1),n.scaleY(1),e.set({fontSize:e.fontSize*l,letterSpacing:e.letterSpacing,width:n.width()*l,x:n.x(),y:n.y(),rotation:n.rotation(),height:n.height()*l})}ct.current=t.target.position()},onTransformEnd:t=>{F(!1),T(!0);const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.fontSize*o,width:t.target.width()*o,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o})}}),t.createElement(o,{ref:c,image:h,x:e.a.x,y:e.a.y,offsetX:L,offsetY:L-rt,listening:!1,rotation:e.a.rotation,width:e.a.width+2*L,height:(e.a.width+2*L)*((null==h?void 0:h.height)/(null==h?void 0:h.width)||1),visible:!it&&!N,opacity:e.a.opacity,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled||k||it}),(it||dt)&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-rt},t.createElement(S,{divProps:{style:{pointerEvents:"none"}}},t.createElement(W,{dangerouslySetInnerHTML:{__html:J},style:{pointerEvents:"none",opacity:e.a.opacity,textShadow:e.shadowEnabled?`${e.shadowOffsetX}px ${e.shadowOffsetY}px ${e.shadowBlur}px ${e.shadowColor}`:void 0}}))),N&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-rt},t.createElement(S,null,t.createElement(X,{html:J,element:e,onChange:t=>{const o=C({oldText:$(e.text),newText:$(t),element:e});e.set({text:t,fontSize:o})},onBlur:t=>{e.toggleEditMode(!1),ot(!0)},clickCoords:ft.current}))))});export function setCursorFromCoords(t,e){if(!t||!e){return}const{x:o,y:n}=e;try{let e=null;if(document.caretRangeFromPoint){e=document.caretRangeFromPoint(o,n)}else if(document.caretPositionFromPoint){const t=document.caretPositionFromPoint(o,n);t&&(e=document.createRange(),e.setStart(t.offsetNode,t.offset))}if(e){const o=a.find(e.startContainer,!0);if(o){const n=o.offset(t.scroll)+e.startOffset;return void t.setSelection(n,0,"api")}}}catch(i){}t.setSelection(0,0,"api")}
package/canvas/rules.js CHANGED
@@ -36,4 +36,4 @@ import e from"react";import{getTotalClientRect as t}from"../utils/math.js";impor
36
36
  transform: rotate(90deg);
37
37
  transform-origin: left top;
38
38
  overflow: hidden;
39
- `,p=[.1,.2,.5,1,2,5,10,20,25,50,100,200,500,1e3,2e3,5e3,1e4];export const TopRules=r(({store:r,width:i,height:c})=>{const u=e.useRef(null);if(!r.activePage){return null}const h=r.activePage,f=(r.bleedVisible&&h.bleed,h.computedWidth*r.scale),g=h.computedHeight*r.scale,m=(i-f)/2,x=(b=e=>o({unitVal:e,dpi:r.dpi,unit:r.unit})*r.scale,p.find(e=>b(e)>30)||1e4);var b;const y=o({unitVal:x,dpi:r.dpi,unit:r.unit})*r.scale,v=Math.round(f/y)+1,w=Math.round(g/y)+1,k=t(r.selectedShapes);return e.createElement(l,{ref:u,className:"polotno-rulers"},e.createElement(n,{style:{width:i+"px"},className:"polotno-x-ruler"},[...Array(v)].map((t,o)=>e.createElement(s,{key:o,style:{left:m+o*y+"px",width:y+"px"}},"px"===r.unit||x>=1?Math.round(x*o):(x*o).toFixed(1))),!!r.selectedShapes.length&&e.createElement("div",{style:{position:"absolute",left:m+k.x*r.scale+"px",height:"14px",width:k.width*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}})),r.pages.map((t,o)=>{var i;const l=t.computedHeight*r.scale,n=(c-l)/2;return e.createElement(a,{key:t.id,style:{height:c+"px"},className:"polotno-y-ruler"},[...Array(w)].map((t,o)=>e.createElement(d,{key:o,style:{top:n+o*y-14+"px",width:y+"px"}},"px"===r.unit||x>=1?Math.round(x*o):(x*o).toFixed(1))),(null===(i=r.selectedShapes[0])||void 0===i?void 0:i.page)===t&&e.createElement("div",{style:{position:"absolute",top:n+k.y*r.scale-14+"px",width:"14px",height:k.height*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}}))}))});export function LeftRules(){return e.createElement("div",null,e.createElement("h1",null,"Top rules"))}
39
+ `,p=[.1,.2,.5,1,2,5,10,20,25,50,100,200,500,1e3,2e3,5e3,1e4];export const TopRules=r(({store:r,width:i,height:c})=>{const u=e.useRef(null);if(!r.activePage){return null}const h=r.activePage,f=(r.bleedVisible&&h.bleed,h.computedWidth*r.scale),g=h.computedHeight*r.scale,m=(i-f)/2,x=(b=e=>o({unitVal:e,dpi:r.dpi,unit:r.unit})*r.scale,p.find(e=>b(e)>30)||1e4);var b;const y=o({unitVal:x,dpi:r.dpi,unit:r.unit})*r.scale,v=Math.round(f/y)+1,w=Math.round(g/y)+1,k=t(r.selectedShapes);return e.createElement(l,{ref:u,className:"polotno-rulers"},e.createElement(n,{style:{width:i+"px"},className:"polotno-x-ruler"},[...Array(v)].map((t,o)=>e.createElement(s,{key:o,style:{left:m+o*y+"px",width:y+"px"}},"px"===r.unit||x>=1?Math.round(x*o):(x*o).toFixed(1))),!!r.selectedShapes.length&&e.createElement("div",{style:{position:"absolute",left:m+k.x*r.scale+"px",height:"14px",width:k.width*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}})),r.pages.map((t,o)=>{var i;const l=t.computedHeight*r.scale,n=(c-l)/2;return e.createElement(a,{key:t.id,style:{height:c-14+"px"},className:"polotno-y-ruler"},[...Array(w)].map((t,o)=>e.createElement(d,{key:o,style:{top:n+o*y-14+"px",width:y+"px"}},"px"===r.unit||x>=1?Math.round(x*o):(x*o).toFixed(1))),(null===(i=r.selectedShapes[0])||void 0===i?void 0:i.page)===t&&e.createElement("div",{style:{position:"absolute",top:n+k.y*r.scale-14+"px",width:"14px",height:k.height*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}}))}))});export function LeftRules(){return e.createElement("div",null,e.createElement("h1",null,"Top rules"))}
@@ -1 +1 @@
1
- import t from"react";import{observer as e}from"mobx-react-lite";import{Text as n,Group as o,Path as r,TextPath as i}from"react-konva";import{Html as a}from"react-konva-utils";import{autorun as l}from"mobx";import s from"konva";import{parsePath as c,roundCommands as d}from"svg-round-corners";import{useColor as h}from"./use-color.js";import{incrementLoader as u}from"../utils/loader.js";import{isFontLoaded as f}from"../utils/fonts.js";import{flags as g}from"../utils/flags.js";import{removeTags as m}from"../utils/text.js";import{applyFilter as x}from"./apply-filters.js";import{useFadeIn as p}from"./use-fadein.js";import{isTouchDevice as w}from"../utils/screen.js";import{isAlive as y}from"mobx-state-tree";import{getLimitedFontSize as v}from"./text-element/max-font-size.js";import{getOptimalCaretColor as S}from"./text-element/caret-color.js";let E;function b(){return E||(E=document.getElementById("polotno-text-style"),E||(E=document.createElement("style"),E.id="polotno-text-style",document.head.appendChild(E)),E)}s._fixTextRendering=!0;const z={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};function $(t){var e="֑-߿‏‫‮יִ-﷽ﹰ-ﻼ";return new RegExp("^[^"+e+"]*?["+e+"]").test(t)}export function isRTLText(t){t=t.replace(/\s/g,"");let e=0;for(var n=0;n<t.length;n++){$(t[n])&&(e+=1)}return e>t.length/2}export function getDir(t){return isRTLText(t)?"rtl":"ltr"}const A=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(z),s=e.current;t.useLayoutEffect(()=>{const t={};t.width=s.width()-2*s.padding()+"px",t.height=s.height()-2*s.padding()+s.fontSize()*s.lineHeight()+"px",t.fontSize=s.fontSize()+"px",t.lineHeight=s.lineHeight()+.01,t.fontFamily=s.fontFamily(),t.textAlign=s.align(),t.color=s.fill(),t.fontWeight=n.fontWeight,t.fontStyle=n.fontStyle,t.letterSpacing=n.letterSpacing+"em",t.opacity=Math.max(n.a.opacity,.2),t.textTransform=n.textTransform,t.caretColor=S(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=b();o.innerHTML="",o.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(a)&&l(t)});const c=t.useRef(null);t.useLayoutEffect(()=>{var t;const e=c.current;if(!e){return}null===(t=c.current)||void 0===t||t.focus();const n=i||e.value.length;e.selectionStart=e.selectionEnd=n,r&&(null==e||e.select(),document.execCommand("selectAll",!1,null))},[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=c.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]);let d=0;const h=s.textArr.length*s.lineHeight()*s.fontSize();"middle"===n.verticalAlign&&(d=(n.a.height-h)/2),"bottom"===n.verticalAlign&&(d=n.a.height-h);const u=m(n.text);return t.createElement("textarea",{className:"polotno-input",ref:c,dir:getDir(u),style:Object.assign(Object.assign(Object.assign({},z),a),{paddingTop:d+"px"}),value:u,onChange:t=>{const e=v({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),M=e=>t.createElement(a,null,t.createElement(A,Object.assign({},e)));export const useFontLoader=(e,n)=>{const[o,r]=t.useReducer(t=>t+1,0),i=t.useRef(f(n)),a=t.useRef(null);return t.useLayoutEffect(()=>{if(i.current=f(n),i.current){return}let t=!0;return(async()=>{i.current=!1,r();const o=u(`text ${n}`);await e.loadFont(n),t?(a.current=o,i.current=!0,r()):o()})(),()=>{a.current&&(a.current(),a.current=null),t=!1}},[n]),t.useEffect(()=>{i.current&&setTimeout(()=>{a.current&&(a.current(),a.current=null)})},[i.current]),[i.current]};export const getLineHeight=({fontLoaded:e,fontFamily:n,fontSize:o,lineHeight:r})=>t.useMemo(()=>{if("number"==typeof r){return r}const t=document.createElement("div");t.style.fontFamily=n,t.style.fontSize=o+"px",t.style.lineHeight=r,t.innerText="Test text",document.body.appendChild(t);const e=t.offsetHeight;return document.body.removeChild(t),e/o},[e,n,o,r]);export function usePrevious(e){const n=t.useRef(e),o=t.useRef(e);return t.useMemo(()=>{o.current=n.current,n.current=e},[e]),o.current}export function getCurvePath(t,e,n,o){const r=Math.max(-.9999,Math.min(.9999,n));if(Math.abs(r)<1e-4){return`M 0 ${e/2} L ${t} ${e/2}`}const i=5*o/(2*Math.abs(r))-o,a=t/2;if(r>0){const t=2*i+o/2;return[`M ${a} ${t}`,`A ${i} ${i} 0 1 1 ${a} ${t-2*i}`,`A ${i} ${i} 0 1 1 ${a} ${t}`].join(" ")}{const t=-(2*i-Math.round(e))-o/2;return[`M ${a} ${t}`,`A ${i} ${i} 0 1 0 ${a} ${t+2*i}`,`A ${i} ${i} 0 1 0 ${a} ${t}`].join(" ")}}export const TextElement=e(({element:e,store:a})=>{const s=t.useRef(null),u=t.useRef(null),f=t.useRef(null),{editorEnabled:v,selectAll:S}=(e=>{const[n,o]=t.useState(!1),r=t.useRef(!1);return t.useEffect(()=>{var t=!0;return setTimeout(()=>{t&&(e._editModeEnabled&&(r.current=!0),o(!0),setTimeout(()=>{r.current=!1},50))},50),()=>{t=!1}},[]),{editorEnabled:n&&e._editModeEnabled,selectAll:r.current}})(e),[E,b]=t.useState(!1),z=t.useRef(e.a.height),$=a.selectedShapes.indexOf(e)>=0&&e.selectable,{textVerticalResizeEnabled:A}=g,k=usePrevious(e.fontFamily),[O,F]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=s.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(O)&&F(n)}),t.useEffect(()=>{if(e.a.width){return}const t=s.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{$||""!==e.text||!e.removable||e.placeholder||a.deleteElements([e.id])},[$]),t.useLayoutEffect(()=>l(()=>{const t=s.current;x(t,e)}));const[L]=useFontLoader(a,e.fontFamily);let T=m(e.text);"uppercase"===e.textTransform&&(T=T.toUpperCase());const R=()=>{if(e.curveEnabled){const t=u.current;return t.getSelfRect().height||t.fontSize()}const t=s.current.clone({height:void 0}),n=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),n};t.useLayoutEffect(()=>{if(!L){return}const{textOverflow:t,textSplitAllowed:n}=g;if(!e.a.height){const t=R();return void a.history.ignore(()=>{e.set({height:t})})}if(!a.isPlaying){if("change-font-size"!==t||E){if("resize"===t){const t=R();A&&e.a.height<t&&a.history.ignore(()=>{var n;y(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0),A||e.a.height===t||E||a.history.ignore(()=>{var n;y(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0)}}else{const t=function(t,e,n=!1){const o=t.fontSize(),r=t.height(),i=m(e.text);let a=e.a.fontSize;t.height(void 0);const l=Math.round(2*e.a.fontSize)-1;for(let s=1;s<l;s++){const o=e.a.height&&t.height()>e.a.height;let r=i.split("\n").join(" ").split(/[\s-]+/).reduce((t,e)=>/[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFFEF\u4E00-\u9FAF\uAC00-\uD7AF]/.test(e)?t.concat(e.split("")):t.concat(e),[]),l=t.textArr.map(t=>t.text).join(";");const s=r.find(t=>!l.includes(t)||(l=l.replace(t,""),!1));if(!(o||s&&!n)){break}a-=.5,t.fontSize(a)}return t.fontSize(o),t.height(r),a}(s.current,e,n);if(t!==e.a.fontSize){return void a.history.ignore(()=>{e.set({fontSize:t})},!1,!0)}const o=R();e.a.height===o||A||a.history.ignore(()=>{e.set({height:o})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(L&&e.curveEnabled){const n=null===(t=u.current)||void 0===t?void 0:t.getSelfRect().width;if(n){const t=n-e.a.width,o=e.a.rotation*Math.PI/180,r=-t/2*Math.cos(o),i=-t/2*Math.sin(o);e.set({width:n,x:e.a.x+r,y:e.a.y+i})}}},[L,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useLayoutEffect(()=>{const t=s.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),x(t,e))},[L]);const j=t.useRef(null),C=t.useRef(0),H=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(C.current=function(t){var e;const n=t.target,o=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var n=t.getStage().getPointerPosition();return e.point(n)}(n),r=n.textArr,i=Math.floor(o.y/(n.fontSize()*n.lineHeight())),a=r.slice(0,i).reduce((t,e)=>t+e.text.length,i),l=null!==(e=r[i])&&void 0!==e?e:r[0];let s=0;return"right"===n.align()?s=n.width()-l.width:"center"===n.align()&&(s=n.width()/2-l.width/2),a+Math.round((o.x-s)/l.width*l.text.length)}(t),e.toggleEditMode())},W=!T&&e.placeholder?.6:e.a.opacity;p(s,W);const P=getLineHeight({fontLoaded:L,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),X=e.selectable||"admin"===a.role,Y=h(e),B=t.useMemo(()=>e.backgroundEnabled?function({lines:t,lineHeight:e,width:n,align:o="left",padding:r=0,cornerRadius:i=0}){var a;t.forEach((t,e)=>{t.cx=n/2,"right"===o?t.cx=n-t.width/2:"left"===o&&(t.cx=t.width/2),"justify"!==o||t.lastInParagraph||(t.width=n),"justify"===o&&(t.cx=t.width/2)});let l=`M ${null===(a=t[0])||void 0===a?void 0:a.cx} ${-r}`;t.forEach((n,o)=>{const{cx:i}=n,a=t[o-1];a&&a.width>n.width?l+=` L ${i+n.width/2+r} ${o*e+r}`:l+=` L ${i+n.width/2+r} ${o*e-r}`;const s=t[o+1];s&&s.width>n.width?l+=` L ${i+n.width/2+r} ${(o+1)*e-r}`:l+=` L ${i+n.width/2+r} ${(o+1)*e+r}`});for(var s=t.length-1;s>=0;s--){const n=t[s],{cx:o}=n,i=t[s+1];i&&i.width>n.width?l+=` L ${o-n.width/2-r} ${(s+1)*e-r}`:l+=` L ${o-n.width/2-r} ${(s+1)*e+r}`;const a=t[s-1];a&&a.width>n.width?l+=` L ${o-n.width/2-r} ${s*e+r}`:l+=` L ${o-n.width/2-r} ${s*e-r}`}l+=" Z";const h=c(l);return d(h,i).path}({lines:JSON.parse(JSON.stringify(O)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*P*.5),lineHeight:P*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*P*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.backgroundCornerRadius,e.a.fontSize,P,e.backgroundPadding,e.a.width,e.align,O]),D=w();let N=0;"middle"===e.verticalAlign?N=(e.a.height-O.length*P*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(N=e.a.height-O.length*P*e.a.fontSize);const I=e.curveEnabled?getCurvePath(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",J=L?e.fontFamily:k===e.fontFamily?"Arial":e.fontFamily;return t.createElement(t.Fragment,null,t.createElement(r,{ref:f,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*W,data:B,fill:e.backgroundColor,offsetY:-N}),t.createElement(r,{data:I,stroke:"red",strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:u,visible:e.curveEnabled,data:I,text:T||e.placeholder,listening:!1,align:"center",textBaseline:"middle"},Y,{stroke:e.stroke,strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${k}"`,fontStyle:e.fontStyle+" "+e.fontWeight,letterSpacing:e.letterSpacing*e.a.fontSize,x:e.a.x,y:e.a.y,rotation:e.a.rotation,opacity:e._editModeEnabled?.3:W,hideInExport:!e.showInExport})),t.createElement(n,Object.assign({ref:s,id:e.id,name:"element",hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled,x:e.a.x,y:e.a.y,rotation:e.a.rotation,width:e.a.width,height:e.a.height,text:T||e.placeholder,direction:getDir(T)},Y,{stroke:e.stroke,lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:J,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:D?e.draggable&&$:e.draggable,preventDefault:!D||$,opacity:e.curveEnabled?0:W,visible:!e._editModeEnabled,ellipsis:"ellipsis"===g.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:P,letterSpacing:e.letterSpacing*e.a.fontSize,listening:X,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},onClick:H,onTap:H,onTransformStart:()=>{b(!0),z.current=s.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=f.current)||void 0===n||n.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(o=i.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),n=i.width()*t,o=e.a.fontSize;let r=n;n<o&&(r=o,j.current&&i.position(j.current)),i.width(r),i.scaleX(1),i.scaleY(1);const a=R();if("ellipsis"!==g.textOverflow){const t=Math.max(a,z.current);i.height(t),e.set({height:i.height()})}const l=g.textVerticalResizeEnabled?Math.max(a,z.current):R();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),x(i,e)}if("top-center"===a||"bottom-center"===a){let n="resize"===g.textOverflow?R():P*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}j.current=t.target.position();const l=t.target.scaleX();null===(r=f.current)||void 0===r||r.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.a.fontSize*l,width:t.target.width()*l,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*l,shadowBlur:e.shadowBlur*l,shadowOffsetX:e.shadowOffsetX*l,shadowOffsetY:e.shadowOffsetY*l,strokeWidth:e.strokeWidth*l})},onTransformEnd:t=>{var n;const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:Math.round(e.a.fontSize*o),width:Math.ceil(t.target.width()*o),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*o,shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o}),null===(n=f.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),b(!1)}})),v&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement(M,{textNodeRef:s,element:e,selectAll:S,cursorPosition:C.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
1
+ import t from"react";import{observer as e}from"mobx-react-lite";import{Text as n,Group as o,Path as r,TextPath as i}from"react-konva";import{Html as a}from"react-konva-utils";import{autorun as l}from"mobx";import s from"konva";import{parsePath as c,roundCommands as d}from"svg-round-corners";import{useColor as h}from"./use-color.js";import{incrementLoader as u}from"../utils/loader.js";import{isFontLoaded as f}from"../utils/fonts.js";import{flags as g}from"../utils/flags.js";import{removeTags as m}from"../utils/text.js";import{applyFilter as p}from"./apply-filters.js";import{useFadeIn as x}from"./use-fadein.js";import{isTouchDevice as w}from"../utils/screen.js";import{isAlive as y}from"mobx-state-tree";import{getLimitedFontSize as v}from"./text-element/max-font-size.js";import{getOptimalCaretColor as S}from"./text-element/caret-color.js";let E;function b(){return E||(E=document.getElementById("polotno-text-style"),E||(E=document.createElement("style"),E.id="polotno-text-style",document.head.appendChild(E)),E)}s._fixTextRendering=!0;const z={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};function $(t){var e="֑-߿‏‫‮יִ-﷽ﹰ-ﻼ";return new RegExp("^[^"+e+"]*?["+e+"]").test(t)}export function isRTLText(t){t=t.replace(/\s/g,"");let e=0;for(var n=0;n<t.length;n++){$(t[n])&&(e+=1)}return e>t.length/2}export function getDir(t){return isRTLText(t)?"rtl":"ltr"}const O=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(z),s=e.current;t.useLayoutEffect(()=>{const t={};t.width=s.width()-2*s.padding()+"px",t.height=s.height()-2*s.padding()+s.fontSize()*s.lineHeight()+"px",t.fontSize=s.fontSize()+"px",t.lineHeight=s.lineHeight()+.01,t.fontFamily=s.fontFamily(),t.textAlign=s.align(),t.color=s.fill(),t.fontWeight=n.fontWeight,t.fontStyle=n.fontStyle,t.letterSpacing=n.letterSpacing+"em",t.opacity=Math.max(n.a.opacity,.2),t.textTransform=n.textTransform,t.caretColor=S(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=b();o.innerHTML="",o.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(a)&&l(t)});const c=t.useRef(null);t.useLayoutEffect(()=>{var t;const e=c.current;if(!e){return}null===(t=c.current)||void 0===t||t.focus();const n=i||e.value.length;e.selectionStart=e.selectionEnd=n,r&&(null==e||e.select(),document.execCommand("selectAll",!1,null))},[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=c.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]);let d=0;const h=s.textArr.length*s.lineHeight()*s.fontSize();"middle"===n.verticalAlign&&(d=(n.a.height-h)/2),"bottom"===n.verticalAlign&&(d=n.a.height-h);const u=m(n.text);return t.createElement("textarea",{className:"polotno-input",ref:c,dir:getDir(u),style:Object.assign(Object.assign(Object.assign({},z),a),{paddingTop:d+"px"}),value:u,onChange:t=>{const e=v({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),A=e=>t.createElement(a,null,t.createElement(O,Object.assign({},e)));export const useFontLoader=(e,n)=>{const[o,r]=t.useReducer(t=>t+1,0),i=t.useRef(f(n)),a=t.useRef(null);return t.useLayoutEffect(()=>{if(i.current=f(n),i.current){return}let t=!0;return(async()=>{i.current=!1,r();const o=u(`text ${n}`);await e.loadFont(n),t?(a.current=o,i.current=!0,r()):o()})(),()=>{a.current&&(a.current(),a.current=null),t=!1}},[n]),t.useEffect(()=>{i.current&&setTimeout(()=>{a.current&&(a.current(),a.current=null)})},[i.current]),[i.current]};export const getLineHeight=({fontLoaded:e,fontFamily:n,fontSize:o,lineHeight:r})=>t.useMemo(()=>{if("number"==typeof r){return r}const t=document.createElement("div");t.style.fontFamily=n,t.style.fontSize=o+"px",t.style.lineHeight=r,t.innerText="Test text",document.body.appendChild(t);const e=t.offsetHeight;return document.body.removeChild(t),e/o},[e,n,o,r]);export function usePrevious(e){const n=t.useRef(e),o=t.useRef(e);return t.useMemo(()=>{o.current=n.current,n.current=e},[e]),o.current}export function getCurvePath(t,e,n,o){const r=Math.max(-.9999,Math.min(.9999,n));if(Math.abs(r)<1e-4){return`M 0 ${e/2} L ${t} ${e/2}`}const i=5*o/(2*Math.abs(r))-o,a=t/2;if(r>0){const t=2*i+o/2;return[`M ${a} ${t}`,`A ${i} ${i} 0 1 1 ${a} ${t-2*i}`,`A ${i} ${i} 0 1 1 ${a} ${t}`].join(" ")}{const t=-(2*i-Math.round(e))-o/2;return[`M ${a} ${t}`,`A ${i} ${i} 0 1 0 ${a} ${t+2*i}`,`A ${i} ${i} 0 1 0 ${a} ${t}`].join(" ")}}export const TextElement=e(({element:e,store:a})=>{const s=t.useRef(null),u=t.useRef(null),f=t.useRef(null),{editorEnabled:v,selectAll:S}=(e=>{const[n,o]=t.useState(!1),r=t.useRef(!1);return t.useEffect(()=>{var t=!0;return setTimeout(()=>{t&&(e._editModeEnabled&&(r.current=!0),o(!0),setTimeout(()=>{r.current=!1},50))},50),()=>{t=!1}},[]),{editorEnabled:n&&e._editModeEnabled,selectAll:r.current}})(e),[E,b]=t.useState(!1),z=t.useRef(e.a.height),$=a.selectedShapes.indexOf(e)>=0&&e.selectable,{textVerticalResizeEnabled:O}=g,M=usePrevious(e.fontFamily),[k,F]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=s.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(k)&&F(n)}),t.useEffect(()=>{if(e.a.width){return}const t=s.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{$||""!==e.text||!e.removable||e.placeholder||a.deleteElements([e.id])},[$]),t.useLayoutEffect(()=>l(()=>{const t=s.current;p(t,e)}));const[L]=useFontLoader(a,e.fontFamily);let T=m(e.text);"uppercase"===e.textTransform&&(T=T.toUpperCase());const R=()=>{if(e.curveEnabled){const t=u.current;return t.getSelfRect().height||t.fontSize()}const t=s.current.clone({height:void 0}),n=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),n};t.useLayoutEffect(()=>{if(!L){return}const{textOverflow:t,textSplitAllowed:n}=g;if(!e.a.height){const t=R();return void a.history.ignore(()=>{e.set({height:t})})}if(!a.isPlaying){if("change-font-size"!==t||E){if("resize"===t){const t=R();O&&e.a.height<t&&!E&&a.history.ignore(()=>{var n;y(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0),O||e.a.height===t||E||a.history.ignore(()=>{var n;y(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0)}}else{const t=function(t,e,n=!1){const o=t.fontSize(),r=t.height(),i=m(e.text);let a=e.a.fontSize;t.height(void 0);const l=Math.round(2*e.a.fontSize)-1;for(let s=1;s<l;s++){const o=e.a.height&&t.height()>e.a.height;let r=i.split("\n").join(" ").split(/[\s-]+/).reduce((t,e)=>/[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFFEF\u4E00-\u9FAF\uAC00-\uD7AF]/.test(e)?t.concat(e.split("")):t.concat(e),[]),l=t.textArr.map(t=>t.text).join(";");const s=r.find(t=>!l.includes(t)||(l=l.replace(t,""),!1));if(!(o||s&&!n)){break}a-=.5,t.fontSize(a)}return t.fontSize(o),t.height(r),a}(s.current,e,n);if(t!==e.a.fontSize){return void a.history.ignore(()=>{e.set({fontSize:t})},!1,!0)}const o=R();e.a.height===o||O||a.history.ignore(()=>{e.set({height:o})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(L&&e.curveEnabled){const n=null===(t=u.current)||void 0===t?void 0:t.getSelfRect().width;if(n){const t=n-e.a.width,o=e.a.rotation*Math.PI/180,r=-t/2*Math.cos(o),i=-t/2*Math.sin(o);e.set({width:n,x:e.a.x+r,y:e.a.y+i})}}},[L,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useLayoutEffect(()=>{const t=s.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),p(t,e))},[L]);const j=t.useRef(null),C=t.useRef(0),H=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(C.current=function(t){var e;const n=t.target,o=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var n=t.getStage().getPointerPosition();return e.point(n)}(n),r=n.textArr,i=Math.floor(o.y/(n.fontSize()*n.lineHeight())),a=r.slice(0,i).reduce((t,e)=>t+e.text.length,i),l=null!==(e=r[i])&&void 0!==e?e:r[0];let s=0;return"right"===n.align()?s=n.width()-l.width:"center"===n.align()&&(s=n.width()/2-l.width/2),a+Math.round((o.x-s)/l.width*l.text.length)}(t),e.toggleEditMode())},W=!T&&e.placeholder?.6:e.a.opacity;x(s,W);const X=getLineHeight({fontLoaded:L,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),Y=e.selectable||"admin"===a.role,P=h(e),B=t.useMemo(()=>e.backgroundEnabled?function({lines:t,lineHeight:e,width:n,align:o="left",padding:r=0,cornerRadius:i=0}){var a;t.forEach((t,e)=>{t.cx=n/2,"right"===o?t.cx=n-t.width/2:"left"===o&&(t.cx=t.width/2),"justify"!==o||t.lastInParagraph||(t.width=n),"justify"===o&&(t.cx=t.width/2)});let l=`M ${null===(a=t[0])||void 0===a?void 0:a.cx} ${-r}`;t.forEach((n,o)=>{const{cx:i}=n,a=t[o-1];a&&a.width>n.width?l+=` L ${i+n.width/2+r} ${o*e+r}`:l+=` L ${i+n.width/2+r} ${o*e-r}`;const s=t[o+1];s&&s.width>n.width?l+=` L ${i+n.width/2+r} ${(o+1)*e-r}`:l+=` L ${i+n.width/2+r} ${(o+1)*e+r}`});for(var s=t.length-1;s>=0;s--){const n=t[s],{cx:o}=n,i=t[s+1];i&&i.width>n.width?l+=` L ${o-n.width/2-r} ${(s+1)*e-r}`:l+=` L ${o-n.width/2-r} ${(s+1)*e+r}`;const a=t[s-1];a&&a.width>n.width?l+=` L ${o-n.width/2-r} ${s*e+r}`:l+=` L ${o-n.width/2-r} ${s*e-r}`}l+=" Z";const h=c(l);return d(h,i).path}({lines:JSON.parse(JSON.stringify(k)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*X*.5),lineHeight:X*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*X*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.backgroundCornerRadius,e.a.fontSize,X,e.backgroundPadding,e.a.width,e.align,k]),D=w();let N=0;"middle"===e.verticalAlign?N=(e.a.height-k.length*X*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(N=e.a.height-k.length*X*e.a.fontSize);const I=e.curveEnabled?getCurvePath(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",J=L?'"'+e.fontFamily+'"':M===e.fontFamily?"Arial":'"'+M+'"';return t.createElement(t.Fragment,null,t.createElement(r,{ref:f,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*W,data:B,fill:e.backgroundColor,offsetY:-N}),t.createElement(r,{data:I,stroke:"red",strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:u,visible:e.curveEnabled,data:I,text:T||e.placeholder,listening:!1,align:"center",textBaseline:"middle"},P,{stroke:e.stroke,strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${M}"`,fontStyle:e.fontStyle+" "+e.fontWeight,letterSpacing:e.letterSpacing*e.a.fontSize,x:e.a.x,y:e.a.y,rotation:e.a.rotation,opacity:e._editModeEnabled?.3:W,hideInExport:!e.showInExport,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity})),t.createElement(n,Object.assign({ref:s,id:e.id,name:"element",hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled,x:e.a.x,y:e.a.y,rotation:e.a.rotation,width:e.a.width,height:e.a.height,text:T||e.placeholder,direction:getDir(T)},P,{stroke:e.stroke,lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:J,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:D?e.draggable&&$:e.draggable,preventDefault:!D||$,opacity:e.curveEnabled?0:W,visible:!e._editModeEnabled,ellipsis:"ellipsis"===g.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:X,letterSpacing:e.letterSpacing*e.a.fontSize,listening:Y,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},onClick:H,onTap:H,onTransformStart:()=>{b(!0),z.current=s.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=f.current)||void 0===n||n.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(o=i.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),n=i.width()*t,o=e.a.fontSize;let r=n;n<o&&(r=o,j.current&&i.position(j.current)),i.width(r),i.scaleX(1),i.scaleY(1);const a=R();if("ellipsis"!==g.textOverflow){const t=Math.max(a,z.current);i.height(t),e.set({height:i.height()})}const l=g.textVerticalResizeEnabled?Math.max(a,z.current):R();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),p(i,e)}if("top-center"===a||"bottom-center"===a){let n="resize"===g.textOverflow?R():X*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}j.current=t.target.position();const l=t.target.scaleX();null===(r=f.current)||void 0===r||r.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.a.fontSize*l,width:t.target.width()*l,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*l,shadowBlur:e.shadowBlur*l,shadowOffsetX:e.shadowOffsetX*l,shadowOffsetY:e.shadowOffsetY*l,strokeWidth:e.strokeWidth*l})},onTransformEnd:t=>{var n;const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:Math.round(e.a.fontSize*o),width:Math.ceil(t.target.width()*o),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*o,shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o}),null===(n=f.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),b(!1)}})),v&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement(A,{textNodeRef:s,element:e,selectAll:S,cursorPosition:C.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
package/canvas/tooltip.js CHANGED
@@ -1 +1 @@
1
- import e from"react";import{observer as t}from"mobx-react-lite";import{Html as n}from"react-konva-utils";import{Navbar as o,NavbarGroup as r}from"@blueprintjs/core";import{getTotalClientRect as l}from"../utils/math.js";import{extendToolbar as i}from"../toolbar/element-container.js";import{TextAiWrite as s}from"../toolbar/text-ai-write.js";import{DuplicateButton as a}from"../toolbar/duplicate-button.js";import{RemoveButton as u}from"../toolbar/remove-button.js";import{PositionPicker as c}from"../toolbar/position-picker.js";import{GroupButton as d}from"../toolbar/group-button.js";function m(e,t){return e.classList.contains(t)?e:e.parentElement?m(e.parentElement,t):null}const f=()=>null;export const Tooltip=t(({store:t,page:p,components:v,stageRef:h})=>{var g,E,b;const k=t.selectedShapes.every(e=>e.page===p),w=e.useRef(null),[y,x]=e.useState(!1),C=t._hasCroppedImages;t.selectedElements.length,e.useEffect(()=>{var e,t,n;const o=()=>{x(!0)},r=()=>{x(!1)};null===(e=null==h?void 0:h.current)||void 0===e||e.on("dragstart",o),null===(t=null==h?void 0:h.current)||void 0===t||t.on("dragend",r);const l=null===(n=null==h?void 0:h.current)||void 0===n?void 0:n.findOne("Transformer");return null==l||l.on("transformstart",o),null==l||l.on("transformend",r),()=>{var e,t;null===(e=null==h?void 0:h.current)||void 0===e||e.off("dragstart",o),null===(t=null==h?void 0:h.current)||void 0===t||t.off("dragend",r),null==l||l.off("transformstart",o),null==l||l.off("transformend",r)}},[]);const[I,j]=e.useState({fit:!0,needCalculate:!1,token:Math.random()});function N(){if(!w.current){return}if(!I.needCalculate){return}const e=m(w.current,"polotno-workspace-container");if(!e){return}const t=e.getBoundingClientRect(),n=w.current.getBoundingClientRect(),o=(n.right,t.left,n.top-t.top),r=(n.left,t.left,n.bottom-t.top);o<20&&I.fit?j({fit:!1,needCalculate:!1,token:I.token}):r-t.height>-20&&!I.fit?j({fit:!0,needCalculate:!1,token:I.token}):j({fit:I.fit,needCalculate:!1,token:I.token})}if(e.useEffect(()=>{0!==t.selectedElements.length&&j({fit:!0,needCalculate:!0,token:Math.random()})},[t.selectedElements,y]),e.useLayoutEffect(()=>{const e=setTimeout(()=>{N()},100);return()=>{clearTimeout(e)}},[I.needCalculate,w.current,I.token]),e.useEffect(()=>{if(!h.current){return}const e=m(h.current.content,"polotno-workspace-inner");if(!e){return}const n=()=>{t.selectedElements.length&&j({fit:!0,needCalculate:!0,token:Math.random()})};return null==e||e.addEventListener("scroll",n),()=>{null==e||e.removeEventListener("scroll",n)}},[]),0===t.selectedShapes.length){return null}if(y){return null}if(!k){return null}if(t.activePage!==p){return null}if(C){return null}const T=l(t.selectedShapes),O=(null==v?void 0:v.Position)||c,R=(null==v?void 0:v.Duplicate)||a,S=(null==v?void 0:v.Remove)||u,M=(null==v?void 0:v.Group)||d,Y=(null==v?void 0:v.Lock)||f,B=null===(g=t.selectedElements[0])||void 0===g?void 0:g.type,F=Object.assign({TextAiWrite:s},v),L=i({components:F,type:B,usedItems:[]}),P=(null===(b=null===(E=null==h?void 0:h.current)||void 0===E?void 0:E.findOne("Transformer"))||void 0===b?void 0:b.rotation())||0;let X=30;return Math.abs(P)<30&&I.fit&&(X=80),Math.abs(P)>140&&!I.fit&&(X=80),e.createElement(n,{parentNodeFunc:({stage:e})=>{var t,n;return(null===(t=null==e?void 0:e.container())||void 0===t?void 0:t.closest(".polotno-workspace-container"))||(null===(n=null==e?void 0:e.container())||void 0===n?void 0:n.parentNode)},transformFunc:e=>{var t;const n=T.x+T.width/2,o=I.fit?T.y*e.scaleY-X:T.y*e.scaleY+T.height*e.scaleY+X,r=null===(t=null==h?void 0:h.current)||void 0===t?void 0:t.container(),l=(null==r?void 0:r.getBoundingClientRect())||{left:0,top:0,width:0,height:0,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},i=null==r?void 0:r.closest(".polotno-workspace-container"),s=(null==i?void 0:i.getBoundingClientRect())||{left:0,top:0,width:Number.POSITIVE_INFINITY,height:Number.POSITIVE_INFINITY,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},a=l.left-s.left,u=l.top-s.top;let c=a+e.x+n*e.scaleX,d=c-T.width*e.scaleX/2,m=c+T.width*e.scaleX/2;const f=Math.min(50,T.width/2*e.scaleX),p=m>=f&&d<=s.width-f,v=w.current?w.current.getBoundingClientRect().width:0;if(Number.isFinite(s.width)&&v>0&&p){const e=8+v/2,t=s.width-8-v/2;t>=e&&(c=Math.max(e,Math.min(c,t)))}return m<f&&(c-=v+8),d>s.width-f&&(c+=v+8),Object.assign(Object.assign({},e),{x:c,y:u+e.y+o,scaleX:1,scaleY:1})},divProps:{style:{pointerEvents:"none",position:"absolute",visibility:I.needCalculate?"hidden":"visible",zIndex:9}}},e.createElement("div",{ref:e=>{w.current=e,N()},style:{pointerEvents:"none"}},e.createElement(o,{style:{padding:"2px",borderRadius:"5px",height:"34px",transform:"translate(-50%, -50%)",pointerEvents:"auto"}},e.createElement(r,{style:{height:"30px"}},L.map(n=>{const o=F[n];return e.createElement(o,{elements:t.selectedElements,element:t.selectedElements[0],store:t,key:n})}),e.createElement(M,{store:t}),e.createElement(Y,{store:t}),e.createElement(R,{store:t}),e.createElement(S,{store:t}),e.createElement(O,{store:t})))))});
1
+ import e from"react";import{observer as t}from"mobx-react-lite";import{Html as n}from"react-konva-utils";import{Navbar as o,NavbarGroup as r}from"@blueprintjs/core";import{getTotalClientRect as l}from"../utils/math.js";import{extendToolbar as i}from"../toolbar/element-container.js";import{TextAiWrite as s}from"../toolbar/text-ai-write.js";import{DuplicateButton as a}from"../toolbar/duplicate-button.js";import{RemoveButton as u}from"../toolbar/remove-button.js";import{PositionPicker as c}from"../toolbar/position-picker.js";import{GroupButton as d}from"../toolbar/group-button.js";function m(e,t){return e.classList.contains(t)?e:e.parentElement?m(e.parentElement,t):null}const f=()=>null;export const Tooltip=t(({store:t,page:p,components:v,stageRef:h})=>{var g,E,b;const k=t.selectedShapes.every(e=>e.page===p),w=e.useRef(null),[y,x]=e.useState(!1),C=t._hasCroppedImages;t.selectedElements.length,e.useEffect(()=>{var e,t,n;const o=()=>{x(!0)},r=()=>{x(!1)};null===(e=null==h?void 0:h.current)||void 0===e||e.on("dragstart",o),null===(t=null==h?void 0:h.current)||void 0===t||t.on("dragend",r);const l=null===(n=null==h?void 0:h.current)||void 0===n?void 0:n.findOne("Transformer");return null==l||l.on("transformstart",o),null==l||l.on("transformend",r),()=>{var e,t;null===(e=null==h?void 0:h.current)||void 0===e||e.off("dragstart",o),null===(t=null==h?void 0:h.current)||void 0===t||t.off("dragend",r),null==l||l.off("transformstart",o),null==l||l.off("transformend",r)}},[]);const[I,j]=e.useState({fit:!0,needCalculate:!1,token:Math.random()});function N(){if(!w.current){return}if(!I.needCalculate){return}const e=m(w.current,"polotno-workspace-container");if(!e){return}const t=e.getBoundingClientRect(),n=w.current.getBoundingClientRect(),o=(n.right,t.left,n.top-t.top),r=(n.left,t.left,n.bottom-t.top);o<20&&I.fit?j({fit:!1,needCalculate:!1,token:I.token}):r-t.height>-20&&!I.fit?j({fit:!0,needCalculate:!1,token:I.token}):j({fit:I.fit,needCalculate:!1,token:I.token})}if(e.useEffect(()=>{0!==t.selectedElements.length&&j({fit:!0,needCalculate:!0,token:Math.random()})},[t.selectedElements,y]),e.useLayoutEffect(()=>{const e=setTimeout(()=>{N()},100);return()=>{clearTimeout(e)}},[I.needCalculate,w.current,I.token]),e.useEffect(()=>{if(!h.current){return}const e=m(h.current.content,"polotno-workspace-inner");if(!e){return}const n=()=>{t.selectedElements.length&&j({fit:!0,needCalculate:!0,token:Math.random()})};return null==e||e.addEventListener("scroll",n),()=>{null==e||e.removeEventListener("scroll",n)}},[]),0===t.selectedShapes.length){return null}if(y){return null}if(!k){return null}if(t.activePage!==p){return null}if(C){return null}const T=l(t.selectedShapes),O=(null==v?void 0:v.Position)||c,R=(null==v?void 0:v.Duplicate)||a,S=(null==v?void 0:v.Remove)||u,M=(null==v?void 0:v.Group)||d,Y=(null==v?void 0:v.Lock)||f,B=null===(g=t.selectedElements[0])||void 0===g?void 0:g.type,F=Object.assign({TextAiWrite:s},v),L=i({components:F,type:B,usedItems:[]}),P=(null===(b=null===(E=null==h?void 0:h.current)||void 0===E?void 0:E.findOne("Transformer"))||void 0===b?void 0:b.rotation())||0;let X=30;return Math.abs(P)<30&&I.fit&&(X=80),Math.abs(P)>140&&!I.fit&&(X=80),e.createElement(n,{parentNodeFunc:({stage:e})=>{var t,n;return(null===(t=null==e?void 0:e.container())||void 0===t?void 0:t.closest(".polotno-workspace-container"))||(null===(n=null==e?void 0:e.container())||void 0===n?void 0:n.parentNode)},transformFunc:e=>{var t;const n=T.x+T.width/2,o=I.fit?T.y*e.scaleY-X:T.y*e.scaleY+T.height*e.scaleY+X,r=null===(t=null==h?void 0:h.current)||void 0===t?void 0:t.container(),l=(null==r?void 0:r.getBoundingClientRect())||{left:0,top:0,width:0,height:0,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},i=null==r?void 0:r.closest(".polotno-workspace-container"),s=(null==i?void 0:i.getBoundingClientRect())||{left:0,top:0,width:Number.POSITIVE_INFINITY,height:Number.POSITIVE_INFINITY,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},a=l.left-s.left,u=l.top-s.top;let c=a+e.x+n*e.scaleX,d=c-T.width*e.scaleX/2,m=c+T.width*e.scaleX/2;const f=Math.min(50,T.width/2*e.scaleX),p=m>=f&&d<=s.width-f,v=w.current?w.current.getBoundingClientRect().width:0;if(Number.isFinite(s.width)&&v>0&&p){const e=8+v/2,t=s.width-8-v/2;t>=e&&(c=Math.max(e,Math.min(c,t)))}return m<f&&(c-=v+8),d>s.width-f&&(c+=v+8),Object.assign(Object.assign({},e),{x:c,y:u+e.y+o,scaleX:1,scaleY:1})},divProps:{style:{pointerEvents:"none",position:"absolute",visibility:I.needCalculate?"hidden":"visible",zIndex:9}}},e.createElement("div",{ref:e=>{w.current=e,!w.current&&e&&N()},style:{pointerEvents:"none"}},e.createElement(o,{style:{padding:"2px",borderRadius:"5px",height:"34px",transform:"translate(-50%, -50%)",pointerEvents:"auto"}},e.createElement(r,{style:{height:"30px"}},L.map(n=>{const o=F[n];return e.createElement(o,{elements:t.selectedElements,element:t.selectedElements[0],store:t,key:n})}),e.createElement(M,{store:t}),e.createElement(Y,{store:t}),e.createElement(R,{store:t}),e.createElement(S,{store:t}),e.createElement(O,{store:t})))))});
@@ -7,6 +7,7 @@ export declare const Audio: import("mobx-state-tree").IModelType<{
7
7
  endTime: import("mobx-state-tree").IType<number, number, number>;
8
8
  volume: import("mobx-state-tree").IType<number, number, number>;
9
9
  delay: import("mobx-state-tree").IType<number, number, number>;
10
+ custom: import("mobx-state-tree").IType<any, any, any>;
10
11
  }, {
11
12
  toJSON(): {
12
13
  id: string;
@@ -16,6 +17,7 @@ export declare const Audio: import("mobx-state-tree").IModelType<{
16
17
  endTime: number;
17
18
  volume: number;
18
19
  delay: number;
20
+ custom: any;
19
21
  };
20
22
  } & {
21
23
  set(attrs: any): void;
@@ -1 +1 @@
1
- import{types as t,getSnapshot as e}from"mobx-state-tree";export const Audio=t.model("Audio",{id:t.identifier,src:"",duration:0,startTime:0,endTime:1,volume:1,delay:0}).actions(t=>({toJSON:()=>Object.assign({},e(t))})).actions(t=>({set(e){Object.assign(t,e)}}));
1
+ import{types as t,getSnapshot as e}from"mobx-state-tree";export const Audio=t.model("Audio",{id:t.identifier,src:"",duration:0,startTime:0,endTime:1,volume:1,delay:0,custom:t.frozen()}).actions(t=>({toJSON:()=>Object.assign({},e(t))})).actions(t=>({set(e){Object.assign(t,e)}}));
@@ -65,7 +65,6 @@ export declare const GifElement: import("mobx-state-tree").IModelType<{
65
65
  borderSize: import("mobx-state-tree").IType<number, number, number>;
66
66
  keepRatio: import("mobx-state-tree").IType<boolean, boolean, boolean>;
67
67
  stretchEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
68
- _cropModeEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
69
68
  } & {
70
69
  type: import("mobx-state-tree").IType<string, string, string>;
71
70
  duration: import("mobx-state-tree").IType<number, number, number>;
@@ -141,6 +140,8 @@ export declare const GifElement: import("mobx-state-tree").IModelType<{
141
140
  } & {
142
141
  toggleCropMode(flag?: boolean): void;
143
142
  beforeDestroy(): void;
143
+ } & {
144
+ readonly _cropModeEnabled: boolean;
144
145
  }, import("mobx-state-tree").ModelCreationType<{
145
146
  id: string;
146
147
  type: string;
@@ -394,7 +394,6 @@ export declare const TYPES_MAP: {
394
394
  borderSize: import("mobx-state-tree").IType<number, number, number>;
395
395
  keepRatio: import("mobx-state-tree").IType<boolean, boolean, boolean>;
396
396
  stretchEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
397
- _cropModeEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
398
397
  }, {
399
398
  readonly locked: boolean;
400
399
  readonly page: any;
@@ -466,6 +465,8 @@ export declare const TYPES_MAP: {
466
465
  } & {
467
466
  toggleCropMode(flag?: boolean): void;
468
467
  beforeDestroy(): void;
468
+ } & {
469
+ readonly _cropModeEnabled: boolean;
469
470
  }, import("mobx-state-tree").ModelCreationType<{
470
471
  id: string;
471
472
  type: string;
@@ -682,7 +683,6 @@ export declare const TYPES_MAP: {
682
683
  borderSize: import("mobx-state-tree").IType<number, number, number>;
683
684
  keepRatio: import("mobx-state-tree").IType<boolean, boolean, boolean>;
684
685
  stretchEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
685
- _cropModeEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
686
686
  } & {
687
687
  type: import("mobx-state-tree").IType<string, string, string>;
688
688
  duration: import("mobx-state-tree").IType<number, number, number>;
@@ -760,6 +760,8 @@ export declare const TYPES_MAP: {
760
760
  } & {
761
761
  toggleCropMode(flag?: boolean): void;
762
762
  beforeDestroy(): void;
763
+ } & {
764
+ readonly _cropModeEnabled: boolean;
763
765
  }, import("mobx-state-tree").ModelCreationType<{
764
766
  id: string;
765
767
  type: string;
@@ -975,7 +977,6 @@ export declare const TYPES_MAP: {
975
977
  borderSize: import("mobx-state-tree").IType<number, number, number>;
976
978
  keepRatio: import("mobx-state-tree").IType<boolean, boolean, boolean>;
977
979
  stretchEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
978
- _cropModeEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
979
980
  } & {
980
981
  type: import("mobx-state-tree").IType<string, string, string>;
981
982
  duration: import("mobx-state-tree").IType<number, number, number>;
@@ -1051,6 +1052,8 @@ export declare const TYPES_MAP: {
1051
1052
  } & {
1052
1053
  toggleCropMode(flag?: boolean): void;
1053
1054
  beforeDestroy(): void;
1055
+ } & {
1056
+ readonly _cropModeEnabled: boolean;
1054
1057
  }, import("mobx-state-tree").ModelCreationType<{
1055
1058
  id: string;
1056
1059
  type: string;
package/model/history.js CHANGED
@@ -1 +1 @@
1
- import{types as t,resolvePath as e,onSnapshot as o,getSnapshot as a,applySnapshot as n}from"mobx-state-tree";import{deepEqual as r}from"../utils/deep-equal.js";Object.assign(t);export const UndoManager=t.model("UndoManager",{history:t.array(t.frozen()),undoIdx:-1,targetPath:""}).views(t=>({get canUndo(){return t.undoIdx>0},get canRedo(){return t.undoIdx<t.history.length-1}})).actions(t=>{let d,s,i=!1,c=null,h=0,u=0;const l=()=>u>0;function g(){const t=a(d);return{pages:t.pages,width:t.width,height:t.height,custom:t.custom,audios:t.audios}}function m(t){const e=d.pages.map(t=>t.id),o=t.pages.map(t=>t.id),a=!r(e,o),s=!r(d.custom,t.custom);a?n(d.pages,t.pages):d.pages.forEach((e,o)=>{n(e,t.pages[o])}),s&&d.set({custom:t.custom}),d.setSize(t.width,t.height)}return{startTransaction(){u++},endTransaction(t){u--,t||this.requestAddState(g())},async ignore(e,o=!1,a=!1){a&&await new Promise(t=>setTimeout(t,10)),h&&t.addUndoState();let n=l();t.startTransaction();let r=u;try{await e()}catch(i){setTimeout(()=>{throw i})}const d=r!==u,s=!d;t.endTransaction(s),o||n||t.replaceState(),d||(clearTimeout(h),h=0)},async transaction(e){await t.ignore(e,!0),this.addUndoState()},requestAddState(t){c=t,h||l()||(i?i=!1:h=setTimeout(()=>{h=0,clearTimeout(h),l()||this.addUndoState()},100))},addUndoState(){if(i){return void(i=!1)}const e=t.history[t.undoIdx];!r(c,e)&&(clearTimeout(h),h=0,t.history.splice(t.undoIdx+1),t.history.push(c),t.undoIdx=t.history.length-1)},afterCreate(){if(d=e(t,".."),!d){throw new Error("Failed to find target store for UndoManager. Please provide `targetPath` property, or a `targetStore` in the environment")}s=o(d,()=>{this.requestAddState(g())}),0===t.history.length&&this.requestAddState(g())},clear(){clearTimeout(h),h=0,t.history.splice(0,t.history.length),t.undoIdx=-1,t.addUndoState(g())},beforeDestroy(){s()},undo(){h&&this.addUndoState(),t.canUndo?(t.undoIdx--,i=!0,m(t.history[t.undoIdx])):console.warn("No undo history. Please check `store.history.canUndo` before calling undo action.")},redo(){h&&this.addUndoState(),t.canRedo?(t.undoIdx++,i=!0,m(t.history[t.undoIdx])):console.warn("No redo history. Please check `store.history.canRedo` before calling redo action.")},replaceState(){t.history[t.undoIdx]=g()}}});export default UndoManager;
1
+ import{types as t,resolvePath as e,onSnapshot as o,getSnapshot as a,applySnapshot as n}from"mobx-state-tree";import{deepEqual as r}from"../utils/deep-equal.js";Object.assign(t);export const UndoManager=t.model("UndoManager",{history:t.array(t.frozen()),undoIdx:-1,targetPath:""}).views(t=>({get canUndo(){return t.undoIdx>0},get canRedo(){return t.undoIdx<t.history.length-1}})).actions(t=>{let d,s,i=!1,c=null,h=0,u=0;const l=()=>u>0;function g(){const t=a(d);return{pages:t.pages,width:t.width,height:t.height,custom:t.custom,audios:t.audios}}function m(t){const e=d.pages.map(t=>t.id),o=t.pages.map(t=>t.id),a=!r(e,o),s=!r(d.custom,t.custom);a?n(d.pages,t.pages):d.pages.forEach((e,o)=>{n(e,t.pages[o])}),s&&d.set({custom:t.custom}),d.setSize(t.width,t.height)}return{startTransaction(){u++},endTransaction(t){u--,t||this.requestAddState(g())},async ignore(e,o=!1,a=!1){a&&await new Promise(t=>setTimeout(t,10)),h&&t.addUndoState();let n=l();t.startTransaction();let r=u;try{await e()}catch(i){setTimeout(()=>{throw i})}const d=r!==u,s=!d;t.endTransaction(s),o||n||t.replaceState(),d||(clearTimeout(h),h=0)},async transaction(e){await t.ignore(e,!0),this.addUndoState()},requestAddState(t){c=t,h||l()||(i?i=!1:h=setTimeout(()=>{h=0,clearTimeout(h),l()||this.addUndoState()},100))},addUndoState(){if(i){return void(i=!1)}const e=t.history[t.undoIdx];!r(c,e)&&(clearTimeout(h),h=0,t.history.splice(t.undoIdx+1),t.history.push(c),t.undoIdx=t.history.length-1)},afterCreate(){if(d=e(t,".."),!d){throw new Error("Failed to find target store for UndoManager. Please provide `targetPath` property, or a `targetStore` in the environment")}s=o(d,()=>{this.requestAddState(g())}),0===t.history.length&&this.requestAddState(g())},clear(){clearTimeout(h),h=0,t.history.splice(0,t.history.length),t.undoIdx=-1,t.addUndoState(g())},beforeDestroy(){s()},undo(){h&&this.addUndoState(),l()?m(t.history[t.undoIdx]):t.canUndo?(t.undoIdx--,i=!0,m(t.history[t.undoIdx])):console.warn("No undo history. Please check `store.history.canUndo` before calling undo action.")},redo(){h&&this.addUndoState(),t.canRedo?(t.undoIdx++,i=!0,m(t.history[t.undoIdx])):console.warn("No redo history. Please check `store.history.canRedo` before calling redo action.")},replaceState(){t.history[t.undoIdx]=g()}}});export default UndoManager;
@@ -65,7 +65,6 @@ export declare const ImageElement: import("mobx-state-tree").IModelType<{
65
65
  borderSize: import("mobx-state-tree").IType<number, number, number>;
66
66
  keepRatio: import("mobx-state-tree").IType<boolean, boolean, boolean>;
67
67
  stretchEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
68
- _cropModeEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
69
68
  }, {
70
69
  readonly locked: boolean;
71
70
  readonly page: any;
@@ -137,6 +136,8 @@ export declare const ImageElement: import("mobx-state-tree").IModelType<{
137
136
  } & {
138
137
  toggleCropMode(flag?: boolean): void;
139
138
  beforeDestroy(): void;
139
+ } & {
140
+ readonly _cropModeEnabled: boolean;
140
141
  }, import("mobx-state-tree").ModelCreationType<{
141
142
  id: string;
142
143
  type: string;
@@ -1 +1 @@
1
- import{Shape as o}from"./shape-model.js";export const ImageElement=o.named("Image").props({type:"image",width:100,height:100,src:"",cropX:0,cropY:0,cropWidth:1,cropHeight:1,cornerRadius:0,flipX:!1,flipY:!1,clipSrc:"",borderColor:"black",borderSize:0,keepRatio:!1,stretchEnabled:!1,_cropModeEnabled:!1}).actions(o=>({toggleCropMode(e){o._cropModeEnabled=null!=e?e:!o._cropModeEnabled,o._cropModeEnabled?o.store.history.startTransaction():o.store.history.endTransaction()},beforeDestroy(){o._cropModeEnabled&&o.store.history.endTransaction()}}));
1
+ import{observable as e}from"mobx";import{Shape as o}from"./shape-model.js";export const ImageElement=o.named("Image").props({type:"image",width:100,height:100,src:"",cropX:0,cropY:0,cropWidth:1,cropHeight:1,cornerRadius:0,flipX:!1,flipY:!1,clipSrc:"",borderColor:"black",borderSize:0,keepRatio:!1,stretchEnabled:!1}).extend(o=>{const r=e.box(!1);let t=!1;return{views:{get _cropModeEnabled(){return r.get()}},actions:{toggleCropMode(e){const s=null!=e?e:!r.get();r.set(s),s&&!t?(o.store.history.startTransaction(),t=!0):!s&&t&&(o.store.history.endTransaction(),t=!1)},beforeDestroy(){t&&(o.store.history.endTransaction(),t=!1)}}}});
@@ -0,0 +1,183 @@
1
+ export interface Store {
2
+ schemaVersion: number;
3
+ width: number;
4
+ height: number;
5
+ unit: 'px' | 'pt' | 'mm' | 'in';
6
+ dpi: number;
7
+ custom?: unknown;
8
+ fonts: Font[];
9
+ pages: Page[];
10
+ audios: Audio[];
11
+ }
12
+ export interface Font {
13
+ fontFamily: string;
14
+ url?: string;
15
+ styles?: unknown;
16
+ }
17
+ export interface Audio {
18
+ id: string;
19
+ src: string;
20
+ duration: number;
21
+ startTime: number;
22
+ endTime: number;
23
+ volume: number;
24
+ delay: number;
25
+ }
26
+ export interface Page {
27
+ id: string;
28
+ width: number | 'auto';
29
+ height: number | 'auto';
30
+ background: string;
31
+ bleed: number;
32
+ custom?: unknown;
33
+ duration: number;
34
+ children: Element[];
35
+ }
36
+ export type Element = TextElement | ImageElement | SVGElement | LineElement | VideoElement | FigureElement | GifElement | GroupElement;
37
+ export interface Animation {
38
+ delay: number;
39
+ duration: number;
40
+ enabled: boolean;
41
+ type: 'enter' | 'exit' | 'loop';
42
+ name: string;
43
+ data: unknown;
44
+ }
45
+ interface ShapeAttributes {
46
+ id: string;
47
+ type: string;
48
+ name?: string;
49
+ custom?: unknown;
50
+ x: number;
51
+ y: number;
52
+ width: number;
53
+ height: number;
54
+ rotation: number;
55
+ opacity: number;
56
+ animations: Animation[];
57
+ blurEnabled: boolean;
58
+ blurRadius: number;
59
+ brightnessEnabled: boolean;
60
+ brightness: number;
61
+ sepiaEnabled: boolean;
62
+ grayscaleEnabled: boolean;
63
+ filters: Record<string, {
64
+ intensity: number;
65
+ }>;
66
+ shadowEnabled: boolean;
67
+ shadowBlur: number;
68
+ shadowOffsetX: number;
69
+ shadowOffsetY: number;
70
+ shadowColor: string;
71
+ shadowOpacity: number;
72
+ visible: boolean;
73
+ draggable: boolean;
74
+ resizable: boolean;
75
+ selectable: boolean;
76
+ contentEditable: boolean;
77
+ styleEditable: boolean;
78
+ alwaysOnTop: boolean;
79
+ showInExport: boolean;
80
+ }
81
+ export interface GroupElement {
82
+ id: string;
83
+ type: 'group';
84
+ name?: string;
85
+ custom?: unknown;
86
+ opacity?: number;
87
+ visible?: boolean;
88
+ selectable?: boolean;
89
+ removable?: boolean;
90
+ alwaysOnTop?: boolean;
91
+ showInExport?: boolean;
92
+ children: Element[];
93
+ }
94
+ export interface TextElement extends ShapeAttributes {
95
+ type: 'text';
96
+ text: string;
97
+ placeholder: string;
98
+ fontSize: number;
99
+ fontFamily: string;
100
+ fontStyle: string;
101
+ fontWeight: string;
102
+ textDecoration: string;
103
+ textTransform: string;
104
+ fill: string;
105
+ align: 'left' | 'center' | 'right' | 'justify';
106
+ height: number;
107
+ verticalAlign: string;
108
+ strokeWidth: number;
109
+ stroke: string;
110
+ lineHeight: number | string;
111
+ letterSpacing: number;
112
+ backgroundEnabled: boolean;
113
+ backgroundColor: string;
114
+ backgroundOpacity: number;
115
+ backgroundCornerRadius: number;
116
+ backgroundPadding: number;
117
+ curveEnabled: boolean;
118
+ curvePower: number;
119
+ }
120
+ interface BaseImageProps {
121
+ src: string;
122
+ cropX: number;
123
+ cropY: number;
124
+ cropWidth: number;
125
+ cropHeight: number;
126
+ cornerRadius: number;
127
+ flipX: boolean;
128
+ flipY: boolean;
129
+ clipSrc: string;
130
+ borderColor: string;
131
+ borderSize: number;
132
+ keepRatio: boolean;
133
+ stretchEnabled: boolean;
134
+ }
135
+ export interface ImageElement extends ShapeAttributes, BaseImageProps {
136
+ type: 'image';
137
+ }
138
+ export interface SVGElement extends ShapeAttributes {
139
+ type: 'svg';
140
+ src: string;
141
+ maskSrc: string;
142
+ cropX: number;
143
+ cropY: number;
144
+ cropWidth: number;
145
+ cropHeight: number;
146
+ keepRatio: boolean;
147
+ stretchEnabled: boolean;
148
+ flipX: boolean;
149
+ flipY: boolean;
150
+ borderColor: string;
151
+ borderSize: number;
152
+ cornerRadius: number;
153
+ colorsReplace: Record<string, string>;
154
+ }
155
+ export interface LineElement extends ShapeAttributes {
156
+ type: 'line';
157
+ color: string;
158
+ dash: number[];
159
+ startHead: string;
160
+ endHead: string;
161
+ }
162
+ export interface FigureElement extends ShapeAttributes {
163
+ type: 'figure';
164
+ subType: string;
165
+ fill: string;
166
+ dash: number[];
167
+ strokeWidth: number;
168
+ stroke: string;
169
+ cornerRadius: number;
170
+ }
171
+ export interface GifElement extends ShapeAttributes, BaseImageProps {
172
+ type: 'gif';
173
+ duration: number;
174
+ keepRatio: boolean;
175
+ }
176
+ export interface VideoElement extends ShapeAttributes, BaseImageProps {
177
+ type: 'video';
178
+ duration: number;
179
+ startTime: number;
180
+ endTime: number;
181
+ volume: number;
182
+ }
183
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/model/store.d.ts CHANGED
@@ -107,6 +107,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
107
107
  endTime: import("mobx-state-tree").IType<number, number, number>;
108
108
  volume: import("mobx-state-tree").IType<number, number, number>;
109
109
  delay: import("mobx-state-tree").IType<number, number, number>;
110
+ custom: import("mobx-state-tree").IType<any, any, any>;
110
111
  }, {
111
112
  toJSON(): {
112
113
  id: string;
@@ -116,6 +117,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
116
117
  endTime: number;
117
118
  volume: number;
118
119
  delay: number;
120
+ custom: any;
119
121
  };
120
122
  } & {
121
123
  set(attrs: any): void;
@@ -985,6 +987,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
985
987
  endTime: import("mobx-state-tree").IType<number, number, number>;
986
988
  volume: import("mobx-state-tree").IType<number, number, number>;
987
989
  delay: import("mobx-state-tree").IType<number, number, number>;
990
+ custom: import("mobx-state-tree").IType<any, any, any>;
988
991
  }>[];
989
992
  unit: string;
990
993
  dpi: number;
package/model/store.js CHANGED
@@ -1 +1 @@
1
- var e=this&&this.__rest||function(e,t){var i={};for(var o in e){Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(i[o]=e[o])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++){t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(i[o[n]]=e[o[n]])}}return i};import{types as t,onSnapshot as i,applySnapshot as o,detach as n,getSnapshot as a,cast as s,destroy as r,setLivelinessChecking as l}from"mobx-state-tree";import{UndoManager as d}from"./history.js";import{nanoid as c}from"nanoid";import p from"konva";import{computed as g}from"mobx";import{downloadFile as m}from"../utils/download.js";import{getJsPDF as u}from"../utils/pdf.js";import{createGIF as f}from"../utils/gif-lib.js";import{validateKey as h}from"../utils/validate-key.js";import*as y from"../utils/fonts.js";import{flags as b}from"../utils/flags.js";import{whenLoaded as v}from"../utils/loader.js";import{pxToUnit as w}from"../utils/unit.js";import{deepEqual as P}from"../utils/deep-equal.js";import{waitTillAvailable as E}from"../utils/wait.js";import{jsonToHTML as x}from"../utils/to-html.js";import{jsonToSVG as _}from"../utils/to-svg.js";import{Page as I}from"./page-model.js";import{forEveryChild as k}from"./group-model.js";import{Audio as S}from"./audio-model.js";l("ignore");export const Font=t.model("Font",{fontFamily:t.string,url:t.optional(t.string,""),styles:t.frozen()}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}));export const Store=t.model("Store",{role:"",pages:t.array(I),fonts:t.array(Font),audios:t.array(S),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:"px",dpi:72,schemaVersion:2,bleedVisible:!1,rulesVisible:!1,openedSidePanel:"",previousOpenedSidePanel:"",custom:t.frozen(),selectedElementsIds:t.array(t.string),animatedElementsIds:t.array(t.string),history:t.optional(d,{targetPath:"../pages"}),_elementsPixelRatio:Math.min(2,"undefined"!=typeof window&&window.devicePixelRatio||1),_activePageId:"",_selectedPagesIds:t.array(t.string),_forceShowCredit:!1,_key:"",_validated:!1}).views(e=>{const t=g(()=>{const t={};return k({children:e.pages},e=>(t[e.id]=e,!1)),t},{keepAlive:!0});return{get _idsMap(){return t.get()}}}).views(e=>({get _bleedVisible(){return console.warn("store._bleedVisible is deprecated. Please use store.bleedVisible instead."),e.bleedVisible},get selectedElements(){return e.selectedElementsIds.map(t=>{for(const i of e.pages){for(const e of i.children){if(e.id===t){return e}}}}).filter(e=>!!e)},get children(){return e.pages},get selectedShapes(){const t=[];return k({children:e.selectedElements},e=>{"group"!==e.type&&t.push(e)}),t},get activePage(){return e.pages.slice().find(t=>t.id===e._activePageId)||(e.pages.length?e.pages[0]:null)},get selectedPages(){return e._selectedPagesIds.map(t=>e.pages.find(e=>e.id===t))},get duration(){let t=0;return e.pages.forEach(e=>{t+=e.duration}),t},get _hasCroppedImages(){return e.find(e=>"image"===e.type&&e._cropModeEnabled)},find(t){let i;return k({children:e.pages},e=>{if(!i&&t(e)){return i=e,!0}}),i},getElementById:t=>e._idsMap[t]})).actions(e=>{let t=0,i=null,o=!1;return{afterCreate(){e.history.canUndo},setCurrentTime(t){e.currentTime=t},_togglePlaying(t=!e.isPlaying){e.isPlaying=t},play({animatedElementsIds:n=[],startTime:a=0,currentTime:r=0,endTime:l=e.duration,repeat:d=!1}={}){r&&(console.warn("currentTime property of store.play() is deprecated. Please use startTime instead."),a=r),e.animatedElementsIds=s(n),e.currentTime=a,e.isPlaying=!0,t=Date.now(),i=l,o=d,requestAnimationFrame(e.seek)},checkActivePage(){let t=0;for(const i of e.pages){if(e.currentTime>=i.startTime&&e.currentTime<i.startTime+i.duration){e.selectPage(i.id);break}t+=i.duration}},seek(){if(!e.isPlaying){return}const n=Date.now(),a=n-t;t=n,e.currentTime+=a,e.checkActivePage();const s=i||e.duration;e.isPlaying&&e.currentTime<s?requestAnimationFrame(e.seek):e.isPlaying&&o?(e.currentTime=0,requestAnimationFrame(e.seek)):e.stop()},stop(){e.isPlaying=!1,e.currentTime=0,e.animatedElementsIds=s([]),e.checkActivePage()}}}).actions(t=>({__(){t._validated||(h(t._key,t._forceShowCredit),t._validated=!0)},set(e){Object.assign(t,e)},setUnit({unit:e,dpi:i}){t.unit=e||t.unit,t.dpi=i||t.dpi},setRole(e){t.role=e},addPage(e){const i=I.create(Object.assign({id:c(10)},e));return t.pages.push(i),t._activePageId=i.id,i},selectPage(e){t._activePageId=e,1===t._selectedPagesIds.length&&(t._selectedPagesIds=s([e]))},selectPages(e){t._selectedPagesIds=s(e),1===t._selectedPagesIds.length&&(t._activePageId=t._selectedPagesIds[0])},selectElements(e){const i=e.map(e=>t.getElementById(e)).sort((e,t)=>e.page.children.indexOf(e)-e.page.children.indexOf(t)).filter(e=>!!e).map(e=>e.id);t.selectedElementsIds=s(i)},toggleBleed(e){t.bleedVisible=null!=e?e:!t.bleedVisible},toggleRulers(e){t.rulesVisible=null!=e?e:!t.rulesVisible},openSidePanel(e){t.openedSidePanel!==e&&(t.previousOpenedSidePanel=t.openedSidePanel,t.openedSidePanel=e)},setScale(e){t.scale=e},_setScaleToFit(e){t.scaleToFit=e},setElementsPixelRatio(e){t._elementsPixelRatio=e},setSize(e,i,o){t.pages.forEach(t=>{t.setSize({width:e,height:i,useMagic:o,softChange:!0})}),t.width=e,t.height=i},setPageZIndex(e,i){const o=t.pages.find(t=>t.id===e);o&&(n(o),t.pages.remove(o),t.pages.splice(i,0,o))},deletePages(e){const i=t.pages.indexOf(t.activePage);e.forEach(e=>{const i=t.pages.find(t=>t.id===e);r(i)});const o=Math.min(t.pages.length-1,i),n=t.pages[o];n&&(t._activePageId=n.id),t.selectedElementsIds=s(t.selectedElementsIds.filter(e=>t.getElementById(e)))},groupElements(e,i={}){const o=e.map(e=>t.getElementById(e)),a=o[0].page;if(o.forEach(e=>{e&&n(e)}),!o.length){return}const r=Object.assign({id:c(10),children:o,type:"group"},i);return a.children.push(r),t.selectedElementsIds=s([r.id]),a.children.find(e=>e.id===r.id)},ungroupElements(e){const i=e.map(e=>t.getElementById(e)),o=[];i.forEach(e=>{if(e&&"group"===e.type){const t=e.page,i=t.children.indexOf(e);e.children.forEach(e=>{o.push(e.id)}),e.children.forEach(e=>{n(e),t.children.push(e)}),t.children.splice(i,1)}}),t.selectedElementsIds=s(o)},deleteElements(e){const i=[];t.find(t=>(e.includes(t.id)&&i.push(t),!1)),i.forEach(e=>{r(e)}),t.selectedElementsIds=s(t.selectedElementsIds.filter(e=>t.getElementById(e)))},on(e,o){if("change"===e){let e=t.toJSON();return i(t,i=>{const n=t.toJSON();!P(e,n)&&(e=n,o(n))})}},async _toCanvas({pixelRatio:e,ignoreBackground:i,pageId:o,mimeType:n,includeBleed:a,_skipTimeout:s,quickMode:r=!1}={}){var l;const d=e||1;o=o||(null===(l=t.pages[0])||void 0===l?void 0:l.id);const c=t.pages.find(e=>e.id===o);if(!c){throw new Error(`No page for export with id ${o}`)}const g=t._elementsPixelRatio;d>t._elementsPixelRatio&&t.setElementsPixelRatio(d),r?null==c||c.set({_forceMount:!0}):null==c||c.set({_exporting:!0});const m=await E(()=>p.stages.find(e=>e.getAttr("pageId")===o));if(!m){throw null==c||c.set({_forceMount:!1,_exporting:!1}),t.setElementsPixelRatio(g),new Error(`Export is failed. Can not find stage for page ${o}. Looks like <Workspace /> component is not mounted, but it is required in order to process the export.`)}await t.waitLoading({_skipTimeout:s});const u=m.findOne(".page-container");if(!u){throw t.setElementsPixelRatio(g),null==c||c.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const f=m.position();m.position({x:0,y:0}),m.find("Transformer").forEach(e=>{e.setAttr("oldVisible",e.visible()),e.visible(!1)}),u.find(".page-background").forEach(e=>e.shadowEnabled(!1)),u.find(".page-background").forEach(e=>e.strokeEnabled(!1)),u.find(".highlighter").forEach(e=>e.visible(!1));const h=u.findOne(".page-background-group"),y=h.clip();h.clip({x:null,y:null,width:null,height:null});const b=u.findOne(".elements-container"),v=b.clip();b.clip({x:null,y:null,width:null,height:null});const w=u.find(e=>!e.visible()&&e.getAttr("editModeEnabled")&&!e.getAttr("hideInExport"));w.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()});const P=u.find(e=>e.getAttr("hideInExport"));P.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()}),i&&u.find(".page-background").forEach(e=>e.hide());const x=a?c.bleed:0;let _=x;!t.bleedVisible&&a||(t.bleedVisible||a?t.bleedVisible&&a?_=0:t.bleedVisible&&!a&&(_=-c.bleed):_=0);const I=document.createElement("canvas");I.width=Math.round((c.computedWidth+2*x)*d),I.height=Math.round((c.computedHeight+2*x)*d);const k=I.getContext("2d");"image/jpeg"===n&&(k.fillStyle="white",k.fillRect(0,0,I.width,I.height));const S=u.scale();u.scale({x:1,y:1});const O=u.toCanvas({x:u.x()-_,y:u.y()-_,width:c.computedWidth+2*x,height:c.computedHeight+2*x,pixelRatio:d});return u.scale(S),k.drawImage(O,0,0,I.width,I.height),p.Util.releaseCanvas(O),i&&u.find(".page-background").forEach(e=>e.show()),P.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),w.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),u.find(".page-background").forEach(e=>e.shadowEnabled(!0)),u.find(".page-background").forEach(e=>e.strokeEnabled(!0)),m.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),u.find(".highlighter").forEach(e=>e.visible(!0)),h.clip(y),b.clip(v),m.position(f),null==c||c.set({_exporting:!1,_forceMount:!1}),await new Promise(e=>setTimeout(e)),t.setElementsPixelRatio(g),I},async toDataURL(i={}){var{mimeType:o,quality:n}=i,a=e(i,["mimeType","quality"]);const s=await t._toCanvas(Object.assign({mimeType:o},a)),r=s.toDataURL(o,n);return p.Util.releaseCanvas(s),r},async toBlob(i={}){var{mimeType:o,quality:n}=i,a=e(i,["mimeType","quality"]);const s=await t._toCanvas(Object.assign({mimeType:o},a)),r=await new Promise(e=>{s.toBlob(e,o,n)});return p.Util.releaseCanvas(s),r},async saveAsImage(i={}){var{fileName:o}=i,n=e(i,["fileName"]);const a=n.mimeType||"image/png",s=a.split("/")[1];m(await t.toDataURL(n),o||"polotno."+s,a)},async _toPDF(e){const i=e.dpi||t.dpi,o=e.parallel||1,n=e.unit||("px"===t.unit?"mm":t.unit),a=e.pixelRatio||1,s=e.pageIds||t.pages.map(e=>e.id),r=t.pages.filter(e=>s.includes(e.id)),l=await u(),d=e=>w({px:e,unit:n,dpi:i}),c=e.cropMarkSize||0,p=d(c),g=r[0]||{},m=e.includeBleed?g.bleed:0,f=d(g.computedWidth+2*m+2*p),h=d(g.computedHeight+2*m+2*p);var y=new l({unit:n,orientation:f>h?"landscape":"portrait",format:[f,h],compress:!0,putOnlyUsedFonts:!0});y.deletePage(1);const b=((e,t)=>{for(var i=[],o=0;o<e.length;o+=t){i.push(e.slice(o,o+t))}return i})(r,o);let v=0;for(const u of b){const i=u.map(async i=>{const o=e.includeBleed?i.bleed:0,n=i.computedWidth+2*o+2*c,r=i.computedHeight+2*o+2*c,l=d(n),p=d(r);let g=0,m=a;for(;g<10;){g+=1,2===g&&console.error("Polotno can not export PDF with current settings. Quality is automatically reduced.");const o=await t.toDataURL(Object.assign(Object.assign({},e),{pageId:i.id,pixelRatio:m}));if(o.length>20){return e.onProgress&&e.onProgress(++v/s.length*.9),{url:o,width:l,height:p,widthPx:n,heightPx:r}}m*=.8}});(await Promise.all(i)).forEach(({url:e,width:t,height:i,widthPx:o,heightPx:a})=>{y.addPage([t,i],t>i?"landscape":"portrait");const s=y.getCurrentPageInfo();var r;switch(n){case"pt":r=1;break;case"mm":r=72/25.4;break;case"cm":r=72/2.54;break;case"in":r=72;break;case"px":r=.75;break;case"pc":case"em":r=12;break;case"ex":r=6;break;default:throw"Invalid unit: "+n}if(s.pageContext.cropBox={bottomLeftX:0,bottomLeftY:0,topRightX:t*r,topRightY:i*r},s.pageContext.artBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(o-c-m)*r,topRightY:d(a-c-m)*r},s.pageContext.bleedBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(o-c-m)*r,topRightY:d(a-c-m)*r},p){y.setLineWidth(d(1));const e=p+d(m);y.line(e,0,e,p),y.line(0,e,p,e),y.line(t-e,0,t-e,p),y.line(t,e,t-p,e),y.line(0,i-e,p,i-e),y.line(e,i,e,i-p),y.line(t,i-e,t-p,i-e),y.line(t-e,i,t-e,i-p)}y.addImage(e,p,p,t-2*p,i-2*p,void 0,"FAST")})}return y},toPDFDataURL:async e=>(await t._toPDF(Object.assign({mimeType:"image/jpeg"},e))).output("datauristring"),async toGIFDataURL(e={}){const i=e.pixelRatio||1,o=await f({width:t.width*i,height:t.height*i}),n=1e3/(e.fps||10),a=t.duration/n;for(let s=0;s<a-1;s++){const e=s*n||1;t.setCurrentTime(e);let a=0,r="";for(const i of t.pages){if(a+=i.duration,i.set({_rendering:a>e}),a>e){r=i.id;break}}const l=await t._toCanvas({pixelRatio:i,pageId:r,_skipTimeout:!0});o.addFrame(l.getContext("2d"),{delay:n,copy:!0})}for(const s of t.pages){s.set({_rendering:!1})}return t.stop(),o.render(),new Promise(e=>{o.on("finished",function(t){!function(e,t){var i=new FileReader;i.onload=function(e){t(e.target.result)},i.readAsDataURL(e)}(t,e)})})},async saveAsGIF(i={}){var{fileName:o}=i,n=e(i,["fileName"]);const a=await t.toGIFDataURL(n);m(a,o||"polotno.gif")},async toHTML({elementHook:e}={elementHook:void 0}){const i=t.toJSON();return x({json:i,elementHook:e})},async saveAsHTML({fileName:e}={}){const i=await t.toHTML(),o="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));m(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:i,fontEmbedding:o="inline"}={elementHook:void 0,pageId:void 0,fontEmbedding:"inline"}){var n;const a=t.toJSON();i=i||(null===(n=a.pages[0])||void 0===n?void 0:n.id);const s=a.pages.find(e=>e.id===i);return _({json:Object.assign(Object.assign({},a),{pages:s?[s]:[]}),elementHook:e,fontEmbedding:o})},async saveAsSVG({fileName:e,elementHook:i,pageId:o,fontEmbedding:n="inline"}={}){const a=await t.toSVG({elementHook:i,pageId:o,fontEmbedding:n}),s="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(a)));m(s,e||"polotno.svg")},async saveAsPDF(i={}){var{fileName:o}=i,n=e(i,["fileName"]);(await t._toPDF(Object.assign({mimeType:"image/jpeg"},n))).save(o||"polotno.pdf")},async waitLoading({_skipTimeout:e=!1}={}){e||await new Promise(e=>setTimeout(e,50)),await v()},toJSON:()=>({width:t.width,height:t.height,fonts:a(t.fonts),pages:a(t.pages),audios:a(t.audios),unit:t.unit,dpi:t.dpi,custom:t.custom,schemaVersion:t.schemaVersion}),loadJSON(e,i=!1){var n;const s=JSON.parse(JSON.stringify(e)),r=s.schemaVersion||0;r<1&&b.htmlRenderEnabled&&k({children:s.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),r<2&&k({children:s.pages},e=>{e.filters&&Object.keys(e.filters).forEach(t=>{if(["warm","cold","natural"].includes(t)){return}const i=e.filters[t];i&&"number"==typeof i.intensity&&(i.intensity=i.intensity/100)})}),delete s.schemaVersion;const l=t.pages.indexOf(t.activePage);let d=null===(n=s.pages[l]||s.pages[0])||void 0===n?void 0:n.id;s._activePageId=d;const c=Object.assign({},a(t));Object.assign(c,s),c.history=i?t.history.toJSON():{history:[],undoIdx:-1},o(t,c)},clear({keepHistory:e=!1}={}){const i=t.pages.map(e=>e.id);t.deletePages(i),t.custom=null,e||t.history.clear()},addFont(e){t.removeFont(e.fontFamily),t.fonts.push(e),t.loadFont(e.fontFamily)},removeFont(e){t.fonts.filter(t=>t.fontFamily===e).forEach(e=>r(e))},addAudio(e){const i=S.create(Object.assign({id:c(10)},e));t.audios.push(i)},removeAudio(e){const i=t.audios.find(t=>t.id===e);i&&t.audios.remove(i)},async loadFont(e){const i=t.fonts.find(t=>t.fontFamily===e)||y.globalFonts.find(t=>t.fontFamily===e);let o=[{fontStyle:"normal",fontWeight:"normal"},{fontStyle:"normal",fontWeight:"bold"}];return i?(i.styles&&(o=i.styles.map(e=>({fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"normal"}))),y.injectCustomFont(i)):y.injectGoogleFont(e),Promise.all(o.map(t=>y.loadFont(e,t.fontStyle,t.fontWeight)))},validate:e=>Store.validate(e,[{path:"",type:Store}]).map(e=>({path:"store"+e.context.map(e=>e.path).join("."),message:e.message}))}));export function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){return Store.create({_forceShowCredit:t,_key:e})}export default createStore;
1
+ var e=this&&this.__rest||function(e,t){var i={};for(var o in e){Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(i[o]=e[o])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++){t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(i[o[n]]=e[o[n]])}}return i};import{types as t,onSnapshot as i,applySnapshot as o,detach as n,getSnapshot as a,cast as s,destroy as r,setLivelinessChecking as l}from"mobx-state-tree";import{UndoManager as d}from"./history.js";import{nanoid as c}from"nanoid";import p from"konva";import{computed as g}from"mobx";import{downloadFile as m}from"../utils/download.js";import{getJsPDF as u}from"../utils/pdf.js";import{createGIF as f}from"../utils/gif-lib.js";import{validateKey as h}from"../utils/validate-key.js";import*as y from"../utils/fonts.js";import{flags as b}from"../utils/flags.js";import{whenLoaded as v}from"../utils/loader.js";import{pxToUnit as w}from"../utils/unit.js";import{deepEqual as P}from"../utils/deep-equal.js";import{waitTillAvailable as E}from"../utils/wait.js";import{jsonToHTML as x}from"../utils/to-html.js";import{jsonToSVG as _}from"../utils/to-svg.js";import{Page as I}from"./page-model.js";import{forEveryChild as k}from"./group-model.js";import{Audio as S}from"./audio-model.js";l("ignore");export const Font=t.model("Font",{fontFamily:t.string,url:t.optional(t.string,""),styles:t.frozen()}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}));export const Store=t.model("Store",{role:"",pages:t.array(I),fonts:t.array(Font),audios:t.array(S),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:"px",dpi:72,schemaVersion:2,bleedVisible:!1,rulesVisible:!1,openedSidePanel:"",previousOpenedSidePanel:"",custom:t.frozen(),selectedElementsIds:t.array(t.string),animatedElementsIds:t.array(t.string),history:t.optional(d,{targetPath:"../pages"}),_elementsPixelRatio:Math.min(2,"undefined"!=typeof window&&window.devicePixelRatio||1),_activePageId:"",_selectedPagesIds:t.array(t.string),_forceShowCredit:!1,_key:"",_validated:!1}).views(e=>{const t=g(()=>{const t={};return k({children:e.pages},e=>(t[e.id]=e,!1)),t},{keepAlive:!0});return{get _idsMap(){return t.get()}}}).views(e=>({get _bleedVisible(){return console.warn("store._bleedVisible is deprecated. Please use store.bleedVisible instead."),e.bleedVisible},get selectedElements(){return e.selectedElementsIds.map(t=>{for(const i of e.pages){for(const e of i.children){if(e.id===t){return e}}}}).filter(e=>!!e)},get children(){return e.pages},get selectedShapes(){const t=[];return k({children:e.selectedElements},e=>{"group"!==e.type&&t.push(e)}),t},get activePage(){return e.pages.slice().find(t=>t.id===e._activePageId)||(e.pages.length?e.pages[0]:null)},get selectedPages(){return e._selectedPagesIds.map(t=>e.pages.find(e=>e.id===t))},get duration(){let t=0;return e.pages.forEach(e=>{t+=e.duration}),t},get _hasCroppedImages(){return e.find(e=>"image"===e.type&&e._cropModeEnabled)},find(t){let i;return k({children:e.pages},e=>{if(!i&&t(e)){return i=e,!0}}),i},getElementById:t=>e._idsMap[t]})).actions(e=>{let t=0,i=null,o=!1;return{afterCreate(){e.history.canUndo},setCurrentTime(t){e.currentTime=t},_togglePlaying(t=!e.isPlaying){e.isPlaying=t},play({animatedElementsIds:n=[],startTime:a=0,currentTime:r=0,endTime:l=e.duration,repeat:d=!1}={}){r&&(console.warn("currentTime property of store.play() is deprecated. Please use startTime instead."),a=r),e.animatedElementsIds=s(n),e.currentTime=a,e.isPlaying=!0,t=Date.now(),i=l,o=d,requestAnimationFrame(e.seek)},checkActivePage(){let t=0;for(const i of e.pages){if(e.currentTime>=i.startTime&&e.currentTime<i.startTime+i.duration){e.selectPage(i.id);break}t+=i.duration}},seek(){if(!e.isPlaying){return}const n=Date.now(),a=n-t;t=n,e.currentTime+=a,e.checkActivePage();const s=i||e.duration;e.isPlaying&&e.currentTime<s?requestAnimationFrame(e.seek):e.isPlaying&&o?(e.currentTime=0,requestAnimationFrame(e.seek)):e.stop()},stop(){e.isPlaying=!1,e.currentTime=0,e.animatedElementsIds=s([]),e.checkActivePage()}}}).actions(t=>({__(){t._validated||(h(t._key,t._forceShowCredit),t._validated=!0)},set(e){Object.assign(t,e)},setUnit({unit:e,dpi:i}){t.unit=e||t.unit,t.dpi=i||t.dpi},setRole(e){t.role=e},addPage(e){const i=I.create(Object.assign({id:c(10)},e));return t.pages.push(i),t._activePageId=i.id,i},selectPage(e){t._activePageId=e,1===t._selectedPagesIds.length&&(t._selectedPagesIds=s([e]))},selectPages(e){t._selectedPagesIds=s(e),1===t._selectedPagesIds.length&&(t._activePageId=t._selectedPagesIds[0])},selectElements(e){const i=e.map(e=>t.getElementById(e)).sort((e,t)=>e.page.children.indexOf(e)-e.page.children.indexOf(t)).filter(e=>!!e).map(e=>e.id);t.selectedElementsIds=s(i)},toggleBleed(e){t.bleedVisible=null!=e?e:!t.bleedVisible},toggleRulers(e){t.rulesVisible=null!=e?e:!t.rulesVisible},openSidePanel(e){t.openedSidePanel!==e&&(t.previousOpenedSidePanel=t.openedSidePanel,t.openedSidePanel=e)},setScale(e){t.scale=e},_setScaleToFit(e){t.scaleToFit=e},setElementsPixelRatio(e){t._elementsPixelRatio=e},setSize(e,i,o){t.pages.forEach(t=>{t.setSize({width:e,height:i,useMagic:o,softChange:!0})}),t.width=e,t.height=i},setPageZIndex(e,i){const o=t.pages.find(t=>t.id===e);o&&(n(o),t.pages.remove(o),t.pages.splice(i,0,o))},deletePages(e){const i=t.pages.indexOf(t.activePage);e.forEach(e=>{const i=t.pages.find(t=>t.id===e);r(i)});const o=Math.min(t.pages.length-1,i),n=t.pages[o];n&&(t._activePageId=n.id),t.selectedElementsIds=s(t.selectedElementsIds.filter(e=>t.getElementById(e)))},groupElements(e,i={}){const o=e.map(e=>t.getElementById(e)),a=o[0].page;if(o.forEach(e=>{e&&n(e)}),!o.length){return}const r=Object.assign({id:c(10),children:o,type:"group"},i);return a.children.push(r),t.selectedElementsIds=s([r.id]),a.children.find(e=>e.id===r.id)},ungroupElements(e){const i=e.map(e=>t.getElementById(e)),o=[];i.forEach(e=>{if(e&&"group"===e.type){const t=e.page,i=t.children.indexOf(e);e.children.forEach(e=>{o.push(e.id)}),e.children.forEach(e=>{n(e),t.children.push(e)}),t.children.splice(i,1)}}),t.selectedElementsIds=s(o)},deleteElements(e){const i=[];t.find(t=>(e.includes(t.id)&&i.push(t),!1)),i.forEach(e=>{r(e)}),t.selectedElementsIds=s(t.selectedElementsIds.filter(e=>t.getElementById(e)))},on(e,o){if("change"===e){let e=t.toJSON();return i(t,i=>{const n=t.toJSON();!P(e,n)&&(e=n,o(n))})}},async _toCanvas({pixelRatio:e,ignoreBackground:i,pageId:o,mimeType:n,includeBleed:a,_skipTimeout:s,quickMode:r=!1}={}){var l;const d=e||1;o=o||(null===(l=t.pages[0])||void 0===l?void 0:l.id);const c=t.pages.find(e=>e.id===o);if(!c){throw new Error(`No page for export with id ${o}`)}const g=t._elementsPixelRatio;d>t._elementsPixelRatio&&t.setElementsPixelRatio(d),r?null==c||c.set({_forceMount:!0}):null==c||c.set({_exporting:!0});const m=await E(()=>{const e=p.stages.filter(e=>e.getAttr("pageId")===o);return 0===e.length?null:e});if(!m){throw null==c||c.set({_forceMount:!1,_exporting:!1}),t.setElementsPixelRatio(g),new Error(`Export is failed. Can not find stage for page ${o}. Looks like <Workspace /> component is not mounted, but it is required in order to process the export.`)}m.length>1&&console.error(`Polotno error: Detected several canvas elements for page "${o}" in the document. This is not supported and will lead to incorrect export. Make sure to use unique ids for all pages and make sure you unmount <Workspace /> when it is not needed.`);const u=m[0];await t.waitLoading({_skipTimeout:s});const f=u.findOne(".page-container");if(!f){throw t.setElementsPixelRatio(g),null==c||c.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const h=u.position();u.position({x:0,y:0}),u.find("Transformer").forEach(e=>{e.setAttr("oldVisible",e.visible()),e.visible(!1)}),f.find(".page-background").forEach(e=>e.shadowEnabled(!1)),f.find(".page-background").forEach(e=>e.strokeEnabled(!1)),f.find(".highlighter").forEach(e=>e.visible(!1));const y=f.findOne(".page-background-group"),b=y.clip();y.clip({x:null,y:null,width:null,height:null});const v=f.findOne(".elements-container"),w=v.clip();v.clip({x:null,y:null,width:null,height:null});const P=f.find(e=>!e.visible()&&e.getAttr("editModeEnabled")&&!e.getAttr("hideInExport"));P.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()});const x=f.find(e=>e.getAttr("hideInExport"));x.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()}),i&&f.find(".page-background").forEach(e=>e.hide());const _=a?c.bleed:0;let I=_;!t.bleedVisible&&a||(t.bleedVisible||a?t.bleedVisible&&a?I=0:t.bleedVisible&&!a&&(I=-c.bleed):I=0);const k=document.createElement("canvas");k.width=Math.round((c.computedWidth+2*_)*d),k.height=Math.round((c.computedHeight+2*_)*d);const S=k.getContext("2d");"image/jpeg"===n&&(S.fillStyle="white",S.fillRect(0,0,k.width,k.height));const O=f.scale();f.scale({x:1,y:1});const j=f.toCanvas({x:f.x()-I,y:f.y()-I,width:c.computedWidth+2*_,height:c.computedHeight+2*_,pixelRatio:d});return f.scale(O),S.drawImage(j,0,0,k.width,k.height),p.Util.releaseCanvas(j),i&&f.find(".page-background").forEach(e=>e.show()),x.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),P.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),f.find(".page-background").forEach(e=>e.shadowEnabled(!0)),f.find(".page-background").forEach(e=>e.strokeEnabled(!0)),u.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),f.find(".highlighter").forEach(e=>e.visible(!0)),y.clip(b),v.clip(w),u.position(h),null==c||c.set({_exporting:!1,_forceMount:!1}),await new Promise(e=>setTimeout(e)),t.setElementsPixelRatio(g),k},async toDataURL(i={}){var{mimeType:o,quality:n}=i,a=e(i,["mimeType","quality"]);const s=await t._toCanvas(Object.assign({mimeType:o},a)),r=s.toDataURL(o,n);return p.Util.releaseCanvas(s),r},async toBlob(i={}){var{mimeType:o,quality:n}=i,a=e(i,["mimeType","quality"]);const s=await t._toCanvas(Object.assign({mimeType:o},a)),r=await new Promise(e=>{s.toBlob(e,o,n)});return p.Util.releaseCanvas(s),r},async saveAsImage(i={}){var{fileName:o}=i,n=e(i,["fileName"]);const a=n.mimeType||"image/png",s=a.split("/")[1];m(await t.toDataURL(n),o||"polotno."+s,a)},async _toPDF(e){const i=e.dpi||t.dpi,o=e.parallel||1,n=e.unit||("px"===t.unit?"mm":t.unit),a=e.pixelRatio||1,s=e.pageIds||t.pages.map(e=>e.id),r=t.pages.filter(e=>s.includes(e.id)),l=await u(),d=e=>w({px:e,unit:n,dpi:i}),c=e.cropMarkSize||0,p=d(c),g=r[0]||{},m=e.includeBleed?g.bleed:0,f=d(g.computedWidth+2*m+2*p),h=d(g.computedHeight+2*m+2*p);var y=new l({unit:n,orientation:f>h?"landscape":"portrait",format:[f,h],compress:!0,putOnlyUsedFonts:!0});y.deletePage(1);const b=((e,t)=>{for(var i=[],o=0;o<e.length;o+=t){i.push(e.slice(o,o+t))}return i})(r,o);let v=0;for(const u of b){const i=u.map(async i=>{const o=e.includeBleed?i.bleed:0,n=i.computedWidth+2*o+2*c,r=i.computedHeight+2*o+2*c,l=d(n),p=d(r);let g=0,m=a;for(;g<10;){g+=1,2===g&&console.error("Polotno can not export PDF with current settings. Quality is automatically reduced.");const o=await t.toDataURL(Object.assign(Object.assign({},e),{pageId:i.id,pixelRatio:m}));if(o.length>20){return e.onProgress&&e.onProgress(++v/s.length*.9),{url:o,width:l,height:p,widthPx:n,heightPx:r}}m*=.8}});(await Promise.all(i)).forEach(({url:e,width:t,height:i,widthPx:o,heightPx:a})=>{y.addPage([t,i],t>i?"landscape":"portrait");const s=y.getCurrentPageInfo();var r;switch(n){case"pt":r=1;break;case"mm":r=72/25.4;break;case"cm":r=72/2.54;break;case"in":r=72;break;case"px":r=.75;break;case"pc":case"em":r=12;break;case"ex":r=6;break;default:throw"Invalid unit: "+n}if(s.pageContext.cropBox={bottomLeftX:0,bottomLeftY:0,topRightX:t*r,topRightY:i*r},s.pageContext.artBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(o-c-m)*r,topRightY:d(a-c-m)*r},s.pageContext.bleedBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(o-c-m)*r,topRightY:d(a-c-m)*r},p){y.setLineWidth(d(1));const e=p+d(m);y.line(e,0,e,p),y.line(0,e,p,e),y.line(t-e,0,t-e,p),y.line(t,e,t-p,e),y.line(0,i-e,p,i-e),y.line(e,i,e,i-p),y.line(t,i-e,t-p,i-e),y.line(t-e,i,t-e,i-p)}y.addImage(e,p,p,t-2*p,i-2*p,void 0,"FAST")})}return y},toPDFDataURL:async e=>(await t._toPDF(Object.assign({mimeType:"image/jpeg"},e))).output("datauristring"),async toGIFDataURL(e={}){const i=e.pixelRatio||1,o=await f({width:t.width*i,height:t.height*i}),n=1e3/(e.fps||10),a=t.duration/n;for(let s=0;s<a-1;s++){const e=s*n||1;t.setCurrentTime(e);let a=0,r="";for(const i of t.pages){if(a+=i.duration,i.set({_rendering:a>e}),a>e){r=i.id;break}}const l=await t._toCanvas({pixelRatio:i,pageId:r,_skipTimeout:!0});o.addFrame(l.getContext("2d"),{delay:n,copy:!0})}for(const s of t.pages){s.set({_rendering:!1})}return t.stop(),o.render(),new Promise(e=>{o.on("finished",function(t){!function(e,t){var i=new FileReader;i.onload=function(e){t(e.target.result)},i.readAsDataURL(e)}(t,e)})})},async saveAsGIF(i={}){var{fileName:o}=i,n=e(i,["fileName"]);const a=await t.toGIFDataURL(n);m(a,o||"polotno.gif")},async toHTML({elementHook:e}={elementHook:void 0}){const i=t.toJSON();return x({json:i,elementHook:e})},async saveAsHTML({fileName:e}={}){const i=await t.toHTML(),o="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));m(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:i,fontEmbedding:o="inline"}={elementHook:void 0,pageId:void 0,fontEmbedding:"inline"}){var n;const a=t.toJSON();i=i||(null===(n=a.pages[0])||void 0===n?void 0:n.id);const s=a.pages.find(e=>e.id===i);return _({json:Object.assign(Object.assign({},a),{pages:s?[s]:[]}),elementHook:e,fontEmbedding:o})},async saveAsSVG({fileName:e,elementHook:i,pageId:o,fontEmbedding:n="inline"}={}){const a=await t.toSVG({elementHook:i,pageId:o,fontEmbedding:n}),s="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(a)));m(s,e||"polotno.svg")},async saveAsPDF(i={}){var{fileName:o}=i,n=e(i,["fileName"]);(await t._toPDF(Object.assign({mimeType:"image/jpeg"},n))).save(o||"polotno.pdf")},async waitLoading({_skipTimeout:e=!1}={}){e||await new Promise(e=>setTimeout(e,50)),await v()},toJSON:()=>({width:t.width,height:t.height,fonts:a(t.fonts),pages:a(t.pages),audios:a(t.audios),unit:t.unit,dpi:t.dpi,custom:t.custom,schemaVersion:t.schemaVersion}),loadJSON(e,i=!1){var n;const s=JSON.parse(JSON.stringify(e)),r=s.schemaVersion||0;r<1&&b.htmlRenderEnabled&&k({children:s.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),r<2&&k({children:s.pages},e=>{e.filters&&Object.keys(e.filters).forEach(t=>{if(["warm","cold","natural"].includes(t)){return}const i=e.filters[t];i&&"number"==typeof i.intensity&&(i.intensity=i.intensity/100)})}),delete s.schemaVersion;const l=t.pages.indexOf(t.activePage);let d=null===(n=s.pages[l]||s.pages[0])||void 0===n?void 0:n.id;s._activePageId=d;const c=Object.assign({},a(t));Object.assign(c,s),c.history=i?t.history.toJSON():{history:[],undoIdx:-1},o(t,c)},clear({keepHistory:e=!1}={}){const i=t.pages.map(e=>e.id);t.deletePages(i),t.custom=null,e||t.history.clear()},addFont(e){t.removeFont(e.fontFamily),t.fonts.push(e),t.loadFont(e.fontFamily)},removeFont(e){t.fonts.filter(t=>t.fontFamily===e).forEach(e=>r(e))},addAudio(e){const i=S.create(Object.assign({id:c(10)},e));t.audios.push(i)},removeAudio(e){const i=t.audios.find(t=>t.id===e);i&&t.audios.remove(i)},async loadFont(e){const i=t.fonts.find(t=>t.fontFamily===e)||y.globalFonts.find(t=>t.fontFamily===e);let o=[{fontStyle:"normal",fontWeight:"normal"},{fontStyle:"normal",fontWeight:"bold"}];return i?(i.styles&&(o=i.styles.map(e=>({fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"normal"}))),y.injectCustomFont(i)):y.injectGoogleFont(e),Promise.all(o.map(t=>y.loadFont(e,t.fontStyle,t.fontWeight)))},validate:e=>Store.validate(e,[{path:"",type:Store}]).map(e=>({path:"store"+e.context.map(e=>e.path).join("."),message:e.message}))}));export function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){return Store.create({_forceShowCredit:t,_key:e})}export default createStore;
@@ -65,7 +65,6 @@ export declare const VideoElement: import("mobx-state-tree").IModelType<{
65
65
  borderSize: import("mobx-state-tree").IType<number, number, number>;
66
66
  keepRatio: import("mobx-state-tree").IType<boolean, boolean, boolean>;
67
67
  stretchEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
68
- _cropModeEnabled: import("mobx-state-tree").IType<boolean, boolean, boolean>;
69
68
  } & {
70
69
  type: import("mobx-state-tree").IType<string, string, string>;
71
70
  duration: import("mobx-state-tree").IType<number, number, number>;
@@ -143,6 +142,8 @@ export declare const VideoElement: import("mobx-state-tree").IModelType<{
143
142
  } & {
144
143
  toggleCropMode(flag?: boolean): void;
145
144
  beforeDestroy(): void;
145
+ } & {
146
+ readonly _cropModeEnabled: boolean;
146
147
  }, import("mobx-state-tree").ModelCreationType<{
147
148
  id: string;
148
149
  type: string;