polotno 2.36.4 → 2.36.6

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.
@@ -1 +1 @@
1
- import t from"react";import{observer as e}from"mobx-react-lite";import{Group as n,Path as o,Text 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{getDir as w,getCurvePath as p,resolveLineHeight as x}from"../utils/text-html.js";import{applyFilter as v}from"./apply-filters.js";import{useFadeIn as y}from"./use-fadein.js";import{isTouchDevice as E}from"../utils/screen.js";import{isAlive as S}from"mobx-state-tree";import{getLimitedFontSize as b}from"./text-element/max-font-size.js";import{getOptimalCaretColor as z}from"./text-element/caret-color.js";let O;function k(){return O||(O=document.getElementById("polotno-text-style"),O||(O=document.createElement("style"),O.id="polotno-text-style",document.head.appendChild(O)),O)}s._fixTextRendering=!0;const A={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};export{getDir}from"../utils/text-html.js";const L=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(A),s=e.current;t.useLayoutEffect(()=>{if(!s){return}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=z(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=k();o.innerHTML="",o.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(a)&&l(t)});const c=t.useRef(null);if(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,void 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)}},[]),!s){return null}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:w(u),style:Object.assign(Object.assign(Object.assign({},A),a),{paddingTop:d+"px"}),value:u,onChange:t=>{const e=b({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),$=e=>t.createElement(a,null,t.createElement(L,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(()=>x({fontFamily:n,fontSize:o,lineHeight:r}),[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{getCurvePath}from"../utils/text-html.js";export const TextElement=e(({element:e,store:a})=>{const s=t.useRef(null),f=t.useRef(null),x=t.useRef(null),b=t.useRef([]),[,z]=t.useReducer(t=>t+1,0),{editorEnabled:O,selectAll:k}=(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),[A,L]=t.useState(!1),F=t.useRef(e.a.height),R=a.selectedShapes.indexOf(e)>=0&&e.selectable,M=usePrevious(R),{textVerticalResizeEnabled:j}=g,T=g.autoDeleteEmptyText,C=usePrevious(e.fontFamily),[H,P]=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(H)&&P(n)}),t.useEffect(()=>{if(e.a.width){return}const t=s.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{M&&!R&&T&&""===e.text&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[T,e.placeholder,e.removable,e.text,R,M]),t.useLayoutEffect(()=>l(()=>{const t=s.current;v(t,e)})),t.useEffect(()=>{const t=b.current;t.length>0&&(b.current=[],t.forEach(t=>t()))});const[W]=useFontLoader(a,e.fontFamily);let X=m(e.text);"uppercase"===e.textTransform&&(X=X.toUpperCase());const Y=()=>{if(e.curveEnabled){const t=f.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(!W){return}const{textOverflow:t,textSplitAllowed:n}=g,o=(t,...n)=>{const o=u(`text ${e.id} before ignore`);a.history.ignore(t,...n).then(()=>{b.current.push(o),z()})};if(!e.a.height){const t=Y();return void o(()=>{e.set({height:t})})}if(!a.isPlaying){if("change-font-size"!==t||A){if("resize"===t){const t=Y();j&&e.a.height<t&&!A&&o(()=>{var n;S(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0),j||e.a.height===t||A||o(()=>{var n;S(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)=>(e=e.toLowerCase(),/[\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.toLowerCase()).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 o(()=>{e.set({fontSize:t})},!1,!0)}const r=Y();e.a.height===r||j||o(()=>{e.set({height:r})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(W&&e.curveEnabled){const n=null===(t=f.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})}}},[W,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(),v(t,e))},[W]);const B=t.useRef(null),D=t.useRef(0),N=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(D.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())},I=!X&&e.placeholder?.6:e.a.opacity;y(s,I);const J=getLineHeight({fontLoaded:W,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),_=e.selectable||"admin"===a.role,V=h(e),Z=h(e,e.stroke,"stroke"),U=t.useMemo(()=>e.backgroundEnabled?e.curveEnabled?function({width:t,height:e,padding:n=0,cornerRadius:o=0}){const r=-n,i=-n,a=t+n,l=e+n,s=c(`M ${r} ${i} L ${a} ${i} L ${a} ${l} L ${r} ${l} Z`);return d(s,o).path}({width:e.a.width,height:e.a.height,cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*J*.5),padding:e.backgroundPadding*(e.a.fontSize*J*.5)}):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(H)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*J*.5),lineHeight:J*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*J*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.curveEnabled,e.backgroundCornerRadius,e.a.fontSize,e.a.height,J,e.backgroundPadding,e.a.width,e.align,H]),q=E();let G=0;e.curveEnabled||("middle"===e.verticalAlign?G=(e.a.height-H.length*J*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(G=e.a.height-H.length*J*e.a.fontSize));const K=e.curveEnabled?p(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",Q=W?'"'+e.fontFamily+'"':C===e.fontFamily?"Arial":'"'+C+'"';return t.createElement(t.Fragment,null,t.createElement(o,{ref:x,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*I,data:U,fill:e.backgroundColor,offsetY:-G}),t.createElement(o,{data:K,stroke:"red",strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:f,visible:e.curveEnabled,data:K,text:X||e.placeholder,listening:!1,align:"center",textBaseline:"middle"},V,Z,{strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${C}"`,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration.trim(),letterSpacing:e.letterSpacing*e.a.fontSize,x:e.a.x,y:e.a.y,rotation:e.a.rotation,opacity:e._editModeEnabled?.3:I,hideInExport:!e.showInExport,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity})),t.createElement(r,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:X||e.placeholder,direction:w(X)},V,Z,{lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:Q,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:q?e.draggable&&R:e.draggable,preventDefault:!q||R,opacity:e.curveEnabled?0:I,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:J,letterSpacing:e.letterSpacing*e.a.fontSize,listening:_,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:N,onTap:N,onTransformStart:()=>{L(!0),F.current=s.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=x.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,B.current&&i.position(B.current)),i.width(r),i.scaleX(1),i.scaleY(1);let a=Y();if("ellipsis"===g.textOverflow){a=F.current}else{const t=Math.max(a,F.current);i.height(t),e.set({height:i.height()})}const l=g.textVerticalResizeEnabled?Math.max(a,F.current):Y();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),v(i,e)}if("top-center"===a||"bottom-center"===a){let n="resize"===g.textOverflow?Y():J*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}B.current=t.target.position();const l=t.target.scaleX();null===(r=x.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=x.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),L(!1)}})),O&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement($,{textNodeRef:s,element:e,selectAll:k,cursorPosition:D.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
1
+ import t from"react";import{observer as e}from"mobx-react-lite";import{Group as n,Path as o,Text 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{getDir as w,getCurvePath as p,resolveLineHeight as x}from"../utils/text-html.js";import{applyFilter as v}from"./apply-filters.js";import{useFadeIn as y}from"./use-fadein.js";import{isTouchDevice as E}from"../utils/screen.js";import{isAlive as S}from"mobx-state-tree";import{getLimitedFontSize as b}from"./text-element/max-font-size.js";import{getOptimalCaretColor as z}from"./text-element/caret-color.js";let O;function k(){return O||(O=document.getElementById("polotno-text-style"),O||(O=document.createElement("style"),O.id="polotno-text-style",document.head.appendChild(O)),O)}s._fixTextRendering=!0;const A={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};export{getDir}from"../utils/text-html.js";const L=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(A),s=e.current;t.useLayoutEffect(()=>{if(!s){return}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=z(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=k();o.innerHTML="",o.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(a)&&l(t)});const c=t.useRef(null);if(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,void 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)}},[]),!s){return null}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:w(u),style:Object.assign(Object.assign(Object.assign({},A),a),{paddingTop:d+"px"}),value:u,onChange:t=>{const e=b({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),$=e=>t.createElement(a,null,t.createElement(L,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(()=>x({fontFamily:n,fontSize:o,lineHeight:r}),[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{getCurvePath}from"../utils/text-html.js";export const TextElement=e(({element:e,store:a})=>{const s=t.useRef(null),f=t.useRef(null),x=t.useRef(null),b=t.useRef([]),[,z]=t.useReducer(t=>t+1,0),{editorEnabled:O,selectAll:k}=(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),[A,L]=t.useState(!1),F=t.useRef(e.a.height),R=a.selectedShapes.indexOf(e)>=0&&e.selectable,M=usePrevious(R),{textVerticalResizeEnabled:j}=g,T=g.autoDeleteEmptyText,C=usePrevious(e.fontFamily),[H,P]=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(H)&&P(n)}),t.useEffect(()=>{if(e.a.width){return}const t=s.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{M&&!R&&T&&""===e.text&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[T,e.placeholder,e.removable,e.text,R,M]),t.useLayoutEffect(()=>l(()=>{const t=s.current;v(t,e)})),t.useEffect(()=>{const t=b.current;t.length>0&&(b.current=[],t.forEach(t=>t()))});const[W]=useFontLoader(a,e.fontFamily);let X=m(e.text);"uppercase"===e.textTransform&&(X=X.toUpperCase());const Y=()=>{if(e.curveEnabled){const t=f.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(!W){return}const{textOverflow:t,textSplitAllowed:n}=g,o=(t,...n)=>{const o=u(`text ${e.id} before ignore`);a.history.ignore(t,...n).then(()=>{b.current.push(o),z()})};if(!e.height){const t=Y();return void o(()=>{e.set({height:t})})}if(!a.isPlaying){if("change-font-size"!==t||A){if("resize"===t){const t=Y();j&&e.height<t&&!A&&o(()=>{var n;S(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0),j||e.height===t||A||o(()=>{var n;S(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)=>(e=e.toLowerCase(),/[\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.toLowerCase()).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.fontSize){return void o(()=>{e.set({fontSize:t})},!1,!0)}const r=Y();e.height===r||j||o(()=>{e.set({height:r})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(W&&e.curveEnabled){const n=null===(t=f.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})}}},[W,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(),v(t,e))},[W]);const B=t.useRef(null),D=t.useRef(0),N=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(D.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())},I=!X&&e.placeholder?.6:e.a.opacity;y(s,I);const J=getLineHeight({fontLoaded:W,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),_=e.selectable||"admin"===a.role,V=h(e),Z=h(e,e.stroke,"stroke"),U=t.useMemo(()=>e.backgroundEnabled?e.curveEnabled?function({width:t,height:e,padding:n=0,cornerRadius:o=0}){const r=-n,i=-n,a=t+n,l=e+n,s=c(`M ${r} ${i} L ${a} ${i} L ${a} ${l} L ${r} ${l} Z`);return d(s,o).path}({width:e.a.width,height:e.a.height,cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*J*.5),padding:e.backgroundPadding*(e.a.fontSize*J*.5)}):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(H)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*J*.5),lineHeight:J*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*J*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.curveEnabled,e.backgroundCornerRadius,e.a.fontSize,e.a.height,J,e.backgroundPadding,e.a.width,e.align,H]),q=E();let G=0;e.curveEnabled||("middle"===e.verticalAlign?G=(e.a.height-H.length*J*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(G=e.a.height-H.length*J*e.a.fontSize));const K=e.curveEnabled?p(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",Q=W?'"'+e.fontFamily+'"':C===e.fontFamily?"Arial":'"'+C+'"';return t.createElement(t.Fragment,null,t.createElement(o,{ref:x,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*I,data:U,fill:e.backgroundColor,offsetY:-G}),t.createElement(o,{data:K,stroke:"red",strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:f,visible:e.curveEnabled,data:K,text:X||e.placeholder,listening:!1,align:"center",textBaseline:"middle"},V,Z,{strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${C}"`,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration.trim(),letterSpacing:e.letterSpacing*e.a.fontSize,x:e.a.x,y:e.a.y,rotation:e.a.rotation,opacity:e._editModeEnabled?.3:I,hideInExport:!e.showInExport,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity})),t.createElement(r,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:X||e.placeholder,direction:w(X)},V,Z,{lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:Q,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:q?e.draggable&&R:e.draggable,preventDefault:!q||R,opacity:e.curveEnabled?0:I,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:J,letterSpacing:e.letterSpacing*e.a.fontSize,listening:_,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:N,onTap:N,onTransformStart:()=>{L(!0),F.current=s.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=x.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,B.current&&i.position(B.current)),i.width(r),i.scaleX(1),i.scaleY(1);let a=Y();if("ellipsis"===g.textOverflow){a=F.current}else{const t=Math.max(a,F.current);i.height(t),e.set({height:i.height()})}const l=g.textVerticalResizeEnabled?Math.max(a,F.current):Y();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),v(i,e)}if("top-center"===a||"bottom-center"===a){let n="resize"===g.textOverflow?Y():J*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}B.current=t.target.position();const l=t.target.scaleX();null===(r=x.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=x.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),L(!1)}})),O&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement($,{textNodeRef:s,element:e,selectAll:k,cursorPosition:D.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
@@ -1 +1 @@
1
- import e from"react";import{observer as t}from"mobx-react-lite";import r from"./page.js";import{TopRules as n}from"./rules.js";import{AudioElement as o}from"./audio.js";import{handleHotkey as l}from"./hotkeys.js";import{t as i}from"../utils/l10n.js";const a=(e,t,r)=>Math.max(t,Math.min(r,e)),s=(e,t)=>Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2)),c=({store:t})=>e.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},e.createElement("p",null,i("workspace.noPages")),e.createElement("button",{onClick:()=>{t.addPage()}},i("workspace.addPage"))),u=({width:t,height:r,xPadding:n,yPadding:o,backgroundColor:l})=>e.createElement("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:n+"px",paddingRight:n+"px",paddingTop:o+"px",paddingBottom:o+"px",flexShrink:0}},e.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}})),d=[4,6];export const WorkspaceCanvas=t(({store:t,layout:i="vertical",pageControlsEnabled:h,backgroundColor:g,pageBorderColor:p,activePageBorderColor:f,bleedColor:m,snapGuideStroke:v,snapGuideStrokeWidth:b,snapGuideDash:w,selectionRectFill:x,selectionRectStroke:k,selectionRectStrokeWidth:E,transformLabelFill:T,transformLabelTextFill:y,distanceGuideStroke:L,distanceLabelFill:M,distanceLabelTextFill:S,rulerBackgroundColor:C,rulerTextColor:P,rulerBorderColor:R,rulerBorderSize:F,rulerTickColor:z,rulerTickSize:B,components:O,onKeyDown:W,paddingX:N,paddingY:j,pageGap:G,altCloneEnabled:_=!0,visiblePagesOffset:Y,renderOnlyActivePage:D,tooltipSafeArea:X})=>{var A;const H="horizontal"===i,I=null!=N?N:20,K=null!=j?j:55,[q,V]=e.useState({width:100,height:100}),J=e.useRef(q),Q=e.useRef(null),U=e.useRef(null),Z=e.useRef(0),$=t.bleedVisible?Math.max(0,...t.pages.map(e=>e.bleed)):0,ee=Math.max(...t.pages.map(e=>e.computedWidth)),te=Math.max(...t.pages.map(e=>e.computedHeight)),re=(null===(A=t.activePage)||void 0===A?void 0:A.computedHeight)||0,ne=ee+2*$,oe=(D?re:te)+2*$,le=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===Q.current){return}const r=Q.current.getBoundingClientRect();0!==r.width&&0!==r.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(Q.current));const n=U.current.clientWidth||r.width,o={width:n,height:r.height};(J.current.width!==o.width||J.current.height!==o.height)&&(V(o),J.current=o);const l=(n-2*I)/ne,i=t.pages.length>1?3.1:2,a=(r.height-K*i)/oe,s=t.pages.length>1?3.1:2,c=(n-I*s)/ne,u=(r.height-2*K)/oe,d=t.pages.length?Math.max(Math.min(H?c:l,H?u:a),.01):1;t.scaleToFit!==d&&(t.setScale(d),t._setScaleToFit(d))};e.useLayoutEffect(()=>{le({skipTimeout:!0})},[]),e.useEffect(()=>{le()},[ne,oe,j,N]),e.useLayoutEffect(()=>{le({skipTimeout:!0})},[t.openedSidePanel]),e.useEffect(()=>{t.__()},[]),e.useEffect(()=>{const e=Q.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{le({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{le({skipTimeout:!0})},100);return()=>clearInterval(e)}},[ne,oe]);const ie=D?1:t.pages.length;let ae,se;if(H){const e=ne*t.scale*ie;ae=Math.max(I,(q.width-e)/ie/2),se=Math.max(K,(q.height-oe*t.scale)/2)}else{ae=Math.max(I,(q.width-ne*t.scale)/2);const e=oe*t.scale*ie;se=Math.max(K,(q.height-e)/ie/2)}Number.isNaN(ae)&&(ae=I),Number.isNaN(se)&&(se=K),e.useEffect(()=>{const e=e=>{(W||l)(e,t)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),e.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const r=Math.max(5,t.scaleToFit);let n=Math.min(.1,t.scaleToFit);H&&ne>0&&Number.isFinite(ne)&&(n=Math.max(n,300/ne)),n=Math.max(n,.01);const o=.03,l=a(e.deltaY<0?t.scale*(1+o):t.scale/(1+o),n,r);return void t.setScale(l)}},r=U.current;return null==r||r.addEventListener("wheel",e),()=>null==r?void 0:r.removeEventListener("wheel",e)},[H,ne,t]),e.useEffect(()=>{const e=U.current;if(!e){return}const r=e=>{2===e.touches.length&&(Z.current=s(e.touches[0],e.touches[1]))},n=r=>{if(2===r.touches.length&&Z.current>0){r.preventDefault();const n=s(r.touches[0],r.touches[1]),o=n/Z.current,l=Math.max(5,t.scaleToFit);let i=Math.min(.1,t.scaleToFit);H&&ne>0&&Number.isFinite(ne)&&(i=Math.max(i,300/ne)),i=Math.max(i,.01);const c=t.scale,u=a(c*o,i,l),d=u/c,h=e.getBoundingClientRect(),g=(r.touches[0].clientX+r.touches[1].clientX)/2-h.left,p=(r.touches[0].clientY+r.touches[1].clientY)/2-h.top,f=e.scrollLeft+g,m=e.scrollTop+p;ge.current=!0,t.setScale(u),e.scrollLeft=f*d-g,e.scrollTop=m*d-p,Z.current=n}},o=()=>{Z.current=0};return e.addEventListener("touchstart",r,{passive:!0}),e.addEventListener("touchmove",n,{passive:!1}),e.addEventListener("touchend",o,{passive:!0}),()=>{e.removeEventListener("touchstart",r),e.removeEventListener("touchmove",n),e.removeEventListener("touchend",o)}},[H,ne,t]);const ce=void 0!==G,ue=e.useMemo(()=>t.pages.map(e=>{if(H){const r=(e.computedWidth+2*$)*t.scale;return ce?r+G:r+2*ae}{const r=(e.computedHeight+2*$)*t.scale;return ce?r+G:r+2*se}}),[t.pages,t.scale,$,ae,se,G,H,ce]),de=e.useMemo(()=>{const e=[];let t=ce?H?ae:se:0;for(let r=0;r<ue.length;r++){e.push(t),t+=ue[r]}return e},[ue,ce,H,ae,se]),he=e.useMemo(()=>{const e=ue.reduce((e,t)=>e+t,0);return ce?e+(H?2*ae:2*se):e},[ue,ce,H,ae,se]),ge=e.useRef(!1),[,pe]=e.useReducer(e=>e+1,0);((t,r,n,o,l,i)=>{const a=e.useRef(r),s=e.useRef(0),c=e.useRef(!1),u=e.useRef(o.pages.length);c.current=u.current!==o.pages.length,u.current=o.pages.length,e.useEffect(()=>{const e=t.current,r=t=>{s.current=i?e.scrollLeft:e.scrollTop};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[i]),e.useLayoutEffect(()=>{if(!t.current){return}if(c.current){return}const e=t.current,n=i?e.offsetWidth:e.offsetHeight,o=(s.current+n/2)/a.current;l.current=!0;const u=o*r-n/2;i?e.scrollLeft=u:e.scrollTop=u,a.current=r},[n,r,i])})(U,he,t.scale,t,ge,H);const{handleScroll:fe}=((t,r,n,o,l,i,a,s,c)=>{const u=e.useRef(!1),d=e.useRef(null),h=e.useRef(!1),g="horizontal"===s;e.useEffect(()=>{const e=t.current,r=()=>{i.current};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[]);const p=o.pages.indexOf(o.activePage);return e.useLayoutEffect(()=>{if(a){return}if(!o.activePage){return}if(!t.current){return}if(u.current){return}const e=t.current,l=o.pages.indexOf(o.activePage),i=r[l]||0,s=g?e.scrollLeft:e.scrollTop,d=n[l]||n[0]||0;let p=()=>{};return(Math.abs(i-s)>.5*d||h.current)&&(h.current=!0,p=(({element:e,scrollTop:t,scrollLeft:r,duration:n=300,onFinish:o=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,a=l?t:r,s=a-i;let c=0,u=!1;if(0===n){return l?e.scrollTop=a:e.scrollLeft=a,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,s,n);l?e.scrollTop=t:e.scrollLeft=t,c<n?setTimeout(d,20):o()},h=(e,t,r,n)=>(e/=n/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:e},g?{scrollLeft:i}:{scrollTop:i}),{onFinish:()=>{h.current=!1,null==c||c()},duration:o.isPlaying?0:300}))),p},[o.activePage,p,o.isPlaying,a,s,r,n]),{handleScroll:e=>{if(a){return}if(h.current){return}u.current=!0,clearTimeout(d.current),d.current=setTimeout(()=>{u.current=!1},300);const t=(g?e.currentTarget.scrollLeft:e.currentTarget.scrollTop)+(g?l.width:l.height)/3;let n=0;for(let o=r.length-1;o>=0;o--){if(t>=r[o]){n=o;break}}const i=o.pages[n];i&&o.activePage!==i&&i.select()}}})(U,de,ue,t,q,ge,D,i,pe),me=q.width>=ne*t.scale+2*ae,ve=q.height>=oe*t.scale+2*se,be=g||"rgba(232, 232, 232, 0.9)",we=(null==O?void 0:O.NoPages)||c,xe=H?q.width:q.height,ke=U.current?H?U.current.scrollLeft:U.current.scrollTop:0,Ee=e=>{for(let t=de.length-1;t>=0;t--){if(e>=de[t]){return t}}return 0},Te=Math.max(0,Ee(ke)),ye=Math.min(t.pages.length-1,Ee(ke+xe)),Le=null!=Y?Y:1,Me=Math.max(0,Te-Le),Se=Math.min(t.pages.length-1,ye+Le);return e.createElement("div",{ref:Q,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:be,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container"},e.createElement("div",{ref:U,onScroll:fe,style:Object.assign({position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:H?"row":"column",overflow:"auto",overflowX:H?"auto":me?"hidden":"auto",overflowY:H&&ve?"hidden":"auto"},ce&&{paddingTop:H?0:se,paddingBottom:H?0:se,paddingLeft:H?ae:0,paddingRight:H?ae:0,boxSizing:"border-box"}),className:"polotno-workspace-inner"},t.pages.map((n,o)=>{const l=n===t.activePage;if(D&&!l&&!n._exportingOrRendering&&!n._forceMount){return null}const a=l||o>=Me&&o<=Se||n._exportingOrRendering||n._forceMount,s=H?ue[o]:ne*t.scale+2*ae,c=H?oe*t.scale+2*se:ue[o];if(!a){return e.createElement("div",{key:n.id,style:{flexShrink:0}},e.createElement(u,{width:s,height:c,backgroundColor:be,xPadding:ae,yPadding:se}))}const g=e.createElement(r,{key:n.id,page:n,xPadding:ae,yPadding:se,width:s,height:c,store:t,pageControlsEnabled:h,backColor:be,pageBorderColor:p||"lightgrey",activePageBorderColor:f||"rgb(0, 161, 255)",altCloneEnabled:_,bleedColor:m||"rgba(255, 0, 0, 0.1)",selectionRectFill:x,selectionRectStroke:k,selectionRectStrokeWidth:E,snapGuideStroke:v||"rgb(0, 161, 255)",snapGuideStrokeWidth:b||1,snapGuideDash:w||d,transformLabelFill:T,transformLabelTextFill:y,distanceGuideStroke:L||"rgb(0, 161, 255)",distanceLabelFill:M||"rgb(0, 161, 255)",distanceLabelTextFill:S||"white",components:O,viewportSize:q,layout:i,tooltipSafeArea:X});return(n._exportingOrRendering||n._forceMount)&&!l&&D?e.createElement("div",{style:{display:"none",flexShrink:0},key:n.id},g):g}),t.rulesVisible&&e.createElement(n,{store:t,xPadding:ae,yPadding:se,width:ne*t.scale+2*ae,height:oe*t.scale+2*se,pageSizes:ue,layout:i,renderOnlyActivePage:D,rulerBackgroundColor:C,rulerTextColor:P,rulerBorderColor:R,rulerBorderSize:F,rulerTickColor:z,rulerTickSize:B}),0===t.pages.length&&e.createElement(we,{store:t}),t.audios.map(r=>e.createElement(o,{key:r.id,audio:r,store:t}))))});export default WorkspaceCanvas;
1
+ import e from"react";import{observer as t}from"mobx-react-lite";import r from"./page.js";import{TopRules as n}from"./rules.js";import{AudioElement as o}from"./audio.js";import{handleHotkey as l}from"./hotkeys.js";import{t as i}from"../utils/l10n.js";const a=(e,t,r)=>Math.max(t,Math.min(r,e)),s=(e,t)=>Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2)),c=({store:t})=>e.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},e.createElement("p",null,i("workspace.noPages")),e.createElement("button",{onClick:()=>{t.addPage()}},i("workspace.addPage"))),u=({width:t,height:r,xPadding:n,yPadding:o,backgroundColor:l})=>e.createElement("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:n+"px",paddingRight:n+"px",paddingTop:o+"px",paddingBottom:o+"px",flexShrink:0}},e.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}})),d=[4,6];export const WorkspaceCanvas=t(({store:t,layout:i="vertical",pageControlsEnabled:h,backgroundColor:g,pageBorderColor:p,activePageBorderColor:f,bleedColor:m,snapGuideStroke:v,snapGuideStrokeWidth:b,snapGuideDash:w,selectionRectFill:x,selectionRectStroke:k,selectionRectStrokeWidth:E,transformLabelFill:T,transformLabelTextFill:y,distanceGuideStroke:L,distanceLabelFill:S,distanceLabelTextFill:C,rulerBackgroundColor:M,rulerTextColor:P,rulerBorderColor:R,rulerBorderSize:F,rulerTickColor:z,rulerTickSize:B,components:O,onKeyDown:W,paddingX:N,paddingY:j,pageGap:G,altCloneEnabled:_=!0,visiblePagesOffset:Y,renderOnlyActivePage:D,tooltipSafeArea:X})=>{var A;const H="horizontal"===i,I=null!=N?N:20,K=null!=j?j:55,[q,V]=e.useState({width:100,height:100}),J=e.useRef(q),Q=e.useRef(null),U=e.useRef(null),Z=e.useRef(0),$=t.bleedVisible?Math.max(0,...t.pages.map(e=>e.bleed)):0,ee=Math.max(...t.pages.map(e=>e.computedWidth)),te=Math.max(...t.pages.map(e=>e.computedHeight)),re=(null===(A=t.activePage)||void 0===A?void 0:A.computedHeight)||0,ne=ee+2*$,oe=(D?re:te)+2*$,le=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===Q.current){return}const r=Q.current.getBoundingClientRect();0!==r.width&&0!==r.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(Q.current));const n=U.current.clientWidth||r.width,o={width:n,height:r.height};(J.current.width!==o.width||J.current.height!==o.height)&&(V(o),J.current=o);const l=(n-2*I)/ne,i=t.pages.length>1?3.1:2,a=(r.height-K*i)/oe,s=t.pages.length>1?3.1:2,c=(n-I*s)/ne,u=(r.height-2*K)/oe,d=t.pages.length?Math.max(Math.min(H?c:l,H?u:a),.01):1;t.scaleToFit!==d&&(t.setScale(d),t._setScaleToFit(d))};e.useLayoutEffect(()=>{le({skipTimeout:!0})},[]),e.useEffect(()=>{le()},[ne,oe,j,N]),e.useLayoutEffect(()=>{le({skipTimeout:!0})},[t.openedSidePanel]),e.useEffect(()=>{t.__()},[]),e.useEffect(()=>{const e=Q.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{le({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{le({skipTimeout:!0})},100);return()=>clearInterval(e)}},[ne,oe]);const ie=D?1:t.pages.length;let ae,se;if(H){const e=ne*t.scale*ie;ae=Math.max(I,(q.width-e)/ie/2),se=Math.max(K,(q.height-oe*t.scale)/2)}else{ae=Math.max(I,(q.width-ne*t.scale)/2);const e=oe*t.scale*ie;se=Math.max(K,(q.height-e)/ie/2)}Number.isNaN(ae)&&(ae=I),Number.isNaN(se)&&(se=K),e.useEffect(()=>{const e=e=>{(W||l)(e,t)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),e.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const r=Math.max(5,t.scaleToFit);let n=Math.min(.1,t.scaleToFit);H&&ne>0&&Number.isFinite(ne)&&(n=Math.max(n,300/ne)),n=Math.max(n,.01);const o=.03,l=a(e.deltaY<0?t.scale*(1+o):t.scale/(1+o),n,r);return void t.setScale(l)}},r=U.current;return null==r||r.addEventListener("wheel",e),()=>null==r?void 0:r.removeEventListener("wheel",e)},[H,ne,t]),e.useEffect(()=>{const e=U.current;if(!e){return}const r=e=>{2===e.touches.length&&(Z.current=s(e.touches[0],e.touches[1]))},n=r=>{if(2===r.touches.length&&Z.current>0){r.preventDefault();const n=s(r.touches[0],r.touches[1]),o=n/Z.current,l=Math.max(5,t.scaleToFit);let i=Math.min(.1,t.scaleToFit);H&&ne>0&&Number.isFinite(ne)&&(i=Math.max(i,300/ne)),i=Math.max(i,.01);const c=t.scale,u=a(c*o,i,l),d=u/c,h=e.getBoundingClientRect(),g=(r.touches[0].clientX+r.touches[1].clientX)/2-h.left,p=(r.touches[0].clientY+r.touches[1].clientY)/2-h.top,f=e.scrollLeft+g,m=e.scrollTop+p;fe.current=!0,t.setScale(u),e.scrollLeft=f*d-g,e.scrollTop=m*d-p,Z.current=n}},o=()=>{Z.current=0};return e.addEventListener("touchstart",r,{passive:!0}),e.addEventListener("touchmove",n,{passive:!1}),e.addEventListener("touchend",o,{passive:!0}),()=>{e.removeEventListener("touchstart",r),e.removeEventListener("touchmove",n),e.removeEventListener("touchend",o)}},[H,ne,t]);const ce=void 0!==G,ue=t.pages.map(e=>{if(H){const r=(e.computedWidth+2*$)*t.scale;return ce?r+G:r+2*ae}{const r=(e.computedHeight+2*$)*t.scale;return ce?r+G:r+2*se}}),de=[];let he=ce?H?ae:se:0;for(let e=0;e<ue.length;e++){de.push(he),he+=ue[e]}const ge=ue.reduce((e,t)=>e+t,0),pe=ce?ge+(H?2*ae:2*se):ge,fe=e.useRef(!1),[,me]=e.useReducer(e=>e+1,0);((t,r,n,o,l,i)=>{const a=e.useRef(r),s=e.useRef(0),c=e.useRef(!1),u=e.useRef(o.pages.length);c.current=u.current!==o.pages.length,u.current=o.pages.length,e.useEffect(()=>{const e=t.current,r=t=>{s.current=i?e.scrollLeft:e.scrollTop};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[i]),e.useLayoutEffect(()=>{if(!t.current){return}if(c.current){return}const e=t.current,n=i?e.offsetWidth:e.offsetHeight,o=(s.current+n/2)/a.current;l.current=!0;const u=o*r-n/2;i?e.scrollLeft=u:e.scrollTop=u,a.current=r},[n,r,i])})(U,pe,t.scale,t,fe,H);const{handleScroll:ve}=((t,r,n,o,l,i,a,s,c)=>{const u=e.useRef(!1),d=e.useRef(null),h=e.useRef(!1),g="horizontal"===s;e.useEffect(()=>{const e=t.current,r=()=>{i.current};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[]);const p=o.pages.indexOf(o.activePage);return e.useLayoutEffect(()=>{if(a){return}if(!o.activePage){return}if(!t.current){return}if(u.current){return}const e=t.current,l=o.pages.indexOf(o.activePage),i=r[l]||0,s=g?e.scrollLeft:e.scrollTop,d=n[l]||n[0]||0;let p=()=>{};return(Math.abs(i-s)>.5*d||h.current)&&(h.current=!0,p=(({element:e,scrollTop:t,scrollLeft:r,duration:n=300,onFinish:o=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,a=l?t:r,s=a-i;let c=0,u=!1;if(0===n){return l?e.scrollTop=a:e.scrollLeft=a,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,s,n);l?e.scrollTop=t:e.scrollLeft=t,c<n?setTimeout(d,20):o()},h=(e,t,r,n)=>(e/=n/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:e},g?{scrollLeft:i}:{scrollTop:i}),{onFinish:()=>{h.current=!1,null==c||c()},duration:o.isPlaying?0:300}))),p},[o.activePage,p,o.isPlaying,a,s,r,n]),{handleScroll:e=>{if(a){return}if(h.current){return}u.current=!0,clearTimeout(d.current),d.current=setTimeout(()=>{u.current=!1},300);const t=(g?e.currentTarget.scrollLeft:e.currentTarget.scrollTop)+(g?l.width:l.height)/3;let n=0;for(let o=r.length-1;o>=0;o--){if(t>=r[o]){n=o;break}}const i=o.pages[n];i&&o.activePage!==i&&i.select()}}})(U,de,ue,t,q,fe,D,i,me),be=q.width>=ne*t.scale+2*ae,we=q.height>=oe*t.scale+2*se,xe=g||"rgba(232, 232, 232, 0.9)",ke=(null==O?void 0:O.NoPages)||c,Ee=H?q.width:q.height,Te=U.current?H?U.current.scrollLeft:U.current.scrollTop:0,ye=e=>{for(let t=de.length-1;t>=0;t--){if(e>=de[t]){return t}}return 0},Le=Math.max(0,ye(Te)),Se=Math.min(t.pages.length-1,ye(Te+Ee)),Ce=null!=Y?Y:1,Me=Math.max(0,Le-Ce),Pe=Math.min(t.pages.length-1,Se+Ce);return e.createElement("div",{ref:Q,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:xe,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container"},e.createElement("div",{ref:U,onScroll:ve,style:Object.assign({position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:H?"row":"column",overflow:"auto",overflowX:H?"auto":be?"hidden":"auto",overflowY:H&&we?"hidden":"auto"},ce&&{paddingTop:H?0:se,paddingBottom:H?0:se,paddingLeft:H?ae:0,paddingRight:H?ae:0,boxSizing:"border-box"}),className:"polotno-workspace-inner"},t.pages.map((n,o)=>{const l=n===t.activePage;if(D&&!l&&!n._exportingOrRendering&&!n._forceMount){return null}const a=l||o>=Me&&o<=Pe||n._exportingOrRendering||n._forceMount,s=H?ue[o]:ne*t.scale+2*ae,c=H?oe*t.scale+2*se:ue[o];if(!a){return e.createElement("div",{key:n.id,style:{flexShrink:0}},e.createElement(u,{width:s,height:c,backgroundColor:xe,xPadding:ae,yPadding:se}))}const g=e.createElement(r,{key:n.id,page:n,xPadding:ae,yPadding:se,width:s,height:c,store:t,pageControlsEnabled:h,backColor:xe,pageBorderColor:p||"lightgrey",activePageBorderColor:f||"rgb(0, 161, 255)",altCloneEnabled:_,bleedColor:m||"rgba(255, 0, 0, 0.1)",selectionRectFill:x,selectionRectStroke:k,selectionRectStrokeWidth:E,snapGuideStroke:v||"rgb(0, 161, 255)",snapGuideStrokeWidth:b||1,snapGuideDash:w||d,transformLabelFill:T,transformLabelTextFill:y,distanceGuideStroke:L||"rgb(0, 161, 255)",distanceLabelFill:S||"rgb(0, 161, 255)",distanceLabelTextFill:C||"white",components:O,viewportSize:q,layout:i,tooltipSafeArea:X});return(n._exportingOrRendering||n._forceMount)&&!l&&D?e.createElement("div",{style:{display:"none",flexShrink:0},key:n.id},g):g}),t.rulesVisible&&e.createElement(n,{store:t,xPadding:ae,yPadding:se,width:ne*t.scale+2*ae,height:oe*t.scale+2*se,pageSizes:ue,layout:i,renderOnlyActivePage:D,rulerBackgroundColor:M,rulerTextColor:P,rulerBorderColor:R,rulerBorderSize:F,rulerTickColor:z,rulerTickSize:B}),0===t.pages.length&&e.createElement(ke,{store:t}),t.audios.map(r=>e.createElement(o,{key:r.id,audio:r,store:t}))))});export default WorkspaceCanvas;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polotno",
3
- "version": "2.36.4",
3
+ "version": "2.36.6",
4
4
  "description": "Design Editor Framework",
