polotno 2.25.9 → 2.25.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/canvas/html-element.js +3 -3
- package/canvas/text-element.js +1 -1
- package/model/store.js +1 -1
- package/package.json +1 -1
- package/polotno.bundle.js +105 -105
- package/utils/to-html.js +1 -1
- package/utils/to-pptx.js +1 -1
- package/utils/to-svg.js +1 -1
- package/utils/validate-key.js +1 -1
package/canvas/html-element.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import t from"react";import{observer as e}from"mobx-react-lite";import{
|
|
1
|
+
import t from"react";import{observer as e}from"mobx-react-lite";import{Group as o,Image as n,Rect as i}from"react-konva";import r from"quill";import*as a from"mobx";import{reaction as l}from"mobx";import{flags as s}from"../utils/flags.js";import{applyFilter as c}from"./apply-filters.js";import{getDir as d,getLineHeight as f,useFontLoader as u,usePrevious as h}from"./text-element.js";import{useColor as g}from"./use-color.js";import{detectSize as m,htmlToCanvas as p,isContentWrapping as x}from"../utils/html2canvas.js";import{resetStyleContent as b}from"../utils/reset-style.js";import{useFadeIn as y}from"./use-fadein.js";import{Html as w}from"react-konva-utils";import v from"../utils/styled.js";import{incrementLoader as E,triggerLoadError as k}from"../utils/loader.js";import{removeTags as S,sanitizeHtml as z}from"../utils/text.js";import*as F from"../utils/fonts.js";import{isTouchDevice as R}from"../utils/screen.js";import{getLimitedFontSize as O}from"./text-element/max-font-size.js";import{useDelayer as C}from"./use-delayer.js";function $(t){const e=(t||"").trim();if("<p><br></p>"===e||"<p></p>"===e){return""}if(e.startsWith("<p>")&&e.endsWith("</p>")){const t=e.slice(3,-4);if(!/(<\/?(p|div|h[1-6]|ul|ol|li|table|thead|tbody|tr|td|blockquote)\b)/i.test(t)){return t}}return t}export const quillRef=a.observable({enabled:!1,currentFormat:{},editor:a.observable.object({instance:null},{},{deep:!1})});const j=v("div",t.forwardRef)`
|
|
2
2
|
.ql-editor {
|
|
3
3
|
outline: none;
|
|
4
4
|
}
|
|
5
5
|
.ql-clipboard {
|
|
6
6
|
pointer-events: none;
|
|
7
7
|
}
|
|
8
|
-
${
|
|
8
|
+
${b}
|
|
9
9
|
strong {
|
|
10
10
|
font-weight: 700;
|
|
11
11
|
}
|
|
12
12
|
.ql-direction-rtl {
|
|
13
13
|
direction: rtl;
|
|
14
14
|
}
|
|
15
|
-
`;let j=["bold","color","font","italic","size","strike","underline","indent","list","direction"];export const setQuillFormats=t=>{j=t};export const createQuill=t=>new r(t,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:j});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 T=({html:e,onBlur:o,onChange:n,element:i,clickCoords:l})=>{const s=t.useRef(null);t.useEffect(()=>{if(!s.current){return}const t=(i=s.current,new r(i,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:j}));var i;return a.runInAction(()=>{quillRef.editor.instance=t}),window.__polotnoQuill=t,t.on("text-change",()=>{t.getSelection()&&a.runInAction(()=>{quillRef.currentFormat=t.getFormat()}),setTimeout(()=>{var t;const e=null===(t=s.current)||void 0===t?void 0:t.childNodes[0];n(e.innerHTML)},10)}),setQuillContent(t,e),l?setCursorFromCoords(t,l):t.setSelection(0,0,"api"),t.on("selection-change",(e,o,n)=>{e&&a.runInAction(()=>{quillRef.currentFormat=t.getFormat()})}),s.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()}),()=>{a.runInAction(()=>{quillRef.editor.instance=null,quillRef.currentFormat={}}),delete window.__polotnoQuill}},[]),t.useEffect(()=>O(()=>i.text,()=>{var t;const o=quillRef.editor.instance;if(!o){return}const n=o.getSelection();(null===(t=s.current)||void 0===t?void 0:t.childNodes[0].innerHTML)===i.text||(setQuillContent(o,e),n&&(o.setSelection(n.index,n.length),a.runInAction(()=>{quillRef.currentFormat=o.getFormat()})))},{fireImmediately:!0}),[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=s.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 c={color:i.fill};return i.fill.indexOf("gradient")>=0&&(c.backgroundColor=i.fill,c.backgroundImage=i.fill,c.backgroundSize="100% 100%",c.backgroundRepeat="repeat",c.webkitBackgroundClip="text",c.MozBackgroundClip="text",c.WebkitTextFillColor="transparent",c.MozTextFillColor="transparent"),t.createElement($,{ref:s,style:Object.assign(Object.assign({},c),{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)}),dir:d(S(i.text))})};function M(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 A(t,{fontFamily:e="",color:o="black"}={}){let n=`color: ${o||t.fill}`;return 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 `),`<div style="${["white-space: pre-wrap",`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("; ")}" contentEditable dir="${d(S(t.text))}">${k(t.text).replace(/\n/g,"</br>")}</div>`}const I=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);export const HTMLElement=e(({element:e,store:r})=>{const d=t.useRef(null),[x,b]=t.useState(),[k,O]=t.useState(!1),[j,X]=t.useState(!1),Y=t.useRef(e.height),q=r.selectedShapes.indexOf(e)>=0&&e.selectable,P=e.fontSize/3,{textVerticalResizeEnabled:H}=l,L=u(e.fontFamily),[W]=c(r,e.fontFamily),_=e._editModeEnabled;y(d);const B=W?e.fontFamily:L!==e.fontFamily?L:"Arial",D=h(e).fill,N=A(e,{fontFamily:B,color:D}),{width:Q,height:V}=function(e,o,n){return t.useMemo(()=>m(e),[e,o.width,n])}(N,e,W);t.useEffect(()=>{if(!W){return}if(!e.height){return void e.set({height:V})}const{textOverflow:t}=l;if("change-font-size"!==t||k){"resize"===t&&(H&&e.height<V&&r.history.ignore(()=>{e.set({height:V})}),H||e.height===V||r.history.ignore(()=>{e.set({height:V})}))}else{const t=(t=>{let e=t.fontSize;for(let o=1;o<50;o++){const o=A(Object.assign(Object.assign({},t.toJSON()),{fontSize:e}),{fontFamily:t.fontFamily}),{height:n}=m(o),i=t.height&&n>t.height,r=p({html:o});if(!i&&!r){break}e-=.5}return e})(e);t!==e.fontSize?r.history.ignore(()=>{e.set({fontSize:t})}):e.height!==V&&(H&&e.height<V?r.history.ignore(()=>{e.set({height:V})}):H||r.history.ignore(()=>{e.set({height:V})}))}});const J=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 g(e),t.lastArgs=Object.assign({},e)),t.lastResult;var o,n}},[]),G=t.useRef(0),K=t.useRef(null);t.useEffect(()=>{k||_||(async()=>{G.current++;const t=G.current;let o=v(`text ${e.id} ${t}`);K.current&&K.current(),K.current=o,X(!0);let n=null;const i=I?5:1;for(let l=0;l<i;l++){const o=l>0?J:g;try{if(n=await o({skipCache:l>0,html:N,width:e.width||1,height:e.height||V||1,fontFamily:B,padding:P,pixelRatio:r._elementsPixelRatio,font:r.fonts.find(t=>t.fontFamily===B)||z.globalFonts.find(t=>t.fontFamily===B)}),t!==G.current){return}if(I&&M(n)){await new Promise(t=>setTimeout(t,50*(l+1)));continue}break}catch(a){console.error(a),E(`Error rendering rich text with id ${e.id}`);break}}n?b(n):o?(o(),o=null):console.error("Finish function is called twice!"),X(!1)})()},[N,k,V,_,B,e.height,r._elementsPixelRatio,W]);const[U,Z]=C(j,300),[tt]=C(k,300,!0),et=tt||U;t.useEffect(()=>{if(!et){return a.autorun(()=>{const t=d.current;s(t,e)})}},[x,et,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]),t.useEffect(()=>{x&&!j&&K.current&&(K.current(),K.current=null)},[x,j]),t.useEffect(()=>()=>{K.current&&K.current()},[]);let ot=0;"middle"===e.verticalAlign&&(ot=(e.height-V)/2),"bottom"===e.verticalAlign&&(ot=e.height-V);const nt=f({fontLoaded:W,fontFamily:e.fontFamily,fontSize:e.fontSize,lineHeight:e.lineHeight}),it=F(),rt=t.useRef(null),at=t.useRef(null),lt=_&&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*nt*.5),offsetY:e.backgroundPadding*(e.fontSize*nt*.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*nt),height:e.a.height+e.backgroundPadding*(e.fontSize*nt),cornerRadius:e.backgroundCornerRadius*(e.fontSize*nt*.5)}),t.createElement(i,{ref:d,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:!et,draggable:it?e.draggable&&q:e.draggable,preventDefault:!it||q,opacity:_?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&&(at.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];at.current=n?{x:n.clientX,y:n.clientY}:null,e.toggleEditMode(!0)}},onTransformStart:t=>{O(!0),Y.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,s=n.scaleX();if(r){const t=n.scaleX(),o=n.width()*t,i=e.fontSize;let r=o;if(o<i&&(r=i,rt.current&&n.position(rt.current)),n.width(r),n.scaleX(1),l.textVerticalResizeEnabled){const t=Math.max(V,Y.current);e.set({height:t})}e.set({width:n.width(),x:n.x(),y:n.y()})}else if(a){let o="resize"===l.textOverflow?V: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*s,letterSpacing:e.letterSpacing,width:n.width()*s,x:n.x(),y:n.y(),rotation:n.rotation(),height:n.height()*s})}rt.current=t.target.position()},onTransformEnd:t=>{O(!1),X(!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:d,image:x,x:e.a.x,y:e.a.y,offsetX:P,offsetY:P-ot,listening:!1,rotation:e.a.rotation,width:e.a.width+2*P,height:(e.a.width+2*P)*((null==x?void 0:x.height)/(null==x?void 0:x.width)||1),visible:!et&&!_,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}),(et||lt)&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-ot},t.createElement(w,{divProps:{style:{pointerEvents:"none"}}},t.createElement($,{dangerouslySetInnerHTML:{__html:N},style:{pointerEvents:"none",opacity:e.a.opacity}}))),_&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-ot},t.createElement(w,null,t.createElement(T,{html:N,element:e,onChange:t=>{const o=R({oldText:S(e.text),newText:S(t),element:e});e.set({text:t,fontSize:o})},onBlur:t=>{e.toggleEditMode(!1),Z(!0),""===S(e.text)&&e.removable&&!e.placeholder&&r.deleteElements([e.id])},clickCoords:at.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=r.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 T=["bold","color","font","italic","size","strike","underline","indent","list","direction"];export const setQuillFormats=t=>{T=t};export const createQuill=t=>new r(t,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:T});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 M=({html:e,onBlur:o,onChange:n,element:i,clickCoords:s})=>{const c=t.useRef(null);t.useEffect(()=>{if(!c.current){return}const t=(i=c.current,new r(i,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:T}));var i;return a.runInAction(()=>{quillRef.editor.instance=t}),window.__polotnoQuill=t,t.on("text-change",()=>{t.getSelection()&&a.runInAction(()=>{quillRef.currentFormat=t.getFormat()}),setTimeout(()=>{var t;const e=(null===(t=c.current)||void 0===t?void 0:t.childNodes[0]).innerHTML;n($(e))},10)}),setQuillContent(t,e),s?setCursorFromCoords(t,s):t.setSelection(0,0,"api"),t.on("selection-change",(e,o,n)=>{e&&a.runInAction(()=>{quillRef.currentFormat=t.getFormat()})}),c.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()}),()=>{a.runInAction(()=>{quillRef.editor.instance=null,quillRef.currentFormat={}}),delete window.__polotnoQuill}},[]),t.useEffect(()=>l(()=>i.text,()=>{var t;const o=quillRef.editor.instance;if(!o){return}const n=o.getSelection();$(null===(t=c.current)||void 0===t?void 0:t.childNodes[0].innerHTML)===i.text||(setQuillContent(o,e),n&&(o.setSelection(n.index,n.length),a.runInAction(()=>{quillRef.currentFormat=o.getFormat()})))},{fireImmediately:!0}),[]),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)}},[]);const f={color:i.fill};return 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"),t.createElement(j,{ref:c,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)}),dir:d(S(i.text))})};function A(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 q(t,{fontFamily:e="",color:o="black"}={}){let n=`color: ${o||t.fill}`;return 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 `),`<div style="${["white-space: pre-wrap",`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("; ")}" contentEditable dir="${d(S(t.text))}">${z(t.text).replace(/\n/g,"</br>")}</div>`}const I=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);export const HTMLElement=e(({element:e,store:r})=>{const l=t.useRef(null),[d,b]=t.useState(),[v,z]=t.useState(!1),[$,T]=t.useState(!1),X=t.useRef(e.height),Y=r.selectedShapes.indexOf(e)>=0&&e.selectable,P=e.fontSize/3,{textVerticalResizeEnabled:W}=s,H=h(e.fontFamily),[L]=u(r,e.fontFamily),_=e._editModeEnabled;y(l);const B=L?e.fontFamily:H!==e.fontFamily?H:"Arial",D=g(e).fill,N=q(e,{fontFamily:B,color:D}),{width:Q,height:V}=function(e,o,n){return t.useMemo(()=>m(e),[e,o.width,n])}(N,e,L);t.useEffect(()=>{if(!L){return}if(!e.height){return void r.history.ignore(()=>{e.set({height:V})})}const{textOverflow:t}=s;if("change-font-size"!==t||v){"resize"===t&&(W&&e.height<V&&r.history.ignore(()=>{e.set({height:V})}),W||e.height===V||r.history.ignore(()=>{e.set({height:V})}))}else{const t=(t=>{let e=t.fontSize;for(let o=1;o<50;o++){const o=q(Object.assign(Object.assign({},t.toJSON()),{fontSize:e}),{fontFamily:t.fontFamily}),{height:n}=m(o),i=t.height&&n>t.height,r=x({html:o});if(!i&&!r){break}e-=.5}return e})(e);t!==e.fontSize?r.history.ignore(()=>{e.set({fontSize:t})}):e.height!==V&&(W&&e.height<V?r.history.ignore(()=>{e.set({height:V})}):W||r.history.ignore(()=>{e.set({height:V})}))}});const J=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 p(e),t.lastArgs=Object.assign({},e)),t.lastResult;var o,n}},[]),G=t.useRef(0),K=t.useRef(null);t.useEffect(()=>{v||_||(async()=>{G.current++;const t=G.current;let o=E(`text ${e.id} ${t}`);K.current&&K.current(),K.current=o,T(!0);let n=null;const i=I?5:1;for(let l=0;l<i;l++){const o=l>0?J:p;try{if(n=await o({skipCache:l>0,html:N,width:e.width||1,height:e.height||V||1,fontFamily:B,padding:P,pixelRatio:r._elementsPixelRatio,font:r.fonts.find(t=>t.fontFamily===B)||F.globalFonts.find(t=>t.fontFamily===B)}),t!==G.current){return}if(I&&A(n)){await new Promise(t=>setTimeout(t,50*(l+1)));continue}break}catch(a){console.error(a),k(`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)})()},[N,v,V,_,B,e.height,r._elementsPixelRatio,L]);const[U,Z]=C($,300),[tt]=C(v,300,!0),et=tt||U;t.useEffect(()=>{var t;if(!et){return a.autorun(()=>{const t=l.current;c(t,e)})}null===(t=l.current)||void 0===t||t.clearCache()},[d,et,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]),t.useEffect(()=>{d&&!$&&K.current&&(K.current(),K.current=null)},[d,$]),t.useEffect(()=>()=>{K.current&&K.current()},[]),t.useEffect(()=>{Y||""!==S(e.text)||!e.removable||e.placeholder||r.deleteElements([e.id])},[Y]);let ot=0;"middle"===e.verticalAlign&&(ot=(e.height-V)/2),"bottom"===e.verticalAlign&&(ot=e.height-V);const nt=f({fontLoaded:L,fontFamily:e.fontFamily,fontSize:e.fontSize,lineHeight:e.lineHeight}),it=R(),rt=t.useRef(null),at=t.useRef(null),lt=_&&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*nt*.5),offsetY:e.backgroundPadding*(e.fontSize*nt*.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*nt),height:e.a.height+e.backgroundPadding*(e.fontSize*nt),cornerRadius:e.backgroundCornerRadius*(e.fontSize*nt*.5)}),t.createElement(i,{ref:l,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:!et,draggable:it?e.draggable&&Y:e.draggable,preventDefault:!it||Y,opacity:_?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&&(at.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];at.current=n?{x:n.clientX,y:n.clientY}:null,e.toggleEditMode(!0)}},onTransformStart:t=>{z(!0),X.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,rt.current&&n.position(rt.current)),n.width(r),n.scaleX(1),s.textVerticalResizeEnabled){const t=Math.max(V,X.current);e.set({height:t})}e.set({width:n.width(),x:n.x(),y:n.y()})}else if(a){let o="resize"===s.textOverflow?V: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})}rt.current=t.target.position()},onTransformEnd:t=>{z(!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(n,{ref:l,image:d,x:e.a.x,y:e.a.y,offsetX:P,offsetY:P-ot,listening:!1,rotation:e.a.rotation,width:e.a.width+2*P,height:(e.a.width+2*P)*((null==d?void 0:d.height)/(null==d?void 0:d.width)||1),visible:!et&&!_,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||v||et}),(et||lt)&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-ot},t.createElement(w,{divProps:{style:{pointerEvents:"none"}}},t.createElement(j,{dangerouslySetInnerHTML:{__html:N},style:{pointerEvents:"none",opacity:e.a.opacity}}))),_&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-ot},t.createElement(w,null,t.createElement(M,{html:N,element:e,onChange:t=>{const o=O({oldText:S(e.text),newText:S(t),element:e});e.set({text:t,fontSize:o})},onBlur:t=>{e.toggleEditMode(!1),Z(!0)},clickCoords:at.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=r.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/text-element.js
CHANGED
|
@@ -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}from"react-konva";import{Html as i}from"react-konva-utils";import{autorun as a}from"mobx";import l from"konva";import{parsePath as s,roundCommands as c}from"svg-round-corners";import{useColor as d}from"./use-color.js";import{incrementLoader as h}from"../utils/loader.js";import{isFontLoaded as u}from"../utils/fonts.js";import{flags as f}from"../utils/flags.js";import{removeTags as g}from"../utils/text.js";import{applyFilter as m}from"./apply-filters.js";import{useFadeIn as p}from"./use-fadein.js";import{isTouchDevice as x}from"../utils/screen.js";import{isAlive as w}from"mobx-state-tree";import{getLimitedFontSize as v}from"./text-element/max-font-size.js";let y;function S(){return y||(y=document.getElementById("polotno-text-style"),y||(y=document.createElement("style"),y.id="polotno-text-style",document.head.appendChild(y)),y)}l._fixTextRendering=!0;const E={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 b(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++){b(t[n])&&(e+=1)}return e>t.length/2}export function getDir(t){return isRTLText(t)?"rtl":"ltr"}const z=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(E),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;const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=S();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=g(n.text);return t.createElement("textarea",{className:"polotno-input",ref:c,dir:getDir(u),style:Object.assign(Object.assign(Object.assign({},E),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})}),O=e=>t.createElement(i,null,t.createElement(z,Object.assign({},e)));export const useFontLoader=(e,n)=>{const[o,r]=t.useReducer(t=>t+1,0),i=t.useRef(u(n));return t.useLayoutEffect(()=>{if(i.current=u(n),i.current){return}let t=!0;return(async()=>{i.current=!1,r();const o=h(`text ${n}`);await e.loadFont(n),setTimeout(o,100),t&&(i.current=!0,r())})(),()=>{t=!1}},[n]),[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 const TextElement=e(({element:e,store:i})=>{const l=t.useRef(null),h=t.useRef(null),{editorEnabled:u,selectAll:v}=(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),[y,S]=t.useState(!1),E=t.useRef(e.a.height),b=i.selectedShapes.indexOf(e)>=0&&e.selectable,{textVerticalResizeEnabled:z}=f,A=usePrevious(e.fontFamily),[T,L]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=l.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(T)&&L(n)}),t.useEffect(()=>{if(e.a.width){return}const t=l.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useLayoutEffect(()=>a(()=>{const t=l.current;m(t,e)}));const[k]=useFontLoader(i,e.fontFamily);let F=g(e.text);"uppercase"===e.textTransform&&(F=F.toUpperCase());const M=()=>{const t=l.current.clone({height:void 0}),e=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),e};t.useLayoutEffect(()=>{if(!k){return}const{textOverflow:t,textSplitAllowed:n}=f;if(!e.a.height){const t=M();return void i.history.ignore(()=>{e.set({height:t})},!1,!0)}if(!i.isPlaying){if("change-font-size"!==t||y){if("resize"===t){const t=M();z&&e.a.height<t&&i.history.ignore(()=>{var n;w(e)&&e.set({height:t}),null===(n=l.current)||void 0===n||n.height(t)},!1,!0),z||e.a.height===t||y||i.history.ignore(()=>{var n;w(e)&&e.set({height:t}),null===(n=l.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=g(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}(l.current,e,n);if(t!==e.a.fontSize){return void i.history.ignore(()=>{e.set({fontSize:t})},!1,!0)}const o=M();e.a.height===o||z||i.history.ignore(()=>{e.set({height:o})},!1,!0)}}}),t.useLayoutEffect(()=>{const t=l.current;t&&(t.width(t.width()+1e-8),t._setTextData(),m(t,e))},[k]);const R=t.useRef(null),$=t.useRef(0),j=t=>{t.evt.preventDefault();const n=i.selectedShapes.find(t=>t===e);n&&e.contentEditable&&($.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())},H=!F&&e.placeholder?.6:e.a.opacity;p(l,H);const C=getLineHeight({fontLoaded:k,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),X=e.selectable||"admin"===i.role,Y=d(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 d=t.length-1;d>=0;d--){const n=t[d],{cx:o}=n,i=t[d+1];i&&i.width>n.width?l+=` L ${o-n.width/2-r} ${(d+1)*e-r}`:l+=` L ${o-n.width/2-r} ${(d+1)*e+r}`;const a=t[d-1];a&&a.width>n.width?l+=` L ${o-n.width/2-r} ${d*e+r}`:l+=` L ${o-n.width/2-r} ${d*e-r}`}l+=" Z";const h=s(l);return c(h,i).path}({lines:JSON.parse(JSON.stringify(T)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*C*.5),lineHeight:C*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*C*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.backgroundCornerRadius,e.a.fontSize,C,e.backgroundPadding,e.a.width,e.align,T]),D=x();let W=0;return"middle"===e.verticalAlign?W=(e.a.height-T.length*C*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(W=e.a.height-T.length*C*e.a.fontSize),t.createElement(t.Fragment,null,t.createElement(r,{ref:h,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*H,data:B,fill:e.backgroundColor,offsetY:-W}),t.createElement(n,Object.assign({ref:l,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:F||e.placeholder,direction:getDir(F)},Y,{stroke:e.stroke,lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${A}"`,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:D?e.draggable&&b:e.draggable,preventDefault:!D||b,opacity:H,visible:!e._editModeEnabled,ellipsis:"ellipsis"===f.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:C,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:j,onTap:j,onTransformStart:()=>{S(!0),E.current=l.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=h.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,R.current&&i.position(R.current)),i.width(r),i.scaleX(1),i.scaleY(1);const a=M();if("ellipsis"!==f.textOverflow){const t=Math.max(a,E.current);i.height(t),e.set({height:i.height()})}const l=f.textVerticalResizeEnabled?Math.max(a,E.current):M();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),m(i,e)}if("top-center"===a||"bottom-center"===a){let n="resize"===f.textOverflow?M():C*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}R.current=t.target.position();const l=t.target.scaleX();null===(r=h.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=h.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),S(!1)}})),u&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement(O,{textNodeRef:l,element:e,selectAll:v,cursorPosition:$.current,onBlur:()=>{e.toggleEditMode(!1),""===e.text&&e.removable&&!e.placeholder&&i.deleteElements([e.id])}})))});
|
|
1
|
+
import t from"react";import{observer as e}from"mobx-react-lite";import{Group as n,Path as o,Text as r}from"react-konva";import{Html as i}from"react-konva-utils";import{autorun as a}from"mobx";import l from"konva";import{parsePath as s,roundCommands as c}from"svg-round-corners";import{useColor as d}from"./use-color.js";import{incrementLoader as h}from"../utils/loader.js";import{isFontLoaded as u}from"../utils/fonts.js";import{flags as f}from"../utils/flags.js";import{removeTags as g}from"../utils/text.js";import{applyFilter as m}from"./apply-filters.js";import{useFadeIn as p}from"./use-fadein.js";import{isTouchDevice as x}from"../utils/screen.js";import{isAlive as w}from"mobx-state-tree";import{getLimitedFontSize as v}from"./text-element/max-font-size.js";let y;function S(){return y||(y=document.getElementById("polotno-text-style"),y||(y=document.createElement("style"),y.id="polotno-text-style",document.head.appendChild(y)),y)}l._fixTextRendering=!0;const E={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 b(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++){b(t[n])&&(e+=1)}return e>t.length/2}export function getDir(t){return isRTLText(t)?"rtl":"ltr"}const z=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(E),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;const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=S();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=g(n.text);return t.createElement("textarea",{className:"polotno-input",ref:c,dir:getDir(u),style:Object.assign(Object.assign(Object.assign({},E),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})}),O=e=>t.createElement(i,null,t.createElement(z,Object.assign({},e)));export const useFontLoader=(e,n)=>{const[o,r]=t.useReducer(t=>t+1,0),i=t.useRef(u(n));return t.useLayoutEffect(()=>{if(i.current=u(n),i.current){return}let t=!0;return(async()=>{i.current=!1,r();const o=h(`text ${n}`);await e.loadFont(n),setTimeout(o,100),t&&(i.current=!0,r())})(),()=>{t=!1}},[n]),[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 const TextElement=e(({element:e,store:i})=>{const l=t.useRef(null),h=t.useRef(null),{editorEnabled:u,selectAll:v}=(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),[y,S]=t.useState(!1),E=t.useRef(e.a.height),b=i.selectedShapes.indexOf(e)>=0&&e.selectable,{textVerticalResizeEnabled:z}=f,A=usePrevious(e.fontFamily),[T,L]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=l.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(T)&&L(n)}),t.useEffect(()=>{if(e.a.width){return}const t=l.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{b||""!==e.text||!e.removable||e.placeholder||i.deleteElements([e.id])},[b]),t.useLayoutEffect(()=>a(()=>{const t=l.current;m(t,e)}));const[k]=useFontLoader(i,e.fontFamily);let F=g(e.text);"uppercase"===e.textTransform&&(F=F.toUpperCase());const M=()=>{const t=l.current.clone({height:void 0}),e=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),e};t.useLayoutEffect(()=>{if(!k){return}const{textOverflow:t,textSplitAllowed:n}=f;if(!e.a.height){const t=M();return void i.history.ignore(()=>{e.set({height:t})})}if(!i.isPlaying){if("change-font-size"!==t||y){if("resize"===t){const t=M();z&&e.a.height<t&&i.history.ignore(()=>{var n;w(e)&&e.set({height:t}),null===(n=l.current)||void 0===n||n.height(t)},!1,!0),z||e.a.height===t||y||i.history.ignore(()=>{var n;w(e)&&e.set({height:t}),null===(n=l.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=g(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}(l.current,e,n);if(t!==e.a.fontSize){return void i.history.ignore(()=>{e.set({fontSize:t})},!1,!0)}const o=M();e.a.height===o||z||i.history.ignore(()=>{e.set({height:o})},!1,!0)}}}),t.useLayoutEffect(()=>{const t=l.current;t&&(t.width(t.width()+1e-8),t._setTextData(),m(t,e))},[k]);const R=t.useRef(null),$=t.useRef(0),j=t=>{t.evt.preventDefault();const n=i.selectedShapes.find(t=>t===e);n&&e.contentEditable&&($.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())},H=!F&&e.placeholder?.6:e.a.opacity;p(l,H);const C=getLineHeight({fontLoaded:k,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),X=e.selectable||"admin"===i.role,Y=d(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 d=t.length-1;d>=0;d--){const n=t[d],{cx:o}=n,i=t[d+1];i&&i.width>n.width?l+=` L ${o-n.width/2-r} ${(d+1)*e-r}`:l+=` L ${o-n.width/2-r} ${(d+1)*e+r}`;const a=t[d-1];a&&a.width>n.width?l+=` L ${o-n.width/2-r} ${d*e+r}`:l+=` L ${o-n.width/2-r} ${d*e-r}`}l+=" Z";const h=s(l);return c(h,i).path}({lines:JSON.parse(JSON.stringify(T)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*C*.5),lineHeight:C*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*C*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.backgroundCornerRadius,e.a.fontSize,C,e.backgroundPadding,e.a.width,e.align,T]),D=x();let W=0;return"middle"===e.verticalAlign?W=(e.a.height-T.length*C*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(W=e.a.height-T.length*C*e.a.fontSize),t.createElement(t.Fragment,null,t.createElement(o,{ref:h,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*H,data:B,fill:e.backgroundColor,offsetY:-W}),t.createElement(r,Object.assign({ref:l,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:F||e.placeholder,direction:getDir(F)},Y,{stroke:e.stroke,lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${A}"`,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:D?e.draggable&&b:e.draggable,preventDefault:!D||b,opacity:H,visible:!e._editModeEnabled,ellipsis:"ellipsis"===f.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:C,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:j,onTap:j,onTransformStart:()=>{S(!0),E.current=l.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=h.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,R.current&&i.position(R.current)),i.width(r),i.scaleX(1),i.scaleY(1);const a=M();if("ellipsis"!==f.textOverflow){const t=Math.max(a,E.current);i.height(t),e.set({height:i.height()})}const l=f.textVerticalResizeEnabled?Math.max(a,E.current):M();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),m(i,e)}if("top-center"===a||"bottom-center"===a){let n="resize"===f.textOverflow?M():C*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}R.current=t.target.position();const l=t.target.scaleX();null===(r=h.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=h.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),S(!1)}})),u&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement(O,{textNodeRef:l,element:e,selectAll:v,cursorPosition:$.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
|
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 m}from"mobx";import{downloadFile as g}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 k}from"../utils/to-svg.js";import{Page as _}from"./page-model.js";import{forEveryChild as I}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(_),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:"",_forceShowCredit:!1,_key:"",_validated:!1}).views(e=>{const t=m(()=>{const t={};return I({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 I({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 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 I({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=_.create(Object.assign({id:c(10)},e));return t.pages.push(i),t._activePageId=i.id,i},selectPage(e){t._activePageId=e},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 m=t._elementsPixelRatio;d>t._elementsPixelRatio&&t.setElementsPixelRatio(d),r?null==c||c.set({_forceMount:!0}):null==c||c.set({_exporting:!0});const g=await E(()=>p.stages.find(e=>e.getAttr("pageId")===o));if(!g){throw null==c||c.set({_forceMount:!1,_exporting:!1}),t.setElementsPixelRatio(m),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=g.findOne(".page-container");if(!u){throw t.setElementsPixelRatio(m),null==c||c.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const f=g.position();g.position({x:0,y:0}),g.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.getAttr("hideInExport"));w.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()});const P=u.find(e=>!e.visible()&&e.getAttr("editModeEnabled"));P.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()}),i&&u.find(".page-background").forEach(e=>e.hide());const x=a?c.bleed:0;let k=x;!t.bleedVisible&&a||(t.bleedVisible||a?t.bleedVisible&&a?k=0:t.bleedVisible&&!a&&(k=-c.bleed):k=0);const _=document.createElement("canvas");_.width=Math.round((c.computedWidth+2*x)*d),_.height=Math.round((c.computedHeight+2*x)*d);const I=_.getContext("2d");"image/jpeg"===n&&(I.fillStyle="white",I.fillRect(0,0,_.width,_.height));const S=u.scale();u.scale({x:1,y:1});const O=u.toCanvas({x:u.x()-k,y:u.y()-k,width:c.computedWidth+2*x,height:c.computedHeight+2*x,pixelRatio:d});return u.scale(S),I.drawImage(O,0,0,_.width,_.height),p.Util.releaseCanvas(O),i&&u.find(".page-background").forEach(e=>e.show()),w.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),P.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)),g.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),u.find(".highlighter").forEach(e=>e.visible(!0)),h.clip(y),b.clip(v),g.position(f),null==c||c.set({_exporting:!1,_forceMount:!1}),await new Promise(e=>setTimeout(e)),t.setElementsPixelRatio(m),_},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];g(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),m=r[0]||{},g=e.includeBleed?m.bleed:0,f=d(m.computedWidth+2*g+2*p),h=d(m.computedHeight+2*g+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 m=0,g=a;for(;m<10;){m+=1,2===m&&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:g}));if(o.length>20){return e.onProgress&&e.onProgress(++v/s.length*.9),{url:o,width:l,height:p,widthPx:n,heightPx:r}}g*=.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+g)*r,bottomLeftY:d(c+g)*r,topRightX:d(o-c-g)*r,topRightY:d(a-c-g)*r},s.pageContext.bleedBox={bottomLeftX:d(c+g)*r,bottomLeftY:d(c+g)*r,topRightX:d(o-c-g)*r,topRightY:d(a-c-g)*r},p){y.setLineWidth(d(1));const e=p+d(g);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);g(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)));g(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:i}={elementHook:void 0,pageId:void 0}){var o;const n=t.toJSON();i=i||(null===(o=n.pages[0])||void 0===o?void 0:o.id);const a=n.pages.find(e=>e.id===i);return k({json:Object.assign(Object.assign({},n),{pages:a?[a]:[]}),elementHook:e})},async saveAsSVG({fileName:e,elementHook:i,pageId:o}={}){const n=await t.toSVG({elementHook:i,pageId:o}),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(n)));g(a,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&&I({children:s.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),r<2&&I({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 m}from"mobx";import{downloadFile as g}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 k}from"../utils/to-svg.js";import{Page as _}from"./page-model.js";import{forEveryChild as I}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(_),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:"",_forceShowCredit:!1,_key:"",_validated:!1}).views(e=>{const t=m(()=>{const t={};return I({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 I({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 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 I({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=_.create(Object.assign({id:c(10)},e));return t.pages.push(i),t._activePageId=i.id,i},selectPage(e){t._activePageId=e},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 m=t._elementsPixelRatio;d>t._elementsPixelRatio&&t.setElementsPixelRatio(d),r?null==c||c.set({_forceMount:!0}):null==c||c.set({_exporting:!0});const g=await E(()=>p.stages.find(e=>e.getAttr("pageId")===o));if(!g){throw null==c||c.set({_forceMount:!1,_exporting:!1}),t.setElementsPixelRatio(m),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=g.findOne(".page-container");if(!u){throw t.setElementsPixelRatio(m),null==c||c.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const f=g.position();g.position({x:0,y:0}),g.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 k=x;!t.bleedVisible&&a||(t.bleedVisible||a?t.bleedVisible&&a?k=0:t.bleedVisible&&!a&&(k=-c.bleed):k=0);const _=document.createElement("canvas");_.width=Math.round((c.computedWidth+2*x)*d),_.height=Math.round((c.computedHeight+2*x)*d);const I=_.getContext("2d");"image/jpeg"===n&&(I.fillStyle="white",I.fillRect(0,0,_.width,_.height));const S=u.scale();u.scale({x:1,y:1});const O=u.toCanvas({x:u.x()-k,y:u.y()-k,width:c.computedWidth+2*x,height:c.computedHeight+2*x,pixelRatio:d});return u.scale(S),I.drawImage(O,0,0,_.width,_.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)),g.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),u.find(".highlighter").forEach(e=>e.visible(!0)),h.clip(y),b.clip(v),g.position(f),null==c||c.set({_exporting:!1,_forceMount:!1}),await new Promise(e=>setTimeout(e)),t.setElementsPixelRatio(m),_},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];g(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),m=r[0]||{},g=e.includeBleed?m.bleed:0,f=d(m.computedWidth+2*g+2*p),h=d(m.computedHeight+2*g+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 m=0,g=a;for(;m<10;){m+=1,2===m&&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:g}));if(o.length>20){return e.onProgress&&e.onProgress(++v/s.length*.9),{url:o,width:l,height:p,widthPx:n,heightPx:r}}g*=.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+g)*r,bottomLeftY:d(c+g)*r,topRightX:d(o-c-g)*r,topRightY:d(a-c-g)*r},s.pageContext.bleedBox={bottomLeftX:d(c+g)*r,bottomLeftY:d(c+g)*r,topRightX:d(o-c-g)*r,topRightY:d(a-c-g)*r},p){y.setLineWidth(d(1));const e=p+d(g);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);g(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)));g(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:i}={elementHook:void 0,pageId:void 0}){var o;const n=t.toJSON();i=i||(null===(o=n.pages[0])||void 0===o?void 0:o.id);const a=n.pages.find(e=>e.id===i);return k({json:Object.assign(Object.assign({},n),{pages:a?[a]:[]}),elementHook:e})},async saveAsSVG({fileName:e,elementHook:i,pageId:o}={}){const n=await t.toSVG({elementHook:i,pageId:o}),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(n)));g(a,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&&I({children:s.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),r<2&&I({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;
|