5
5
  "author": "Anton Lavrenov",
6
6
  "keywords": [
@@ -1 +1 @@
1
- import e from"react";import{observer as t}from"mobx-react-lite";import{ElementTrack as n,ELEMENT_ROW_HEIGHT as r}from"./element-track.js";import{forEveryChild as a}from"../model/group-model.js";export const ElementsTimeline=t(({store:t,scale:o,width:l})=>{const i=t.pages.slice();if(!i.length){return null}const s=i.flatMap(e=>(e=>{const t=[];for(const n of e.children){"group"===n.type?a(n,e=>{"group"!==e.type&&t.push(e)}):t.push(n)}return t})(e).map(t=>({element:t,page:e})));if(!s.length){return null}const m=(e=>{const t=[],n=[];return e.map(({element:e,page:t})=>{const n=((e,t)=>{var n,r;const a=t.duration,o=e.animations.find(e=>"enter"===e.type),l=e.animations.find(e=>"exit"===e.type),i=Math.max(0,Math.min(a,null!==(n=null==o?void 0:o.delay)&&void 0!==n?n:0));return{start:i,end:Math.max(i+50,Math.min(a,a-(null!==(r=null==l?void 0:l.delay)&&void 0!==r?r:0)))}})(e,t);return{element:e,page:t,start:t.startTime+n.start,end:t.startTime+n.end}}).sort((e,t)=>e.start-t.start).forEach(e=>{if(e.end-e.start<50){return}let r=0;for(;r<n.length&&n[r]>e.start;){r++}t.push({element:e.element,page:e.page,row:r,start:e.start,end:e.end}),n[r]=e.end}),t})(s);if(!m.length){return null}const p=(m.reduce((e,t)=>Math.max(e,t.row),-1)+1)*r;return e.createElement("div",{style:{position:"relative",minWidth:l+"px",height:p+"px",marginTop:"12px"},className:"polotno-elements-container"},m.map(({element:r,row:a,page:l})=>e.createElement(n,{key:`${l.id}-${r.id}`,element:r,store:t,page:l,scale:o,row:a})))});
1
+ import e from"react";import{observer as t}from"mobx-react-lite";import{ElementTrack as n,ELEMENT_ROW_HEIGHT as r}from"./element-track.js";import{forEveryChild as a}from"../model/group-model.js";export const ElementsTimeline=t(({store:t,scale:l,width:o})=>{const i=t.pages.slice();if(!i.length){return null}const s=i.flatMap(e=>(e=>{const t=[];for(const n of e.children){"group"===n.type?a(n,e=>{"group"!==e.type&&t.push(e)}):t.push(n)}return t})(e).map(t=>({element:t,page:e}))).filter(({element:e})=>e.selectable||"admin"===t.role);if(!s.length){return null}const m=(e=>{const t=[],n=[];return e.map(({element:e,page:t})=>{const n=((e,t)=>{var n,r;const a=t.duration,l=e.animations.find(e=>"enter"===e.type),o=e.animations.find(e=>"exit"===e.type),i=Math.max(0,Math.min(a,null!==(n=null==l?void 0:l.delay)&&void 0!==n?n:0));return{start:i,end:Math.max(i+50,Math.min(a,a-(null!==(r=null==o?void 0:o.delay)&&void 0!==r?r:0)))}})(e,t);return{element:e,page:t,start:t.startTime+n.start,end:t.startTime+n.end}}).sort((e,t)=>e.start-t.start).forEach(e=>{if(e.end-e.start<50){return}let r=0;for(;r<n.length&&n[r]>e.start;){r++}t.push({element:e.element,page:e.page,row:r,start:e.start,end:e.end}),n[r]=e.end}),t})(s);if(!m.length){return null}const p=(m.reduce((e,t)=>Math.max(e,t.row),-1)+1)*r;return e.createElement("div",{style:{position:"relative",minWidth:o+"px",height:p+"px",marginTop:"12px"},className:"polotno-elements-container"},m.map(({element:r,row:a,page:o})=>e.createElement(n,{key:`${o.id}-${r.id}`,element:r,store:t,page:o,scale:l,row:a})))});