polotno 2.40.0 → 2.40.2

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{autorun as o}from"mobx";import{Group as n,Rect as i,Line as r}from"react-konva";import{Html as s}from"react-konva-utils";import{isTouchDevice as l}from"../utils/screen.js";import{TextElement as a}from"./text-element.js";export const TableElement=e(({element:e,store:c})=>{const d=t.useRef(null),h=t.useRef(null),g=e.selectable||"admin"===c.role,u=l(),y=e.isSelected,f=e._focusedCellIds.length>0,w=e.editingCell;t.useEffect(()=>{y||e.clearCellFocus()},[y]);const p=null==w?void 0:w._editModeEnabled;t.useEffect(()=>{e._editingCellId&&w&&!w._editModeEnabled&&e.exitCellEdit()},[p]),t.useEffect(()=>{f&&!e._editingCellId&&setTimeout(()=>{var t;return null===(t=h.current)||void 0===t?void 0:t.focus()},0)},[f,e._editingCellId]),t.useEffect(()=>o(()=>{e._fitRowsToContent&&c.history.ignore(()=>{e._applyFitRowsToContent()})}),[e,c]);const m=t=>{const o=t.target.getStage();if(!o){return}const n=o.getPointerPosition();if(!n){return}const i=d.current;if(!i){return}const r=i.getAbsoluteTransform().copy().invert().point(n);for(const s of e.visibleCells){const t=e.getCellRect(s.row,s.col,s.rowSpan,s.colSpan);if(r.x>=t.x&&r.x<=t.x+t.width&&r.y>=t.y&&r.y<=t.y+t.height){return s}}},x=(t,e)=>"dashed"===t?[4*e,2*e]:"dotted"===t?[e,e]:void 0,b=[];for(const o of e.visibleCells){const n=e.getCellRect(o.row,o.col,o.rowSpan,o.colSpan);if(0===o.row){const e=o.getEffectiveBorder("top");"none"!==e.style&&e.width>0&&b.push(t.createElement(r,{key:`bt-${o.id}`,points:[n.x,n.y+e.width/2,n.x+n.width,n.y+e.width/2],stroke:e.color,strokeWidth:e.width,dash:x(e.style,e.width),listening:!1}))}if(0===o.col){const e=o.getEffectiveBorder("left");"none"!==e.style&&e.width>0&&b.push(t.createElement(r,{key:`bl-${o.id}`,points:[n.x+e.width/2,n.y,n.x+e.width/2,n.y+n.height],stroke:e.color,strokeWidth:e.width,dash:x(e.style,e.width),listening:!1}))}{const e=o.getEffectiveBorder("bottom");"none"!==e.style&&e.width>0&&b.push(t.createElement(r,{key:`bb-${o.id}`,points:[n.x,n.y+n.height-e.width/2,n.x+n.width,n.y+n.height-e.width/2],stroke:e.color,strokeWidth:e.width,dash:x(e.style,e.width),listening:!1}))}{const e=o.getEffectiveBorder("right");"none"!==e.style&&e.width>0&&b.push(t.createElement(r,{key:`br-${o.id}`,points:[n.x+n.width-e.width/2,n.y,n.x+n.width-e.width/2,n.y+n.height],stroke:e.color,strokeWidth:e.width,dash:x(e.style,e.width),listening:!1}))}}return t.createElement(t.Fragment,null,t.createElement(i,{id:e.id,name:"element",x:e.a.x,y:e.a.y,rotation:e.a.rotation,width:e.a.width,height:e.a.height,fill:"transparent",opacity:e.a.opacity,hideInExport:!e.showInExport,listening:g,draggable:u?e.draggable&&y:e.draggable,onClick:t=>{if(!y){return}if(e.locked||!e.contentEditable){return}const o=m(t);o&&(t.evt.shiftKey&&f?(t.cancelBubble=!0,e.focusCellRange(o.row,o.col)):e.focusCell(o.id))},onDblClick:t=>{if(!y){return}if(e.locked||!e.contentEditable){return}const o=m(t);o&&e.enterCellEdit(o.id)},onDragMove:t=>{var o;const n=t.target;e.set({x:n.x(),y:n.y()}),null===(o=d.current)||void 0===o||o.position({x:n.x(),y:n.y()})},onDragEnd:t=>{const o=t.target;e.set({x:o.x(),y:o.y()})},onTransformStart:()=>{e._setIsTransforming(!0)},onTransformEnd:()=>{e._setIsTransforming(!1),e._resetBaseRowHeights()},onTransform:t=>{var o,n;const i=t.target,r=i.scaleX(),s=i.scaleY();i.scaleX(1),i.scaleY(1);const l=e.width*r,a=e.height*s;i.width(l),i.height(a);const c=i.x(),h=i.y(),g=i.rotation();null===(o=d.current)||void 0===o||o.position({x:c,y:h}),null===(n=d.current)||void 0===n||n.rotation(g),e.set({width:l,height:a,x:c,y:h,rotation:g})}}),t.createElement(n,{ref:d,x:e.a.x,y:e.a.y,rotation:e.a.rotation,opacity:e.a.opacity,hideInExport:!e.showInExport,scaleX:e.a.width/e.width,scaleY:e.a.height/e.height},e.visibleCells.map(o=>{const n=e.getCellRect(o.row,o.col,o.rowSpan,o.colSpan);return"transparent"===o.cellBackground?null:t.createElement(i,{key:`bg-${o.id}`,x:n.x,y:n.y,width:n.width,height:n.height,fill:o.cellBackground,listening:!1})}),b,e.visibleCells.map(e=>t.createElement(a,{key:`text-${e.id}`,element:e,store:c})),e._focusedCellIds.map(o=>{const n=e.cells.find(t=>t.id===o);if(!n){return null}const r=e.getCellRect(n.row,n.col,n.rowSpan,n.colSpan);return t.createElement(i,{key:`focus-${o}`,x:r.x,y:r.y,width:r.width,height:r.height,fill:"rgba(13, 131, 221, 0.1)",stroke:"#0d83dd",strokeWidth:2,listening:!1})}),f&&!w&&t.createElement(s,null,t.createElement("input",{ref:h,style:{position:"absolute",opacity:0,width:"1px",height:"1px",pointerEvents:"none"},readOnly:!0})),y&&!w&&!c.isPlaying&&(()=>{const o=[];let n=0;for(let i=0;i<e.cols-1;i++){n+=e.colWidths[i]*e.a.width;const s=n,l=i;o.push(t.createElement(r,{key:`col-resize-${i}`,x:s,points:[0,0,0,e.a.height],stroke:"transparent",strokeWidth:1,hitStrokeWidth:16,draggable:!0,onMouseEnter:t=>{var e;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.container();o&&(o.style.cursor="col-resize")},onMouseLeave:t=>{var e;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.container();o&&(o.style.cursor="")},onDragStart:t=>{t.cancelBubble=!0,c.history.startTransaction()},onDragMove:t=>{t.cancelBubble=!0;const o=t.target,n=(o.x()-s)/e.width;o.x(s),e.resizeColumn(l,n)},onDragEnd:t=>{t.cancelBubble=!0,t.target.x(s),c.history.endTransaction()}}))}return o})(),y&&!w&&!c.isPlaying&&(()=>{const o=[];let n=0;for(let i=0;i<e.rows-1;i++){n+=e.rowHeights[i]*e.a.height;const s=n,l=i;o.push(t.createElement(r,{key:`row-resize-${i}`,y:s,points:[0,0,e.a.width,0],stroke:"transparent",strokeWidth:1,hitStrokeWidth:16,draggable:!0,onMouseEnter:t=>{var e;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.container();o&&(o.style.cursor="row-resize")},onMouseLeave:t=>{var e;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.container();o&&(o.style.cursor="")},onDragStart:t=>{t.cancelBubble=!0,e._setIsResizingRows(!0),c.history.startTransaction()},onDragMove:t=>{t.cancelBubble=!0;const o=t.target,n=(o.y()-s)/e.height;o.y(s),e.resizeRow(l,n)},onDragEnd:t=>{t.cancelBubble=!0,t.target.y(s),e._setIsResizingRows(!1),e._resetBaseRowHeights(),c.history.endTransaction()}}))}return o})()))});
1
+ import e from"react";import{observer as t}from"mobx-react-lite";import{autorun as o,observable as n,runInAction as i}from"mobx";import{Group as r,Rect as l,Line as s,Circle as a}from"react-konva";import{Html as c}from"react-konva-utils";import{ROLES as h}from"../model/store.js";import{isTouchDevice as d}from"../utils/screen.js";import{TextElement as g}from"./text-element.js";const u="#0d83dd",w=(e,t)=>{const o=e.target.getStage();o&&(o.container().style.cursor=t)},y=t(({axis:t,hovered:o,pillX:n,pillY:i,pillW:r,pillH:s,hitX:a,hitY:c,hitW:h,hitH:d,tint:g,hoverKind:y,idx:p,onSelect:f,onHoverChange:m})=>e.createElement(e.Fragment,null,o&&e.createElement(l,{x:g.x,y:g.y,width:g.width,height:g.height,fill:"rgba(13, 131, 221, 0.08)",listening:!1}),e.createElement(l,{x:n,y:i,width:r,height:s,cornerRadius:Math.min(r,s)/2,fill:o?u:"#9ca3af",opacity:o?.55:.18,listening:!1}),e.createElement(l,{x:a,y:c,width:h,height:d,fill:"transparent",onMouseEnter:e=>{m({kind:y,idx:p}),w(e,"pointer")},onMouseLeave:e=>{m(null),w(e,"")},onClick:f}))),p=t(({x:t,y:o,hovered:n,hoverKind:i,idx:c,isTouch:h,sizes:d,onInsert:g,onHoverChange:y})=>{const{hit:p,r:f,halo:m,stroke:x}=d,v=n||h;return e.createElement(r,{x:t,y:o,onMouseEnter:e=>{y({kind:i,idx:c}),w(e,"pointer")},onMouseLeave:e=>{y(null),w(e,"")},onClick:e=>{e.cancelBubble=!0,g()}},e.createElement(l,{x:-p/2,y:-p/2,width:p,height:p,fill:"transparent"}),v&&e.createElement(e.Fragment,null,e.createElement(a,{radius:f+m,fill:"white",listening:!1}),e.createElement(a,{radius:f,fill:u,listening:!1}),e.createElement(s,{points:[.55*-f,0,.55*f,0],stroke:"white",strokeWidth:x,lineCap:"round",listening:!1}),e.createElement(s,{points:[0,.55*-f,0,.55*f],stroke:"white",strokeWidth:x,lineCap:"round",listening:!1})))}),f=t(({element:t,store:o,inv:n,isTouch:i,hover:r,setHover:l})=>{const s=16*n,a=2*n,c=10*n,h={hit:22*n,r:7*n,halo:2*n,stroke:2*n},d=(e,t)=>null!==r&&r.kind===e&&r.idx===t,g=(e,o)=>n=>{n.cancelBubble=!0;const i=t._anchorCellId?t.cells.find(e=>e.id===t._anchorCellId):void 0;n.evt.shiftKey&&i?"col"===e?t.selectColumnRange(i.col,o):t.selectRowRange(i.row,o):"col"===e?t.selectColumn(o):t.selectRow(o)},u=[0],w=[0];for(let e=0;e<t.cols;e++){u.push(u[e]+t.colWidths[e]*t.a.width)}for(let e=0;e<t.rows;e++){w.push(w[e]+t.rowHeights[e]*t.a.height)}const f=[];for(let p=0;p<t.cols;p++){const o=Math.max(0,u[p+1]-u[p]-6);o<=0||f.push(e.createElement(y,{key:`col-pill-${p}`,axis:"col",hovered:d("colSelect",p),pillX:u[p]+3,pillY:-a-c,pillW:o,pillH:a,hitX:u[p]+1,hitY:-s-c+a,hitW:o+4,hitH:s,tint:{x:u[p],y:0,width:u[p+1]-u[p],height:t.a.height},hoverKind:"colSelect",idx:p,onSelect:g("col",p),onHoverChange:l}))}for(let y=0;y<=t.cols;y++){f.push(e.createElement(p,{key:`col-insert-${y}`,x:u[y],y:-c-a/2,hovered:d("colInsert",y),hoverKind:"colInsert",idx:y,isTouch:i,sizes:h,onInsert:()=>o.history.transaction(()=>t.addColumn(y)),onHoverChange:l}))}for(let p=0;p<t.rows;p++){const o=Math.max(0,w[p+1]-w[p]-6);o<=0||f.push(e.createElement(y,{key:`row-pill-${p}`,axis:"row",hovered:d("rowSelect",p),pillX:-a-c,pillY:w[p]+3,pillW:a,pillH:o,hitX:-s-c+a,hitY:w[p]+1,hitW:s,hitH:o+4,tint:{x:0,y:w[p],width:t.a.width,height:w[p+1]-w[p]},hoverKind:"rowSelect",idx:p,onSelect:g("row",p),onHoverChange:l}))}for(let y=0;y<=t.rows;y++){f.push(e.createElement(p,{key:`row-insert-${y}`,x:-c-a/2,y:w[y],hovered:d("rowInsert",y),hoverKind:"rowInsert",idx:y,isTouch:i,sizes:h,onInsert:()=>o.history.transaction(()=>t.addRow(y)),onHoverChange:l}))}return e.createElement(e.Fragment,null,f)});export const TableElement=t(({element:t,store:a})=>{const u=e.useRef(null),w=e.useRef(null),y=t.selectable||a.role===h.ADMIN,p=d(),m=t.isSelected,x=t._focusedCellIds.length>0,v=t.editingCell,E=1/Math.max(.01,a.scale),[k,b]=e.useState(null);e.useEffect(()=>{m||(t.clearCellFocus(),b(null))},[m]);const C=null==v?void 0:v._editModeEnabled;e.useEffect(()=>{t._editingCellId&&v&&!v._editModeEnabled&&t.exitCellEdit()},[C]),e.useEffect(()=>{x&&!t._editingCellId&&setTimeout(()=>{var e;return null===(e=w.current)||void 0===e?void 0:e.focus()},0)},[x,t._editingCellId]);const S=e.useMemo(()=>n.box(!1),[]);e.useEffect(()=>o(()=>{S.get()||t._fitRowsToContent&&a.history.ignore(()=>{t._applyFitRowsToContent()})}),[t,a,S]);const I=e=>{const o=e.target.getStage();if(!o){return}const n=o.getPointerPosition();if(!n){return}const i=u.current;if(!i){return}const r=i.getAbsoluteTransform().copy().invert().point(n);for(const l of t.visibleCells){const e=t.getCellRect(l.row,l.col,l.rowSpan,l.colSpan);if(r.x>=e.x&&r.x<=e.x+e.width&&r.y>=e.y&&r.y<=e.y+e.height){return l}}},H=(e,t)=>"dashed"===e?[4*t,2*t]:"dotted"===e?[t,t]:void 0,M=[];for(const o of t.visibleCells){const n=t.getCellRect(o.row,o.col,o.rowSpan,o.colSpan),i=0===o.row,r=o.row+o.rowSpan===t.rows,l=0===o.col,a=o.col+o.colSpan===t.cols;if(0===o.row){const t=o.getEffectiveBorder("top");if("none"!==t.style&&t.width>0){const i=n.y+t.width/2,r=n.x-(l?0:t.width/2),c=n.x+n.width+(a?0:t.width/2);M.push(e.createElement(s,{key:`bt-${o.id}`,points:[r,i,c,i],stroke:t.color,strokeWidth:t.width,dash:H(t.style,t.width),listening:!1}))}}if(0===o.col){const t=o.getEffectiveBorder("left");if("none"!==t.style&&t.width>0){const l=n.x+t.width/2,a=n.y-(i?0:t.width/2),c=n.y+n.height+(r?0:t.width/2);M.push(e.createElement(s,{key:`bl-${o.id}`,points:[l,a,l,c],stroke:t.color,strokeWidth:t.width,dash:H(t.style,t.width),listening:!1}))}}{const t=o.getEffectiveBorder("bottom");if("none"!==t.style&&t.width>0){const i=r?n.y+n.height-t.width/2:n.y+n.height,c=n.x-(l?0:t.width/2),h=n.x+n.width+(a?0:t.width/2);M.push(e.createElement(s,{key:`bb-${o.id}`,points:[c,i,h,i],stroke:t.color,strokeWidth:t.width,dash:H(t.style,t.width),listening:!1}))}}{const t=o.getEffectiveBorder("right");if("none"!==t.style&&t.width>0){const l=a?n.x+n.width-t.width/2:n.x+n.width,c=n.y-(i?0:t.width/2),h=n.y+n.height+(r?0:t.width/2);M.push(e.createElement(s,{key:`br-${o.id}`,points:[l,c,l,h],stroke:t.color,strokeWidth:t.width,dash:H(t.style,t.width),listening:!1}))}}}return e.createElement(e.Fragment,null,e.createElement(l,{id:t.id,name:"element",x:t.a.x,y:t.a.y,rotation:t.a.rotation,width:t.a.width,height:t.a.height,fill:"transparent",opacity:t.a.opacity,hideInExport:!t.showInExport,listening:y,draggable:p?t.draggable&&m:t.draggable,onClick:e=>{if(!m){return}if(t.locked||!t.contentEditable){return}const o=I(e);o&&(e.evt.shiftKey&&x?(e.cancelBubble=!0,t.focusCellRange(o.row,o.col)):t.focusCell(o.id))},onDblClick:e=>{if(!m){return}if(t.locked||!t.contentEditable){return}const o=I(e);o&&t.enterCellEdit(o.id)},onDragMove:e=>{var o;const n=e.target;t.set({x:n.x(),y:n.y()}),null===(o=u.current)||void 0===o||o.position({x:n.x(),y:n.y()})},onDragEnd:e=>{const o=e.target;t.set({x:o.x(),y:o.y()})},onTransformStart:()=>{i(()=>S.set(!0))},onTransformEnd:()=>{t._resetBaseRowHeights(),i(()=>S.set(!1))},onTransform:e=>{var o,n;const i=e.target,r=i.scaleX(),l=i.scaleY();i.scaleX(1),i.scaleY(1);const s=t.width*r,a=t.height*l;i.width(s),i.height(a);const c=i.x(),h=i.y(),d=i.rotation();null===(o=u.current)||void 0===o||o.position({x:c,y:h}),null===(n=u.current)||void 0===n||n.rotation(d),t.set({width:s,x:c,y:h,rotation:d}),t.setHeightRedistribute(a)}}),e.createElement(r,{ref:u,x:t.a.x,y:t.a.y,rotation:t.a.rotation,opacity:t.a.opacity,hideInExport:!t.showInExport,scaleX:t.a.width/t.width,scaleY:t.a.height/t.height},t.visibleCells.map(o=>{const n=t.getCellRect(o.row,o.col,o.rowSpan,o.colSpan);return"transparent"===o.cellBackground?null:e.createElement(l,{key:`bg-${o.id}`,x:n.x,y:n.y,width:n.width,height:n.height,fill:o.cellBackground,listening:!1})}),M,t.visibleCells.map(t=>e.createElement(g,{key:`text-${t.id}`,element:t,store:a})),m&&t._focusedCellIds.map(o=>{const n=t.cells.find(e=>e.id===o);if(!n){return null}const i=t.getCellRect(n.row,n.col,n.rowSpan,n.colSpan),r=2*E;return e.createElement(l,{key:`focus-${o}`,x:i.x,y:i.y,width:i.width,height:i.height,fill:"rgba(13, 131, 221, 0.1)",stroke:"#0d83dd",strokeWidth:r,listening:!1})}),x&&!v&&e.createElement(c,null,e.createElement("input",{ref:w,style:{position:"absolute",opacity:0,width:"1px",height:"1px",pointerEvents:"none"},readOnly:!0})),m&&!v&&!a.isPlaying&&(()=>{const o=[];let n=0;for(let i=0;i<t.cols-1;i++){n+=t.colWidths[i]*t.a.width;const r=n,l=i;o.push(e.createElement(s,{key:`col-resize-${i}`,x:r,points:[0,0,0,t.a.height],stroke:"transparent",strokeWidth:1,hitStrokeWidth:16,draggable:!0,onMouseEnter:e=>{var t;const o=null===(t=e.target.getStage())||void 0===t?void 0:t.container();o&&(o.style.cursor="col-resize"),b({kind:"colInsert",idx:l+1})},onMouseLeave:e=>{var t;const o=null===(t=e.target.getStage())||void 0===t?void 0:t.container();o&&(o.style.cursor=""),b(null)},onDragStart:e=>{e.cancelBubble=!0,a.history.startTransaction()},onDragMove:e=>{e.cancelBubble=!0;const o=e.target,n=(o.x()-r)/t.width;o.x(r),t.resizeColumn(l,n)},onDragEnd:e=>{e.cancelBubble=!0,e.target.x(r),a.history.endTransaction()}}))}return o})(),m&&!v&&!a.isPlaying&&(()=>{const o=[];let n=0;for(let r=0;r<t.rows-1;r++){n+=t.rowHeights[r]*t.a.height;const l=n,c=r;o.push(e.createElement(s,{key:`row-resize-${r}`,y:l,points:[0,0,t.a.width,0],stroke:"transparent",strokeWidth:1,hitStrokeWidth:16,draggable:!0,onMouseEnter:e=>{var t;const o=null===(t=e.target.getStage())||void 0===t?void 0:t.container();o&&(o.style.cursor="row-resize"),b({kind:"rowInsert",idx:c+1})},onMouseLeave:e=>{var t;const o=null===(t=e.target.getStage())||void 0===t?void 0:t.container();o&&(o.style.cursor=""),b(null)},onDragStart:e=>{e.cancelBubble=!0,i(()=>S.set(!0)),a.history.startTransaction()},onDragMove:e=>{e.cancelBubble=!0;const o=e.target,n=(o.y()-l)/t.height;o.y(l),t.resizeRow(c,n)},onDragEnd:e=>{e.cancelBubble=!0,e.target.y(l),t._resetBaseRowHeights(),i(()=>S.set(!1)),a.history.endTransaction()}}))}return o})(),m&&!v&&!a.isPlaying&&e.createElement(f,{element:t,store:a,inv:E,isTouch:p,hover:k,setHover:b})))});
@@ -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{generateBackgroundShapeFromRects as u,textLinesToRects as f}from"../utils/background-shape.js";import{useColor as h}from"./use-color.js";import{useWorkspaceStyle as g}from"./workspace-style.js";import{incrementLoader as m}from"../utils/loader.js";import{isFontLoaded as p}from"../utils/fonts.js";import{flags as x}from"../utils/flags.js";import{removeTags as w}from"../utils/text.js";import{getDir as v,getCurvePath as y,resolveLineHeight as S}from"../utils/text-html.js";import{applyFilter as E}from"./apply-filters.js";import{useFadeIn as b}from"./use-fadein.js";import{isTouchDevice as z}from"../utils/screen.js";import{isAlive as O,getParent as k}from"mobx-state-tree";import{getLimitedFontSize as A}from"./text-element/max-font-size.js";import{getOptimalCaretColor as F}from"./text-element/caret-color.js";let R;function M(){return R||(R=document.getElementById("polotno-text-style"),R||(R=document.createElement("style"),R.id="polotno-text-style",document.head.appendChild(R)),R)}s._fixTextRendering=!0;const C={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 j=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(C),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=F(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=M();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 u=s.textArr.length*s.lineHeight()*s.fontSize();"middle"===n.verticalAlign&&(d=(n.a.height-u)/2),"bottom"===n.verticalAlign&&(d=n.a.height-u);const f=w(n.text);return t.createElement("textarea",{className:"polotno-input",ref:c,dir:v(f),style:Object.assign(Object.assign(Object.assign({},C),a),{paddingTop:d+"px"}),value:f,onChange:t=>{const e=A({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),L=e=>t.createElement(a,null,t.createElement(j,Object.assign({},e)));export const useFontLoader=(e,n,o,r,i)=>{const[a,l]=t.useReducer(t=>t+1,0),s=t.useRef(p(n,o,r)),c=t.useRef(null);return t.useLayoutEffect(()=>{if(s.current=p(n,o,r),s.current){return}let t=!0;return(async()=>{s.current=!1,l();const a=m(`text ${n}`);await e.loadFont(n,o,r,i),t?(c.current=a,s.current=!0,l()):a()})(),()=>{c.current&&(c.current(),c.current=null),t=!1}},[n,o,r]),t.useEffect(()=>{s.current&&setTimeout(()=>{c.current&&(c.current(),c.current=null)})},[s.current]),[s.current]};export const getLineHeight=({fontLoaded:e,fontFamily:n,fontSize:o,lineHeight:r})=>t.useMemo(()=>S({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}function T(t,e,n=!1){const o=t.fontSize(),r=t.height(),i=w(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}export{getCurvePath}from"../utils/text-html.js";export const TextElement=e(({element:e,store:a})=>{const{textOverflowIndicatorStyle:s}=g(),p=t.useRef(null),S=t.useRef(null),A=t.useRef(null),F=t.useRef([]),[,R]=t.useReducer(t=>t+1,0),{editorEnabled:M,selectAll:C}=(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),[j,H]=t.useState(!1),[W,X]=t.useState(!1),Y=t.useRef(e.a.height),P=e.isSelected,B=usePrevious(P),{textVerticalResizeEnabled:D}=x,$=x.autoDeleteEmptyText,N=usePrevious(e.fontFamily),[I,J]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=p.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(I)&&J(n)}),t.useEffect(()=>{if(e.a.width||"tablecell"===e.type){return}const t=p.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{B&&!P&&$&&""===e.text&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[$,e.placeholder,e.removable,e.text,P,B]);const _=()=>{if(e.curveEnabled){const t=p.current;null==t||t.clearCache(),null==t||t.setAttrs({filters:[]});const n=S.current;n&&E(n,e)}else{const t=p.current;t&&E(t,e)}};t.useLayoutEffect(()=>{if(!W){return l(()=>{_()})}}),t.useEffect(()=>{const t=F.current;t.length>0&&(F.current=[],t.forEach(t=>t()))});let V=w(e.text);"uppercase"===e.textTransform&&(V=V.toUpperCase());const[q]=useFontLoader(a,e.fontFamily,e.fontStyle,e.fontWeight,e.text||e.placeholder),U=()=>{if(e.curveEnabled){const t=S.current;return t.getSelfRect().height||t.fontSize()}const t=p.current.clone({height:void 0}),n=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),n};t.useLayoutEffect(()=>{if(!q){return}if("tablecell"===e.type){const{textOverflow:t}=x;if("resize"===t){const t=U(),n=O(e)?k(e,2):null;(null==n?void 0:n.setCellContentHeight)&&n.setCellContentHeight(e.id,t)}else if("change-font-size"===t){const t=p.current;if(t){const n=T(t,e,x.textSplitAllowed);n!==e.fontSize&&a.history.ignore(()=>{e.set({fontSize:n})})}}return}const{textOverflow:t,textSplitAllowed:n}=x,o=(t,n,o,r)=>{const i=m(`text ${e.id}`),l=()=>{a.history.ignore(t,n,o).then(()=>{F.current.push(i),R()})};r?queueMicrotask(l):l()};if(!e.height){const t=U();return void o(()=>{e.height||e.set({height:t})},void 0,void 0,!0)}if(!a.isPlaying){if("change-font-size"!==t||j){if("resize"===t){const t=U();D&&e.height<t&&!j&&o(()=>{var n;O(e)&&e.set({height:t}),null===(n=p.current)||void 0===n||n.height(t)},!1,!0),D||e.height===t||j||o(()=>{var n;O(e)&&e.set({height:t}),null===(n=p.current)||void 0===n||n.height(t)},!1,!0)}}else{const t=T(p.current,e,n);if(t!==e.fontSize){return void o(()=>{e.set({fontSize:t})},!1,!0)}const r=U();e.height===r||D||o(()=>{e.set({height:r})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(q&&e.curveEnabled){const n=null===(t=S.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})}}},[q,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useLayoutEffect(()=>{const t=p.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),_())},[q]);const Z=t.useRef(null),G=t.useRef(0),K=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(G.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())},Q=!V&&e.placeholder?.6:e.a.opacity;b(p,Q);const tt=getLineHeight({fontLoaded:q,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),et=e.selectable||"admin"===a.role,nt=h(e),ot=h(e,e.stroke,"stroke"),rt=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*tt*.5),padding:e.backgroundPadding*(e.a.fontSize*tt*.5)}):function({lines:t,lineHeight:e,width:n,align:o="left",padding:r=0,cornerRadius:i=0}){const a=f({lines:t,lineHeight:e,width:n,align:o});return u({rects:a,padding:r,cornerRadius:i})}({lines:JSON.parse(JSON.stringify(I)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*tt*.5),lineHeight:tt*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*tt*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.curveEnabled,e.backgroundCornerRadius,e.a.fontSize,e.a.height,tt,e.backgroundPadding,e.a.width,e.align,I]),it=z();let at=0;e.curveEnabled||("middle"===e.verticalAlign?at=(e.a.height-I.length*tt*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(at=e.a.height-I.length*tt*e.a.fontSize));const lt=e.curveEnabled?y(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",st=q?'"'+e.fontFamily+'"':N===e.fontFamily?"Arial":'"'+N+'"';return t.createElement(t.Fragment,null,t.createElement(o,{ref:A,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*Q,data:rt,fill:e.backgroundColor,offsetY:-at}),t.createElement(o,{data:lt,stroke:s.stroke,strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:S,visible:e.curveEnabled,data:lt,text:V||e.placeholder,listening:!1,align:"center",textBaseline:"middle"},nt,ot,{strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${N}"`,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:Q,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:p,id:e.selectable?e.id:void 0,name:e.selectable?"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:V||e.placeholder,direction:v(V)},nt,ot,{lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:st,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:it?e.draggable&&P:e.draggable,preventDefault:!it||P,opacity:e.curveEnabled?0:Q,visible:!e._editModeEnabled,ellipsis:"ellipsis"===x.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:tt,letterSpacing:e.letterSpacing*e.a.fontSize,listening:!!e.selectable&&et,onDragStart:()=>{X(!0)},onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{X(!1),e.set({x:t.target.x(),y:t.target.y()})},onClick:K,onTap:K,onTransformStart:()=>{H(!0),Y.current=p.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=A.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,Z.current&&i.position(Z.current)),i.width(r),i.scaleX(1),i.scaleY(1);let a=U();if("ellipsis"===x.textOverflow){a=Y.current}else{const t=Math.max(a,Y.current);i.height(t),e.set({height:i.height()})}const l=x.textVerticalResizeEnabled?Math.max(a,Y.current):U();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),_()}if("top-center"===a||"bottom-center"===a){let n="resize"===x.textOverflow?U():tt*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}Z.current=t.target.position();const l=t.target.scaleX();null===(r=A.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=A.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),H(!1)}})),M&&e.contentEditable&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement(L,{textNodeRef:p,element:e,selectAll:C,cursorPosition:G.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{generateBackgroundShapeFromRects as u,textLinesToRects as f}from"../utils/background-shape.js";import{useColor as h}from"./use-color.js";import{useWorkspaceStyle as g}from"./workspace-style.js";import{ROLES as m}from"../model/store.js";import{incrementLoader as p}from"../utils/loader.js";import{isFontLoaded as x}from"../utils/fonts.js";import{flags as w}from"../utils/flags.js";import{removeTags as v}from"../utils/text.js";import{getDir as S,getCurvePath as y,resolveLineHeight as E}from"../utils/text-html.js";import{applyFilter as b}from"./apply-filters.js";import{useFadeIn as z}from"./use-fadein.js";import{isTouchDevice as O}from"../utils/screen.js";import{isAlive as k,getParent as A}from"mobx-state-tree";import{getLimitedFontSize as F}from"./text-element/max-font-size.js";import{getOptimalCaretColor as R}from"./text-element/caret-color.js";let M;function j(){return M||(M=document.getElementById("polotno-text-style"),M||(M=document.createElement("style"),M.id="polotno-text-style",document.head.appendChild(M)),M)}s._fixTextRendering=!0;const C={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(C),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=R(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=j();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({preventScroll:!0});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 u=s.textArr.length*s.lineHeight()*s.fontSize();"middle"===n.verticalAlign&&(d=(n.a.height-u)/2),"bottom"===n.verticalAlign&&(d=n.a.height-u);const f=v(n.text);return t.createElement("textarea",{className:"polotno-input",ref:c,dir:S(f),style:Object.assign(Object.assign(Object.assign({},C),a),{paddingTop:d+"px"}),value:f,onChange:t=>{const e=F({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),T=e=>t.createElement(a,null,t.createElement(L,Object.assign({},e)));export const useFontLoader=(e,n,o,r,i)=>{const[a,l]=t.useReducer(t=>t+1,0),s=t.useRef(x(n,o,r)),c=t.useRef(null);return t.useLayoutEffect(()=>{if(s.current=x(n,o,r),s.current){return}let t=!0;return(async()=>{s.current=!1,l();const a=p(`text ${n}`);await e.loadFont(n,o,r,i),t?(c.current=a,s.current=!0,l()):a()})(),()=>{c.current&&(c.current(),c.current=null),t=!1}},[n,o,r]),t.useEffect(()=>{s.current&&setTimeout(()=>{c.current&&(c.current(),c.current=null)})},[s.current]),[s.current]};export const getLineHeight=({fontLoaded:e,fontFamily:n,fontSize:o,lineHeight:r})=>t.useMemo(()=>E({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}function H(t,e,n=!1){const o=t.fontSize(),r=t.height(),i=v(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}export{getCurvePath}from"../utils/text-html.js";export const TextElement=e(({element:e,store:a})=>{const{textOverflowIndicatorStyle:s}=g(),x=t.useRef(null),E=t.useRef(null),F=t.useRef(null),R=t.useRef([]),[,M]=t.useReducer(t=>t+1,0),{editorEnabled:j,selectAll:C}=(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),[L,W]=t.useState(!1),[X,Y]=t.useState(!1),P=t.useRef(e.a.height),B=e.isSelected,D=usePrevious(B),{textVerticalResizeEnabled:$}=w,N=w.autoDeleteEmptyText,I=usePrevious(e.fontFamily),[J,_]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=x.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(J)&&_(n)}),t.useEffect(()=>{if(e.a.width||"tablecell"===e.type){return}const t=x.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{D&&!B&&N&&""===e.text&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[N,e.placeholder,e.removable,e.text,B,D]);const V=()=>{if(e.curveEnabled){const t=x.current;null==t||t.clearCache(),null==t||t.setAttrs({filters:[]});const n=E.current;n&&b(n,e)}else{const t=x.current;t&&b(t,e)}};t.useLayoutEffect(()=>{if(!X){return l(()=>{V()})}}),t.useEffect(()=>{const t=R.current;t.length>0&&(R.current=[],t.forEach(t=>t()))});let q=v(e.text);"uppercase"===e.textTransform&&(q=q.toUpperCase());const[U]=useFontLoader(a,e.fontFamily,e.fontStyle,e.fontWeight,e.text||e.placeholder),Z=()=>{if(e.curveEnabled){const t=E.current;return t.getSelfRect().height||t.fontSize()}const t=x.current.clone({height:void 0}),n=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),n};t.useLayoutEffect(()=>{if(!U){return}if("tablecell"===e.type){const{textOverflow:t}=w;if("resize"===t){const t=Z(),n=k(e)?A(e,2):null;(null==n?void 0:n.setCellContentHeight)&&n.setCellContentHeight(e.id,t)}else if("change-font-size"===t){const t=x.current;if(t){const n=H(t,e,w.textSplitAllowed);n!==e.fontSize&&a.history.ignore(()=>{e.set({fontSize:n})})}}return}const{textOverflow:t,textSplitAllowed:n}=w,o=(t,n,o,r)=>{const i=p(`text ${e.id}`),l=()=>{a.history.ignore(t,n,o).then(()=>{R.current.push(i),M()})};r?queueMicrotask(l):l()};if(!e.height){const t=Z();return void o(()=>{e.height||e.set({height:t})},void 0,void 0,!0)}if(!a.isPlaying){if("change-font-size"!==t||L){if("resize"===t){const t=Z();$&&e.height<t&&!L&&o(()=>{var n;k(e)&&e.set({height:t}),null===(n=x.current)||void 0===n||n.height(t)},!1,!0),$||e.height===t||L||o(()=>{var n;k(e)&&e.set({height:t}),null===(n=x.current)||void 0===n||n.height(t)},!1,!0)}}else{const t=x.current,r=e.curveEnabled?e.fontSize:H(t,e,n);if(r!==e.fontSize){return void o(()=>{e.set({fontSize:r})},!1,!0)}const i=Z();e.height===i||$||o(()=>{e.set({height:i})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(U&&e.curveEnabled){const n=null===(t=E.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})}}},[U,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useLayoutEffect(()=>{const t=x.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),V())},[U]);const G=t.useRef(null),K=t.useRef(0),Q=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(K.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())},tt=!q&&e.placeholder?.6:e.a.opacity;z(x,tt);const et=getLineHeight({fontLoaded:U,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),nt=e.selectable||a.role===m.ADMIN,ot=h(e),rt=h(e,e.stroke,"stroke"),it=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*et*.5),padding:e.backgroundPadding*(e.a.fontSize*et*.5)}):function({lines:t,lineHeight:e,width:n,align:o="left",padding:r=0,cornerRadius:i=0}){const a=f({lines:t,lineHeight:e,width:n,align:o});return u({rects:a,padding:r,cornerRadius:i})}({lines:JSON.parse(JSON.stringify(J)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*et*.5),lineHeight:et*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*et*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.curveEnabled,e.backgroundCornerRadius,e.a.fontSize,e.a.height,et,e.backgroundPadding,e.a.width,e.align,J]),at=O();let lt=0;e.curveEnabled||("middle"===e.verticalAlign?lt=(e.a.height-J.length*et*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(lt=e.a.height-J.length*et*e.a.fontSize));const st=e.curveEnabled?y(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",ct=U?'"'+e.fontFamily+'"':I===e.fontFamily?"Arial":'"'+I+'"',dt=S(q);return t.createElement(t.Fragment,null,t.createElement(o,{ref:F,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*tt,data:it,fill:e.backgroundColor,offsetY:-lt}),t.createElement(o,{data:st,stroke:s.stroke,strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:E,visible:e.curveEnabled,data:st,text:q||e.placeholder,listening:!1,align:"center",textBaseline:"middle",direction:dt},ot,rt,{strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${I}"`,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:tt,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:x,id:e.selectable?e.id:void 0,name:e.selectable?"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:q||e.placeholder,direction:dt},ot,rt,{lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:ct,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:at?e.draggable&&B:e.draggable,preventDefault:!at||B,opacity:e.curveEnabled?0:tt,visible:!e._editModeEnabled,ellipsis:"ellipsis"===w.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:et,letterSpacing:e.letterSpacing*e.a.fontSize,listening:!!e.selectable&&nt,onDragStart:()=>{Y(!0)},onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{Y(!1),e.set({x:t.target.x(),y:t.target.y()})},onClick:Q,onTap:Q,onTransformStart:()=>{W(!0),P.current=x.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=F.current)||void 0===n||n.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(o=i.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),n=i.width()*t,o=e.a.fontSize;let r=n;n<o&&(r=o,G.current&&i.position(G.current)),i.width(r),i.scaleX(1),i.scaleY(1);let a=Z();if("ellipsis"===w.textOverflow){a=P.current}else{const t=Math.max(a,P.current);i.height(t),e.set({height:i.height()})}const l=w.textVerticalResizeEnabled?Math.max(a,P.current):Z();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),V()}if("top-center"===a||"bottom-center"===a){let n="resize"===w.textOverflow?Z():et*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}G.current=t.target.position();const l=t.target.scaleX();null===(r=F.current)||void 0===r||r.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.a.fontSize*l,width:t.target.width()*l,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*l,shadowBlur:e.shadowBlur*l,shadowOffsetX:e.shadowOffsetX*l,shadowOffsetY:e.shadowOffsetY*l,strokeWidth:e.strokeWidth*l})},onTransformEnd:t=>{var n;const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:Math.round(e.a.fontSize*o),width:Math.ceil(t.target.width()*o),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*o,shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o}),null===(n=F.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),W(!1)}})),j&&e.contentEditable&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement(T,{textNodeRef:x,element:e,selectAll:C,cursorPosition:K.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
@@ -1 +1 @@
1
- import e from"react";import{observer as t}from"mobx-react-lite";import{autorun as r}from"mobx";import{Arc as n,Group as o,Image as i,Rect as a,Text as d,Transformer as h}from"react-konva";import c from"use-image";import l from"konva";import{Portal as s}from"react-konva-utils";import{useWorkspaceStyle as u}from"./workspace-style.js";import{incrementLoader as g,triggerLoadError as f}from"../utils/loader.js";import*as m from"../utils/svg.js";import{flags as p}from"../utils/flags.js";import{applyFilter as w}from"./apply-filters.js";import{useFadeIn as v}from"./use-fadein.js";import{isTouchDevice as x}from"../utils/screen.js";import{useMediabunnyVideo as M}from"./use-mediabunny-video.js";function E(){return document.createElement("canvas")}const y=new window.Image;y.src=m.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" fill="white"/>\n <path d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');const b=new window.Image;b.src=m.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" fill="white"/>\n <path opacity="0.6" d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" fill="white"/>\n <path d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');export const useCornerRadiusAndCrop=(t,r,n,o,i=0,a=!1)=>{const d=Math.floor(Math.max(t.width*o,1)),h=Math.floor(Math.max(t.height*o,1)),c=Math.min(i*o,d/2,h/2),s=Math.max(t.width/n.width,t.height/n.height)*o,u=t.page._exportingOrRendering&&p.imageDownScalingEnabled&&s<1&&!a,g=r instanceof HTMLVideoElement?r.videoWidth:null==r?void 0:r.width,f=r instanceof HTMLVideoElement?r.videoHeight:null==r?void 0:r.height,m=0===n.x&&0===n.y&&n.width===g&&n.height===f,w=e.useMemo(()=>{if(r&&g&&f){return m&&0===c&&!u?void 0:E()}},[r,c,u,m,g,f]),v=()=>{if(!w||!r){return}w.width=d,w.height=h;const e=w.getContext("2d");if(!e){return}c&&(e.beginPath(),e.moveTo(c,0),e.lineTo(d-c,0),e.arc(d-c,c,c,3*Math.PI/2,0,!1),e.lineTo(d,h-c),e.arc(d-c,h-c,c,0,Math.PI/2,!1),e.lineTo(c,h),e.arc(c,h-c,c,Math.PI/2,Math.PI,!1),e.lineTo(0,c),e.arc(c,c,c,Math.PI,3*Math.PI/2,!1),e.clip());const t=u?function(e,t){var r,n;const o=E(),i=e instanceof HTMLVideoElement?e.videoWidth:e.width,a=e instanceof HTMLVideoElement?e.videoHeight:e.height;o.width=i,o.height=a,null===(r=o.getContext("2d"))||void 0===r||r.drawImage(e,0,0,o.width,o.height);const d=function(e,t,r,n,o,i,a){for(var d=new ImageData(t,r),h=new Int32Array(e.data.buffer),c=e.width,l=new Int32Array(d.data.buffer),s=d.width,u=t/i,g=r/a,f=Math.round(1/u),m=Math.round(1/g),p=f*m,w=0;w<d.height;w++){for(var v=0;v<s;v++){for(var x=0+Math.round(v/u)+(0+Math.round(w/g))*c,M=0,E=0,y=0,b=0,L=0;L<m;L++){for(var T=0;T<f;T++){var C=h[x+T+L*c];M+=C<<24>>>24,E+=C<<16>>>24,y+=C<<8>>>24,b+=C>>>24}}M=Math.round(M/p),E=Math.round(E/p),y=Math.round(y/p),b=Math.round(b/p),l[v+w*s]=b<<24|y<<16|E<<8|M}}return d}(o.getContext("2d").getImageData(0,0,o.width,o.height),Math.floor(o.width*t),Math.floor(o.height*t),0,0,o.width,o.height);return o.width=Math.floor(o.width*t),o.height=Math.floor(o.height*t),null===(n=o.getContext("2d"))||void 0===n||n.putImageData(d,0,0),o}(r,s):r,o=u?{x:Math.floor(n.x*s),y:Math.floor(n.y*s),width:Math.floor(n.width*s),height:Math.floor(n.height*s)}:n;e.drawImage(t,o.x,o.y,o.width,o.height,0,0,w.width,w.height)};return e.useLayoutEffect(()=>{v()},[w,t.width,t.height,n.x,n.y,n.width,n.height,i,o,a,t.page._exportingOrRendering,u]),e.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&l.Util.releaseCanvas(w)},[w]),[w||r,v]};const L=E(),T=t(({element:t})=>{const r=Math.min(30,t.width/4,t.height/4),i=e.useRef(null);e.useEffect(()=>{const e=i.current;if(!e){return}const t=new l.Animation(t=>{e.rotate(((null==t?void 0:t.timeDiff)||0)/2)},e.getLayer());return t.start(),()=>{t.stop()}});const{mediaLoadingStyle:d}=u();return e.createElement(o,{x:t.a.x,y:t.a.y,rotation:t.a.rotation,listening:!1,opacity:t.a.opacity,hideInExport:!t.showInExport},e.createElement(a,{width:t.width,height:t.height,fill:d.fill}),e.createElement(n,{ref:i,x:t.width/2,y:t.height/2,fill:d.textFill,outerRadius:Math.abs(r),innerRadius:Math.max(1,r-5),angle:270}))}),C=t(({element:t})=>{const{mediaErrorStyle:r}=u(),n=Math.max(10,Math.min(30,t.width/25));return e.createElement(o,{x:t.a.x,y:t.a.y,rotation:t.a.rotation,listening:!1,opacity:t.a.opacity,hideInExport:!t.showInExport},e.createElement(a,{width:t.width,height:t.height,fill:r.fill}),e.createElement(d,{text:"Can not load the video...",fontSize:n,width:t.width,height:t.height,align:"center",fill:r.textFill,verticalAlign:"middle",padding:5}))});let R=function(t,r,n){const o=e.useRef("loading"),i=e.useRef(void 0),[a,d]=e.useState(0),h=e.useRef(),c=e.useRef(),l=e.useRef();return h.current===t&&c.current===r&&l.current===n||(o.current="loading",i.current=void 0,h.current=t,c.current=r,l.current=n),e.useLayoutEffect(function(){if(t){var e=document.createElement("video");return e.addEventListener("canplay",a),e.addEventListener("error",h),r&&(e.crossOrigin=r),n&&(e.referrerPolicy=n),e.src=t,e.load(),function(){e.removeEventListener("canplay",a),e.removeEventListener("error",h)}}function a(){o.current="loaded",i.current=e,i.current.currentTime=0,d(Math.random()),i.current.removeEventListener("canplay",a)}function h(t){var r;const n=4===e.readyState,a=e.buffered&&e.buffered.length>0&&e.buffered.end(e.buffered.length-1)/e.duration*100>=100;if(n&&a){return}const h=t.message||(null===(r=e.error)||void 0===r?void 0:r.message)||"Unknown error",c=new Error("Video failed to load: "+h);console.error(c),o.current="failed",i.current=void 0,d(Math.random())}},[t,r,n]),[i.current,o.current]};export const setVideoLoaderHook=e=>{R=e};function S(e){return e.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA}export const useLoader=(t,r,n)=>{const o=e.useRef(),i=()=>{var e;null===(e=o.current)||void 0===e||e.call(o),o.current=void 0};e.useEffect(()=>i,[]),e.useLayoutEffect(()=>{const e=r.slice(0,200),a=`video with id ${n} url: ${e}`;"loading"!==t||o.current||(o.current=g(a)),"loading"!==t&&i(),"failed"===t&&f(a)},[t])};export const VideoElement=t(({element:t,store:n})=>{var d;const[u,f]=e.useState(!1),p=e.useRef(null),I=e.useRef(null),k=t.isSelected,[H,X]=e.useState(!1),[Y,W]=R(t.src,"anonymous"),[O,_]=e.useState(!1),A=n.activePage===t.page,P=t.page._exportingOrRendering&&"loaded"===W,V=M(t,n,P);useLoader(W,t.src,t.id),Y&&(Y.playsInline=!0);const D=((t,r,n)=>{const o=e.useMemo(()=>{var e,o;const{flipX:i,flipY:a}=t,d="svg"===t.type||t.src.indexOf("data:image/svg+xml")>=0||t.src.indexOf(".svg")>=0,h=navigator.userAgent.toLowerCase().indexOf("firefox")>-1;if(!(i||a||h&&d)){return r}if(!r){return null}const c=r instanceof HTMLVideoElement?r.videoWidth:null==r?void 0:r.width,l=r instanceof HTMLVideoElement?r.videoHeight:null==r?void 0:r.height;if(!c||!l){return null}const s=E();let u=1;"svg"===t.type&&(u=Math.max(t.width/c*n,t.height/l*n)),s.width=Math.max(c*u,1),s.height=Math.max(l*u,1);let g=i?-s.width:0,f=a?-s.height:0;return null===(e=s.getContext("2d"))||void 0===e||e.scale(i?-1:1,a?-1:1),null===(o=s.getContext("2d"))||void 0===o||o.drawImage(r,g,f,s.width,s.height),s},[t.flipX,t.flipY,r,t.width,t.height,n]);return e.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&l.Util.releaseCanvas(o)},[o]),o})(t,Y,n._elementsPixelRatio),j=P&&V||D||L;e.useEffect(()=>{Y&&n.history.ignore(()=>{t.set({duration:1e3*Y.duration})})},[Y]),e.useEffect(()=>{var e;if(!Y){return}const r=n.animatedElementsIds,o=(!r.length||r.includes(t.id))&&n.isPlaying,i=A&&(o||H);if(!i){return void Y.pause()}i&&(Y.currentTime=t.startTime*Y.duration,Y.play());const a=new l.Animation(()=>{le.current()},null===(e=p.current)||void 0===e?void 0:e.getLayer());a.start();const d=()=>{X(!1),Y.currentTime=t.startTime*Y.duration},h=()=>{Y.currentTime>=t.endTime*Y.duration&&(Y.pause(),Y.currentTime=t.startTime*Y.duration,X(!1))};return Y.addEventListener("ended",d),Y.addEventListener("timeupdate",h),()=>{Y.pause(),a.stop(),Y.removeEventListener("ended",d),Y.removeEventListener("timeupdate",h)}},[Y,H,n.isPlaying,A]),e.useEffect(()=>{Y&&(Y.volume=t.volume)},[Y,t.volume]);const z=e.useRef(null);e.useEffect(()=>{const e=r(()=>{var e,r;if(Y){if(P&&V){return ce(),void n.currentTime}const o=n.animatedElementsIds;if(o.length&&!o.includes(t.id)){return}const i=n.currentTime>=t.page.startTime&&n.currentTime<t.page.startTime+t.page.duration,a=t.startTime*Y.duration*1e3,d=Y.duration*(t.endTime-t.startTime)*1e3;let h=((n.currentTime||t.page.startTime)-t.page.startTime)%d+a;if(i||(h=0),Math.abs(1e3*Y.currentTime-h)>500||!n.isPlaying){const e=h/1e3;e!==Y.currentTime&&(Y.currentTime=e),!S(Y)&&!n.isPlaying&&!z.current&&(z.current=g(`video ${t.id}`))}le.current(),null===(r=null===(e=p.current)||void 0===e?void 0:e.getLayer())||void 0===r||r.batchDraw()}});return()=>{e(),z.current&&(z.current(),z.current=null)}},[n,Y,P,V]),e.useEffect(()=>{var e;if(!Y){return}if(P){return null===(e=z.current)||void 0===e||e.call(z),void(z.current=null)}const r=()=>{var e,r;!S(Y)&&t.page._exportingOrRendering||z.current&&(le.current(),null===(r=null===(e=p.current)||void 0===e?void 0:e.getLayer())||void 0===r||r.batchDraw(),z.current(),z.current=null)};let n;return t.page._exportingOrRendering&&(n=setInterval(r,20)),Y.addEventListener("timeupdate",r),Y.addEventListener("canplay",r),()=>{clearInterval(n),Y.removeEventListener("timeupdate",r),Y.removeEventListener("canplay",r)}},[t.page._exportingOrRendering,Y,t.id,g,P]);let{cropX:B,cropY:U,cropWidth:F,cropHeight:N}=t;"loaded"!==W&&(B=U=0,F=N=1);const Z=($=j)instanceof HTMLVideoElement?$.videoWidth:(null==$?void 0:$.width)||0;var $;const q=(e=>e instanceof HTMLVideoElement?e.videoHeight:(null==e?void 0:e.height)||0)(j),G=Z*F,J=q*N,K=t.width/t.height;let Q,ee;const te=G/J,re="svg"===t.type;re?(Q=G,ee=J):K>=te?(Q=G,ee=G/K):(Q=J*K,ee=J);const ne={x:Z*B,y:q*U,width:Q,height:ee},oe=null!==(d=t.cornerRadius)&&void 0!==d?d:0,[ie,ae]=useCornerRadiusAndCrop(t,j,ne,n._elementsPixelRatio,oe,!0);let[de,he]=((t,r,n,o)=>{const i=(t=>{const[r,n]=e.useState(t);return e.useEffect(()=>{(async()=>{const e=await async function(e){if(!(e.indexOf("data:image/svg+xml")>=0||e.indexOf(".svg")>=0)){return e}const t=await m.urlToString(e),r=m.fixSize(t);return m.svgToURL(r)}(t);e!==r&&n(e)})()},[t]),r})(t.clipSrc||""),[a,d]=c(i,"anonymous"),h=t.clipSrc?d:"loaded";useLoader(h,t.clipSrc,t.id);const s=e.useMemo(()=>{if(r&&a){return E()}},[r,a]);function u(){var e;if(!a){return}const o=r instanceof HTMLVideoElement?r.videoWidth:null==r?void 0:r.width,i=r instanceof HTMLVideoElement?r.videoHeight:null==r?void 0:r.height;if(!r||!o||!i){return}if(!a||!a.width||!a.height){return}if(!s){return}const d=E(),h=Math.max(t.width/a.width*n,t.height/a.height*n);d.width=a.width*h,d.height=a.height*h,null===(e=d.getContext("2d"))||void 0===e||e.drawImage(a,0,0,d.width,d.height),s.width=Math.max(o,1),s.height=Math.max(i,1);const c=s.getContext("2d");c&&(c.save(),c.drawImage(d,0,0,o,i),l.Util.releaseCanvas(d),c.globalCompositeOperation="source-in",c.drawImage(r,0,0,s.width,s.height),c.restore())}return e.useLayoutEffect(()=>{u()},[s,r,a,t.width,t.height,n,...o]),[t.clipSrc&&a?s:r,u]})(t,ie,n._elementsPixelRatio,[ne,oe,n._elementsPixelRatio]);function ce(){var e,t;ae(),he(),null===(t=null===(e=p.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()}e.useEffect(()=>{ce()});const le=e.useRef(ce);le.current=ce;const se=Math.max(t.width/Q,t.height/ee);e.useEffect(()=>{var e;if(!t._cropModeEnabled){return}const r=null===(e=p.current)||void 0===e?void 0:e.getStage();function n(e){t._cropModeEnabled&&e.target!==I.current&&t.toggleCropMode(!1)}function o(e){t._cropModeEnabled&&e.target.parentNode!==(null==r?void 0:r.content)&&t.toggleCropMode(!1)}return document.body.addEventListener("click",o),null==r||r.on("click",n),null==r||r.on("tap",n),()=>{document.body.removeEventListener("click",o),document.body.removeEventListener("touchstart",o),null==r||r.off("click",n),null==r||r.off("click",n)}},[t._cropModeEnabled]),e.useLayoutEffect(()=>{if(!u&&!t._cropModeEnabled){return w(p.current,t),r(()=>{w(p.current,t)},{delay:100})}},[j,u,F,N,t._cropModeEnabled]),e.useLayoutEffect(()=>{var e;u||t._cropModeEnabled?null===(e=p.current)||void 0===e||e.clearCache():w(p.current,t)},[u,t.width,t.height,t._cropModeEnabled]),e.useEffect(()=>{w(p.current,t)},[t.shadowEnabled,t.shadowBlur,t.cornerRadius,t.shadowColor,t.shadowOffsetX,t.shadowOffsetY,t.shadowOpacity]);const ue=e.useRef(null),ge=e.useRef(null),fe=e.useRef(null);e.useLayoutEffect(()=>{t._cropModeEnabled&&(ge.current.nodes([ue.current]),fe.current.nodes([I.current]))},[t._cropModeEnabled]);const me=e=>{Math.round(e.target.x())>0&&(e.target.x(0),e.target.scaleX(1)),Math.round(e.target.y())>0&&(e.target.y(0),e.target.scaleY(1));const r=e.target.width()*e.target.scaleX(),n=e.target.height()*e.target.scaleY(),o=Math.min(1,Q/r),i=Math.min(1,ee/n),a=1-o,d=Math.min(a,Math.max(0,Math.round(-e.target.x())/r)),h=1-i,c=Math.min(h,Math.max(0,Math.round(-e.target.y())/n));e.target.setAttrs({x:-d*Z,y:-c*q,scaleX:1,scaleY:1}),t.set({cropX:d,cropY:c,cropWidth:o,cropHeight:i})},pe=()=>{"svg"!==t.type&&t.contentEditable&&setTimeout(()=>{t.toggleCropMode(!0)})},we="loading"===W,ve="failed"===W,xe=!we&&!ve,Me=e.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Ee=xe?t.a.opacity:0;v(p,Ee);const ye=t.selectable||"admin"===n.role,be=x();return e.createElement(e.Fragment,null,e.createElement(o,{onMouseEnter:()=>_(!0),onMouseLeave:()=>_(!1)},we&&e.createElement(T,{element:t}),ve&&e.createElement(C,{element:t}),e.createElement(i,{ref:p,name:"element",id:t.id,image:de,x:t.a.x,y:t.a.y,width:t.a.width||1,height:t.a.height||1,rotation:t.a.rotation,opacity:Ee,shadowEnabled:t.shadowEnabled,shadowBlur:t.shadowBlur,shadowOffsetX:t.shadowOffsetX,shadowOffsetY:t.shadowOffsetY,shadowColor:t.shadowColor,shadowOpacity:t.shadowOpacity,customCrop:ne,listening:ye,draggable:be?t.draggable&&k:t.draggable,preventDefault:!be||k,hideInExport:!t.showInExport,onDragMove:e=>{t.set({x:e.target.x(),y:e.target.y()})},onDragEnd:e=>{t.set({x:e.target.x(),y:e.target.y()})},onDblClick:pe,onDblTap:pe,onTransformStart:()=>{f(!0),Me.current={cropX:t.cropX,cropY:t.cropY,cropWidth:t.cropWidth,cropHeight:t.cropHeight}},onTransform:e=>{var r;const n=e.currentTarget,o=Math.abs(n.scaleX()-1)<1e-7?1:n.scaleX(),i=Math.abs(n.scaleY()-1)<1e-7?1:n.scaleY();n.scaleX(1),n.scaleY(1);const a=null===(r=e.target.getStage())||void 0===r?void 0:r.findOne("Transformer"),d=1-Q/Z,h=Math.min(d,Math.max(0,t.cropX)),c=1-ee/q,l=Math.min(c,Math.max(0,t.cropY)),s=a.getActiveAnchor(),u=!(s.indexOf("middle")>=0||s.indexOf("center")>=0),g=!u&&o<1&&Me.current.cropHeight>ee/q;let f=u?t.cropWidth:t.cropWidth*o;g&&(f=t.cropWidth);const m=!u&&i<1&&Me.current.cropWidth>Q/Z;let p=u?t.cropHeight:t.cropHeight*i;m&&(p=t.cropHeight),re&&(f=t.cropWidth,p=t.cropHeight),t.set({cropX:h,cropY:l,x:n.x(),y:n.y(),width:n.width()*o,height:n.height()*i,rotation:e.target.rotation(),cropWidth:Math.min(f,1-h),cropHeight:Math.min(p,1-l)})},onTransformEnd:e=>{const r=e.currentTarget;t.set({width:r.width(),height:r.height(),x:r.x(),y:r.y(),rotation:e.target.rotation(),cropWidth:Q/Z,cropHeight:ee/q}),f(!1)}}),e.createElement(a,{x:t.a.x,y:t.a.y,width:Math.max(t.a.width-t.borderSize,0),height:Math.max(t.a.height-t.borderSize,0),opacity:Ee,offsetX:-t.borderSize/2,offsetY:-t.borderSize/2,stroke:t.borderColor,strokeWidth:t.borderSize,listening:!1,visible:!!t.borderSize,rotation:t.rotation,cornerRadius:Math.max(0,oe-t.borderSize),hideInExport:!t.showInExport}),!n.isPlaying&&e.createElement(i,{image:H?O||be?b:void 0:y,x:t.a.x,y:t.a.y,offsetX:-t.a.width/2+15/n.scale,offsetY:-t.a.height/2+15/n.scale,rotation:t.a.rotation,width:30/n.scale,height:30/n.scale,hideInExport:!0,onClick:()=>X(!H),onTap:()=>X(!H)}),t._cropModeEnabled&&e.createElement(s,{selector:".page-abs-container",enabled:!0},e.createElement(a,{x:-window.innerWidth/n.scale,y:-window.innerWidth/n.scale,width:window.innerWidth/n.scale*3,height:window.innerWidth/n.scale*3,fill:"rgba(0,0,0,0.3)"}),e.createElement(i,{listening:!1,image:de,x:t.a.x,y:t.a.y,width:t.a.width,height:t.a.height,rotation:t.a.rotation,shadowEnabled:t.shadowEnabled,shadowBlur:t.shadowBlur}),e.createElement(o,{x:t.a.x,y:t.a.y,rotation:t.a.rotation,scaleX:se,scaleY:se},e.createElement(i,{image:j,ref:I,width:Z,height:q,opacity:.4,draggable:!0,x:-t.cropX*Z,y:-t.cropY*q,onDragMove:me,onTransform:me}),e.createElement(h,{ref:fe,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),e.createElement(a,{width:Q,height:ee,ref:ue,listening:!1,onTransform:e=>{e.target.x()<-t.cropX*Z-1e-9&&(e.target.x(-t.cropX*Z),e.target.scaleX(1)),e.target.y()<-t.cropY*q-1e-9&&(e.target.y(-t.cropY*q),e.target.scaleY(1));const r=Math.min(1,Math.max(0,t.cropX+e.target.x()/Z)),n=Math.min(1,Math.max(0,e.target.y()/q+t.cropY)),o=e.target.width()*e.target.scaleX(),i=e.target.height()*e.target.scaleY(),a=Math.min(1-r,o/Z),d=Math.min(1-n,i/q),h=e.target.getAbsolutePosition(e.target.getParent().getParent());e.target.scale({x:1,y:1}),e.target.position({x:0,y:0}),t.set({x:h.x,y:h.y,cropX:r,cropY:n,cropWidth:a,cropHeight:d,width:Math.min(o*se,Z*(1-r)*se),height:Math.min(i*se,q*(1-n)*se)})}}),e.createElement(h,{ref:ge,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2,visible:t.resizable})))))});
1
+ import e from"react";import{observer as t}from"mobx-react-lite";import{autorun as r}from"mobx";import{Arc as n,Group as o,Image as i,Rect as a,Text as d,Transformer as h}from"react-konva";import{ROLES as c}from"../model/store.js";import l from"use-image";import s from"konva";import{Portal as u}from"react-konva-utils";import{useWorkspaceStyle as g}from"./workspace-style.js";import{incrementLoader as f,triggerLoadError as m}from"../utils/loader.js";import*as p from"../utils/svg.js";import{flags as w}from"../utils/flags.js";import{applyFilter as v}from"./apply-filters.js";import{useFadeIn as x}from"./use-fadein.js";import{isTouchDevice as M}from"../utils/screen.js";import{useMediabunnyVideo as E}from"./use-mediabunny-video.js";function y(){return document.createElement("canvas")}const b=new window.Image;b.src=p.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" fill="white"/>\n <path d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');const L=new window.Image;L.src=p.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" fill="white"/>\n <path opacity="0.6" d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" fill="white"/>\n <path d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');export const useCornerRadiusAndCrop=(t,r,n,o,i=0,a=!1)=>{const d=Math.floor(Math.max(t.width*o,1)),h=Math.floor(Math.max(t.height*o,1)),c=Math.min(i*o,d/2,h/2),l=Math.max(t.width/n.width,t.height/n.height)*o,u=t.page._exportingOrRendering&&w.imageDownScalingEnabled&&l<1&&!a,g=r instanceof HTMLVideoElement?r.videoWidth:null==r?void 0:r.width,f=r instanceof HTMLVideoElement?r.videoHeight:null==r?void 0:r.height,m=0===n.x&&0===n.y&&n.width===g&&n.height===f,p=e.useMemo(()=>{if(r&&g&&f){return m&&0===c&&!u?void 0:y()}},[r,c,u,m,g,f]),v=()=>{if(!p||!r){return}p.width=d,p.height=h;const e=p.getContext("2d");if(!e){return}c&&(e.beginPath(),e.moveTo(c,0),e.lineTo(d-c,0),e.arc(d-c,c,c,3*Math.PI/2,0,!1),e.lineTo(d,h-c),e.arc(d-c,h-c,c,0,Math.PI/2,!1),e.lineTo(c,h),e.arc(c,h-c,c,Math.PI/2,Math.PI,!1),e.lineTo(0,c),e.arc(c,c,c,Math.PI,3*Math.PI/2,!1),e.clip());const t=u?function(e,t){var r,n;const o=y(),i=e instanceof HTMLVideoElement?e.videoWidth:e.width,a=e instanceof HTMLVideoElement?e.videoHeight:e.height;o.width=i,o.height=a,null===(r=o.getContext("2d"))||void 0===r||r.drawImage(e,0,0,o.width,o.height);const d=function(e,t,r,n,o,i,a){for(var d=new ImageData(t,r),h=new Int32Array(e.data.buffer),c=e.width,l=new Int32Array(d.data.buffer),s=d.width,u=t/i,g=r/a,f=Math.round(1/u),m=Math.round(1/g),p=f*m,w=0;w<d.height;w++){for(var v=0;v<s;v++){for(var x=0+Math.round(v/u)+(0+Math.round(w/g))*c,M=0,E=0,y=0,b=0,L=0;L<m;L++){for(var T=0;T<f;T++){var C=h[x+T+L*c];M+=C<<24>>>24,E+=C<<16>>>24,y+=C<<8>>>24,b+=C>>>24}}M=Math.round(M/p),E=Math.round(E/p),y=Math.round(y/p),b=Math.round(b/p),l[v+w*s]=b<<24|y<<16|E<<8|M}}return d}(o.getContext("2d").getImageData(0,0,o.width,o.height),Math.floor(o.width*t),Math.floor(o.height*t),0,0,o.width,o.height);return o.width=Math.floor(o.width*t),o.height=Math.floor(o.height*t),null===(n=o.getContext("2d"))||void 0===n||n.putImageData(d,0,0),o}(r,l):r,o=u?{x:Math.floor(n.x*l),y:Math.floor(n.y*l),width:Math.floor(n.width*l),height:Math.floor(n.height*l)}:n;e.drawImage(t,o.x,o.y,o.width,o.height,0,0,p.width,p.height)};return e.useLayoutEffect(()=>{v()},[p,t.width,t.height,n.x,n.y,n.width,n.height,i,o,a,t.page._exportingOrRendering,u]),e.useEffect(()=>()=>{p&&"CANVAS"===p.nodeName&&s.Util.releaseCanvas(p)},[p]),[p||r,v]};const T=y(),C=t(({element:t})=>{const r=Math.min(30,t.width/4,t.height/4),i=e.useRef(null);e.useEffect(()=>{const e=i.current;if(!e){return}const t=new s.Animation(t=>{e.rotate(((null==t?void 0:t.timeDiff)||0)/2)},e.getLayer());return t.start(),()=>{t.stop()}});const{mediaLoadingStyle:d}=g();return e.createElement(o,{x:t.a.x,y:t.a.y,rotation:t.a.rotation,listening:!1,opacity:t.a.opacity,hideInExport:!t.showInExport},e.createElement(a,{width:t.width,height:t.height,fill:d.fill}),e.createElement(n,{ref:i,x:t.width/2,y:t.height/2,fill:d.textFill,outerRadius:Math.abs(r),innerRadius:Math.max(1,r-5),angle:270}))}),R=t(({element:t})=>{const{mediaErrorStyle:r}=g(),n=Math.max(10,Math.min(30,t.width/25));return e.createElement(o,{x:t.a.x,y:t.a.y,rotation:t.a.rotation,listening:!1,opacity:t.a.opacity,hideInExport:!t.showInExport},e.createElement(a,{width:t.width,height:t.height,fill:r.fill}),e.createElement(d,{text:"Can not load the video...",fontSize:n,width:t.width,height:t.height,align:"center",fill:r.textFill,verticalAlign:"middle",padding:5}))});let S=function(t,r,n){const o=e.useRef("loading"),i=e.useRef(void 0),[a,d]=e.useState(0),h=e.useRef(),c=e.useRef(),l=e.useRef();return h.current===t&&c.current===r&&l.current===n||(o.current="loading",i.current=void 0,h.current=t,c.current=r,l.current=n),e.useLayoutEffect(function(){if(t){var e=document.createElement("video");return e.addEventListener("canplay",a),e.addEventListener("error",h),r&&(e.crossOrigin=r),n&&(e.referrerPolicy=n),e.src=t,e.load(),function(){e.removeEventListener("canplay",a),e.removeEventListener("error",h)}}function a(){o.current="loaded",i.current=e,i.current.currentTime=0,d(Math.random()),i.current.removeEventListener("canplay",a)}function h(t){var r;const n=4===e.readyState,a=e.buffered&&e.buffered.length>0&&e.buffered.end(e.buffered.length-1)/e.duration*100>=100;if(n&&a){return}const h=t.message||(null===(r=e.error)||void 0===r?void 0:r.message)||"Unknown error",c=new Error("Video failed to load: "+h);console.error(c),o.current="failed",i.current=void 0,d(Math.random())}},[t,r,n]),[i.current,o.current]};export const setVideoLoaderHook=e=>{S=e};function I(e){return e.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA}export const useLoader=(t,r,n)=>{const o=e.useRef(),i=()=>{var e;null===(e=o.current)||void 0===e||e.call(o),o.current=void 0};e.useEffect(()=>i,[]),e.useLayoutEffect(()=>{const e=r.slice(0,200),a=`video with id ${n} url: ${e}`;"loading"!==t||o.current||(o.current=f(a)),"loading"!==t&&i(),"failed"===t&&m(a)},[t])};export const VideoElement=t(({element:t,store:n})=>{var d;const[g,m]=e.useState(!1),w=e.useRef(null),k=e.useRef(null),H=t.isSelected,[X,Y]=e.useState(!1),[W,O]=S(t.src,"anonymous"),[_,A]=e.useState(!1),P=n.activePage===t.page,V=t.page._exportingOrRendering&&"loaded"===O,D=E(t,n,V);useLoader(O,t.src,t.id),W&&(W.playsInline=!0);const j=((t,r,n)=>{const o=e.useMemo(()=>{var e,o;const{flipX:i,flipY:a}=t,d="svg"===t.type||t.src.indexOf("data:image/svg+xml")>=0||t.src.indexOf(".svg")>=0,h=navigator.userAgent.toLowerCase().indexOf("firefox")>-1;if(!(i||a||h&&d)){return r}if(!r){return null}const c=r instanceof HTMLVideoElement?r.videoWidth:null==r?void 0:r.width,l=r instanceof HTMLVideoElement?r.videoHeight:null==r?void 0:r.height;if(!c||!l){return null}const s=y();let u=1;"svg"===t.type&&(u=Math.max(t.width/c*n,t.height/l*n)),s.width=Math.max(c*u,1),s.height=Math.max(l*u,1);let g=i?-s.width:0,f=a?-s.height:0;return null===(e=s.getContext("2d"))||void 0===e||e.scale(i?-1:1,a?-1:1),null===(o=s.getContext("2d"))||void 0===o||o.drawImage(r,g,f,s.width,s.height),s},[t.flipX,t.flipY,r,t.width,t.height,n]);return e.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&s.Util.releaseCanvas(o)},[o]),o})(t,W,n._elementsPixelRatio),z=V&&D||j||T;e.useEffect(()=>{W&&n.history.ignore(()=>{t.set({duration:1e3*W.duration})})},[W]),e.useEffect(()=>{var e;if(!W){return}const r=n.animatedElementsIds,o=(!r.length||r.includes(t.id))&&n.isPlaying,i=P&&(o||X);if(!i){return void W.pause()}i&&(W.currentTime=t.startTime*W.duration,W.play());const a=new s.Animation(()=>{se.current()},null===(e=w.current)||void 0===e?void 0:e.getLayer());a.start();const d=()=>{Y(!1),W.currentTime=t.startTime*W.duration},h=()=>{W.currentTime>=t.endTime*W.duration&&(W.pause(),W.currentTime=t.startTime*W.duration,Y(!1))};return W.addEventListener("ended",d),W.addEventListener("timeupdate",h),()=>{W.pause(),a.stop(),W.removeEventListener("ended",d),W.removeEventListener("timeupdate",h)}},[W,X,n.isPlaying,P]),e.useEffect(()=>{W&&(W.volume=t.volume)},[W,t.volume]);const B=e.useRef(null);e.useEffect(()=>{const e=r(()=>{var e,r;if(W){if(V&&D){return le(),void n.currentTime}const o=n.animatedElementsIds;if(o.length&&!o.includes(t.id)){return}const i=n.currentTime>=t.page.startTime&&n.currentTime<t.page.startTime+t.page.duration,a=t.startTime*W.duration*1e3,d=W.duration*(t.endTime-t.startTime)*1e3;let h=((n.currentTime||t.page.startTime)-t.page.startTime)%d+a;if(i||(h=0),Math.abs(1e3*W.currentTime-h)>500||!n.isPlaying){const e=h/1e3;e!==W.currentTime&&(W.currentTime=e),!I(W)&&!n.isPlaying&&!B.current&&(B.current=f(`video ${t.id}`))}se.current(),null===(r=null===(e=w.current)||void 0===e?void 0:e.getLayer())||void 0===r||r.batchDraw()}});return()=>{e(),B.current&&(B.current(),B.current=null)}},[n,W,V,D]),e.useEffect(()=>{var e;if(!W){return}if(V){return null===(e=B.current)||void 0===e||e.call(B),void(B.current=null)}const r=()=>{var e,r;!I(W)&&t.page._exportingOrRendering||B.current&&(se.current(),null===(r=null===(e=w.current)||void 0===e?void 0:e.getLayer())||void 0===r||r.batchDraw(),B.current(),B.current=null)};let n;return t.page._exportingOrRendering&&(n=setInterval(r,20)),W.addEventListener("timeupdate",r),W.addEventListener("canplay",r),()=>{clearInterval(n),W.removeEventListener("timeupdate",r),W.removeEventListener("canplay",r)}},[t.page._exportingOrRendering,W,t.id,f,V]);let{cropX:U,cropY:N,cropWidth:F,cropHeight:Z}=t;"loaded"!==O&&(U=N=0,F=Z=1);const $=(q=z)instanceof HTMLVideoElement?q.videoWidth:(null==q?void 0:q.width)||0;var q;const G=(e=>e instanceof HTMLVideoElement?e.videoHeight:(null==e?void 0:e.height)||0)(z),J=$*F,K=G*Z,Q=t.width/t.height;let ee,te;const re=J/K,ne="svg"===t.type;ne?(ee=J,te=K):Q>=re?(ee=J,te=J/Q):(ee=K*Q,te=K);const oe={x:$*U,y:G*N,width:ee,height:te},ie=null!==(d=t.cornerRadius)&&void 0!==d?d:0,[ae,de]=useCornerRadiusAndCrop(t,z,oe,n._elementsPixelRatio,ie,!0);let[he,ce]=((t,r,n,o)=>{const i=(t=>{const[r,n]=e.useState(t);return e.useEffect(()=>{(async()=>{const e=await async function(e){if(!(e.indexOf("data:image/svg+xml")>=0||e.indexOf(".svg")>=0)){return e}const t=await p.urlToString(e),r=p.fixSize(t);return p.svgToURL(r)}(t);e!==r&&n(e)})()},[t]),r})(t.clipSrc||""),[a,d]=l(i,"anonymous"),h=t.clipSrc?d:"loaded";useLoader(h,t.clipSrc,t.id);const c=e.useMemo(()=>{if(r&&a){return y()}},[r,a]);function u(){var e;if(!a){return}const o=r instanceof HTMLVideoElement?r.videoWidth:null==r?void 0:r.width,i=r instanceof HTMLVideoElement?r.videoHeight:null==r?void 0:r.height;if(!r||!o||!i){return}if(!a||!a.width||!a.height){return}if(!c){return}const d=y(),h=Math.max(t.width/a.width*n,t.height/a.height*n);d.width=a.width*h,d.height=a.height*h,null===(e=d.getContext("2d"))||void 0===e||e.drawImage(a,0,0,d.width,d.height),c.width=Math.max(o,1),c.height=Math.max(i,1);const l=c.getContext("2d");l&&(l.save(),l.drawImage(d,0,0,o,i),s.Util.releaseCanvas(d),l.globalCompositeOperation="source-in",l.drawImage(r,0,0,c.width,c.height),l.restore())}return e.useLayoutEffect(()=>{u()},[c,r,a,t.width,t.height,n,...o]),[t.clipSrc&&a?c:r,u]})(t,ae,n._elementsPixelRatio,[oe,ie,n._elementsPixelRatio]);function le(){var e,t;de(),ce(),null===(t=null===(e=w.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()}e.useEffect(()=>{le()});const se=e.useRef(le);se.current=le;const ue=Math.max(t.width/ee,t.height/te);e.useEffect(()=>{var e;if(!t._cropModeEnabled){return}const r=null===(e=w.current)||void 0===e?void 0:e.getStage();function n(e){t._cropModeEnabled&&e.target!==k.current&&t.toggleCropMode(!1)}function o(e){t._cropModeEnabled&&e.target.parentNode!==(null==r?void 0:r.content)&&t.toggleCropMode(!1)}return document.body.addEventListener("click",o),null==r||r.on("click",n),null==r||r.on("tap",n),()=>{document.body.removeEventListener("click",o),document.body.removeEventListener("touchstart",o),null==r||r.off("click",n),null==r||r.off("click",n)}},[t._cropModeEnabled]),e.useLayoutEffect(()=>{if(!g&&!t._cropModeEnabled){return v(w.current,t),r(()=>{v(w.current,t)},{delay:100})}},[z,g,F,Z,t._cropModeEnabled]),e.useLayoutEffect(()=>{var e;g||t._cropModeEnabled?null===(e=w.current)||void 0===e||e.clearCache():v(w.current,t)},[g,t.width,t.height,t._cropModeEnabled]),e.useEffect(()=>{v(w.current,t)},[t.shadowEnabled,t.shadowBlur,t.cornerRadius,t.shadowColor,t.shadowOffsetX,t.shadowOffsetY,t.shadowOpacity]);const ge=e.useRef(null),fe=e.useRef(null),me=e.useRef(null);e.useLayoutEffect(()=>{t._cropModeEnabled&&(fe.current.nodes([ge.current]),me.current.nodes([k.current]))},[t._cropModeEnabled]);const pe=e=>{Math.round(e.target.x())>0&&(e.target.x(0),e.target.scaleX(1)),Math.round(e.target.y())>0&&(e.target.y(0),e.target.scaleY(1));const r=e.target.width()*e.target.scaleX(),n=e.target.height()*e.target.scaleY(),o=Math.min(1,ee/r),i=Math.min(1,te/n),a=1-o,d=Math.min(a,Math.max(0,Math.round(-e.target.x())/r)),h=1-i,c=Math.min(h,Math.max(0,Math.round(-e.target.y())/n));e.target.setAttrs({x:-d*$,y:-c*G,scaleX:1,scaleY:1}),t.set({cropX:d,cropY:c,cropWidth:o,cropHeight:i})},we=()=>{"svg"!==t.type&&t.contentEditable&&setTimeout(()=>{t.toggleCropMode(!0)})},ve="loading"===O,xe="failed"===O,Me=!ve&&!xe,Ee=e.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),ye=Me?t.a.opacity:0;x(w,ye);const be=t.selectable||n.role===c.ADMIN,Le=M();return e.createElement(e.Fragment,null,e.createElement(o,{onMouseEnter:()=>A(!0),onMouseLeave:()=>A(!1)},ve&&e.createElement(C,{element:t}),xe&&e.createElement(R,{element:t}),e.createElement(i,{ref:w,name:"element",id:t.id,image:he,x:t.a.x,y:t.a.y,width:t.a.width||1,height:t.a.height||1,rotation:t.a.rotation,opacity:ye,shadowEnabled:t.shadowEnabled,shadowBlur:t.shadowBlur,shadowOffsetX:t.shadowOffsetX,shadowOffsetY:t.shadowOffsetY,shadowColor:t.shadowColor,shadowOpacity:t.shadowOpacity,customCrop:oe,listening:be,draggable:Le?t.draggable&&H:t.draggable,preventDefault:!Le||H,hideInExport:!t.showInExport,onDragMove:e=>{t.set({x:e.target.x(),y:e.target.y()})},onDragEnd:e=>{t.set({x:e.target.x(),y:e.target.y()})},onDblClick:we,onDblTap:we,onTransformStart:()=>{m(!0),Ee.current={cropX:t.cropX,cropY:t.cropY,cropWidth:t.cropWidth,cropHeight:t.cropHeight}},onTransform:e=>{var r;const n=e.currentTarget,o=Math.abs(n.scaleX()-1)<1e-7?1:n.scaleX(),i=Math.abs(n.scaleY()-1)<1e-7?1:n.scaleY();n.scaleX(1),n.scaleY(1);const a=null===(r=e.target.getStage())||void 0===r?void 0:r.findOne("Transformer"),d=1-ee/$,h=Math.min(d,Math.max(0,t.cropX)),c=1-te/G,l=Math.min(c,Math.max(0,t.cropY)),s=a.getActiveAnchor(),u=!(s.indexOf("middle")>=0||s.indexOf("center")>=0),g=!u&&o<1&&Ee.current.cropHeight>te/G;let f=u?t.cropWidth:t.cropWidth*o;g&&(f=t.cropWidth);const m=!u&&i<1&&Ee.current.cropWidth>ee/$;let p=u?t.cropHeight:t.cropHeight*i;m&&(p=t.cropHeight),ne&&(f=t.cropWidth,p=t.cropHeight),t.set({cropX:h,cropY:l,x:n.x(),y:n.y(),width:n.width()*o,height:n.height()*i,rotation:e.target.rotation(),cropWidth:Math.min(f,1-h),cropHeight:Math.min(p,1-l)})},onTransformEnd:e=>{const r=e.currentTarget;t.set({width:r.width(),height:r.height(),x:r.x(),y:r.y(),rotation:e.target.rotation(),cropWidth:ee/$,cropHeight:te/G}),m(!1)}}),e.createElement(a,{x:t.a.x,y:t.a.y,width:Math.max(t.a.width-t.borderSize,0),height:Math.max(t.a.height-t.borderSize,0),opacity:ye,offsetX:-t.borderSize/2,offsetY:-t.borderSize/2,stroke:t.borderColor,strokeWidth:t.borderSize,listening:!1,visible:!!t.borderSize,rotation:t.rotation,cornerRadius:Math.max(0,ie-t.borderSize),hideInExport:!t.showInExport}),!n.isPlaying&&e.createElement(i,{image:X?_||Le?L:void 0:b,x:t.a.x,y:t.a.y,offsetX:-t.a.width/2+15/n.scale,offsetY:-t.a.height/2+15/n.scale,rotation:t.a.rotation,width:30/n.scale,height:30/n.scale,hideInExport:!0,onClick:()=>Y(!X),onTap:()=>Y(!X)}),t._cropModeEnabled&&e.createElement(u,{selector:".page-abs-container",enabled:!0},e.createElement(a,{x:-window.innerWidth/n.scale,y:-window.innerWidth/n.scale,width:window.innerWidth/n.scale*3,height:window.innerWidth/n.scale*3,fill:"rgba(0,0,0,0.3)"}),e.createElement(i,{listening:!1,image:he,x:t.a.x,y:t.a.y,width:t.a.width,height:t.a.height,rotation:t.a.rotation,shadowEnabled:t.shadowEnabled,shadowBlur:t.shadowBlur}),e.createElement(o,{x:t.a.x,y:t.a.y,rotation:t.a.rotation,scaleX:ue,scaleY:ue},e.createElement(i,{image:z,ref:k,width:$,height:G,opacity:.4,draggable:!0,x:-t.cropX*$,y:-t.cropY*G,onDragMove:pe,onTransform:pe}),e.createElement(h,{ref:me,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),e.createElement(a,{width:ee,height:te,ref:ge,listening:!1,onTransform:e=>{e.target.x()<-t.cropX*$-1e-9&&(e.target.x(-t.cropX*$),e.target.scaleX(1)),e.target.y()<-t.cropY*G-1e-9&&(e.target.y(-t.cropY*G),e.target.scaleY(1));const r=Math.min(1,Math.max(0,t.cropX+e.target.x()/$)),n=Math.min(1,Math.max(0,e.target.y()/G+t.cropY)),o=e.target.width()*e.target.scaleX(),i=e.target.height()*e.target.scaleY(),a=Math.min(1-r,o/$),d=Math.min(1-n,i/G),h=e.target.getAbsolutePosition(e.target.getParent().getParent());e.target.scale({x:1,y:1}),e.target.position({x:0,y:0}),t.set({x:h.x,y:h.y,cropX:r,cropY:n,cropWidth:a,cropHeight:d,width:Math.min(o*ue,$*(1-r)*ue),height:Math.min(i*ue,G*(1-n)*ue)})}}),e.createElement(h,{ref:fe,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2,visible:t.resizable})))))});
@@ -1544,8 +1544,6 @@ export declare const TYPES_MAP: {
1544
1544
  _cellContentHeights: import("mobx").ObservableMap<string, number>;
1545
1545
  _baseRowHeights: number[] | null;
1546
1546
  _baseHeight: number | null;
1547
- _isResizingRows: boolean;
1548
- _isTransforming: boolean;
1549
1547
  } & {
1550
1548
  afterCreate(): void;
1551
1549
  } & {
@@ -1554,6 +1552,7 @@ export declare const TYPES_MAP: {
1554
1552
  } & {
1555
1553
  getCell(row: number, col: number): import("./table-model.js").TableCellType | undefined;
1556
1554
  readonly minWidth: number;
1555
+ getRowContentOuterHeight(row: number): number;
1557
1556
  readonly minHeight: number;
1558
1557
  readonly actualHeight: number;
1559
1558
  getCellRect(row: number, col: number, rowSpan?: number, colSpan?: number): {
@@ -1565,6 +1564,7 @@ export declare const TYPES_MAP: {
1565
1564
  readonly visibleCells: import("./table-model.js").TableCellType[];
1566
1565
  readonly focusedCells: import("./table-model.js").TableCellType[];
1567
1566
  readonly editingCell: import("./table-model.js").TableCellType | undefined;
1567
+ getFocusedCellRange(): import("./table-model.js").CellRange | null;
1568
1568
  readonly _fitRowsToContent: {
1569
1569
  rowHeights: number[];
1570
1570
  height: number;
@@ -1573,22 +1573,28 @@ export declare const TYPES_MAP: {
1573
1573
  setCellContentHeight(cellId: string, height: number): void;
1574
1574
  _applyFitRowsToContent(): void;
1575
1575
  focusCell(cellId: string, addToSelection?: boolean): void;
1576
+ selectRowRange(startRow: number, endRow: number): void;
1577
+ selectColumnRange(startCol: number, endCol: number): void;
1578
+ selectRow(rowIndex: number): void;
1579
+ selectColumn(colIndex: number): void;
1576
1580
  focusCellRange(targetRow: number, targetCol: number): void;
1577
1581
  clearCellFocus(): void;
1578
1582
  enterCellEdit(cellId: string): void;
1579
1583
  exitCellEdit(): void;
1580
1584
  _resetBaseRowHeights(): void;
1581
- _setIsResizingRows(value: boolean): void;
1582
- _setIsTransforming(value: boolean): void;
1585
+ setHeightRedistribute(newHeight: number): void;
1583
1586
  addRow(index: number): void;
1584
1587
  removeRow(index: number): void;
1585
1588
  addColumn(index: number): void;
1586
1589
  removeColumn(index: number): void;
1590
+ removeRowRange(minRow: number, maxRow: number): void;
1591
+ removeColumnRange(minCol: number, maxCol: number): void;
1587
1592
  distributeRowsEvenly(): void;
1588
1593
  distributeColumnsEvenly(): void;
1589
1594
  resizeColumn(index: number, delta: number): void;
1590
1595
  resizeRow(index: number, delta: number): void;
1591
1596
  setCellBorders(cellIds: string[], sides: import("./table-model.js").BorderSideName[], attrs: import("./table-model.js").BorderAttrs): void;
1597
+ applyBorderMode(mode: import("./table-model.js").BorderMode, attrs: import("./table-model.js").BorderAttrs): void;
1592
1598
  } & {
1593
1599
  clone(attrs?: any, { skipSelect }?: {
1594
1600
  skipSelect?: boolean | undefined;
package/model/store.d.ts CHANGED
@@ -43,6 +43,10 @@ export interface LoadJSONOptions {
43
43
  keepHistory?: boolean;
44
44
  modernizeTextBackground?: boolean;
45
45
  }
46
+ export declare const ROLES: {
47
+ readonly ADMIN: "admin";
48
+ readonly VIEWER: "viewer";
49
+ };
46
50
  export declare const Store: import("mobx-state-tree").IModelType<{
47
51
  role: import("mobx-state-tree").IType<string | undefined, string, string>;
48
52
  pages: import("mobx-state-tree").IArrayType<import("mobx-state-tree").IModelType<{
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{applySnapshot as t,cast as i,destroy as o,detach as n,getSnapshot as a,onSnapshot as s,setLivelinessChecking as r,types as l}from"mobx-state-tree";import{UndoManager as d}from"./history.js";import{nanoid as c}from"nanoid";import p from"konva";import{computed as g}from"mobx";import{downloadFile as m}from"../utils/download.js";import{getJsPDF as u}from"../utils/pdf.js";import{createGIF as f}from"../utils/gif-lib.js";import{validateKey as h}from"../utils/validate-key.js";import*as b from"../utils/fonts.js";import{flags as y}from"../utils/flags.js";import{addDpiMetadataToImage as v}from"../utils/image-dpi.js";import{nodeToCanvas as P}from"../utils/canvas.js";import{whenLoaded as w}from"../utils/loader.js";import{pxToUnit as x}from"../utils/unit.js";import{deepEqual as E}from"../utils/deep-equal.js";import{waitTillAvailable as _}from"../utils/wait.js";import{jsonToHTML as k}from"../utils/to-html.js";import{jsonToSVG as I}from"../utils/to-svg.js";import{Page as S}from"./page-model.js";import{forEveryChild as O,forEveryNode as T}from"./group-model.js";import{Audio as j}from"./audio-model.js";r("ignore");export const Font=l.model("Font",{fontFamily:l.string,url:l.optional(l.string,""),styles:l.frozen()}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}));export const Store=l.model("Store",{role:"",pages:l.array(S),fonts:l.array(Font),audios:l.array(j),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:l.optional(l.enumeration("UnitType",["pt","mm","cm","in","px"]),"px"),dpi:72,schemaVersion:3,bleedVisible:!1,rulesVisible:!1,distanceGuidesVisible:!1,openedSidePanel:"",previousOpenedSidePanel:"",custom:l.frozen(),tool:l.optional(l.enumeration("Tool",["selection","draw","pan","text","eraser"]),"selection"),toolOptions:l.optional(l.model({brushType:l.optional(l.enumeration("BrushType",["brush","highlighter"]),"brush"),strokeWidth:l.optional(l.number,5),stroke:l.optional(l.string,"#000000"),opacity:l.optional(l.number,1)}),{}),selectedElementsIds:l.array(l.string),animatedElementsIds:l.array(l.string),history:l.optional(d,{targetPath:"../pages"}),_elementsPixelRatio:Math.min(2,"undefined"!=typeof window&&window.devicePixelRatio||1),_activePageId:"",_selectedPagesIds:l.array(l.string),_forceShowCredit:!1,_key:"",_validated:!1}).views(e=>{const t=g(()=>{const t={};return T({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 e=[];return O({children:this.selectedElements},t=>{"group"!==t.type&&e.push(t)}),e},get activePage(){return e.pages.slice().find(t=>t.id===e._activePageId)||(e.pages.length?e.pages[0]:null)},get selectedPages(){return e._selectedPagesIds.map(t=>e.pages.find(e=>e.id===t))},get duration(){let t=0;return e.pages.forEach(e=>{t+=e.duration}),t},get _hasCroppedImages(){return this.find(e=>"image"===e.type&&e._cropModeEnabled)},find(t){let i;return T({children:e.pages},e=>{if(!i&&t(e)){return i=e,!0}}),i},getElementById:t=>e._idsMap[t]})).actions(r=>{let l=0,d=null,g=!1;const O={afterCreate(){r.history.canUndo},setCurrentTime(e){r.currentTime=e},_togglePlaying(e=!r.isPlaying){r.isPlaying=e},play({animatedElementsIds:e=[],startTime:t=0,currentTime:o=0,endTime:n=r.duration,repeat:a=!1}={}){o&&(console.warn("currentTime property of store.play() is deprecated. Please use startTime instead."),t=o),r.animatedElementsIds=i(e),r.currentTime=t,r.isPlaying=!0,l=Date.now(),d=n,g=a,requestAnimationFrame(()=>O.seek())},checkActivePage(){let e=0;for(const t of r.pages){if(r.currentTime>=t.startTime&&r.currentTime<t.startTime+t.duration){O.selectPage(t.id);break}e+=t.duration}},seek(){if(!r.isPlaying){return}const e=Date.now(),t=e-l;l=e,r.currentTime+=t,O.checkActivePage();const i=d||r.duration;r.isPlaying&&r.currentTime<i?requestAnimationFrame(()=>O.seek()):r.isPlaying&&g?(r.currentTime=0,requestAnimationFrame(()=>O.seek())):O.stop()},stop(){r.isPlaying=!1,r.currentTime=0,r.animatedElementsIds=i([]),O.checkActivePage()},__(){r._validated||(h(r._key,r._forceShowCredit),r._validated=!0)},set(e){Object.assign(r,e)},setUnit({unit:e,dpi:t}){r.unit=e||r.unit,r.dpi=t||r.dpi},setRole(e){r.role=e},setTool(e){r.tool=e},setToolOptions(e){Object.assign(r.toolOptions,e)},addPage(e){const t=S.create(Object.assign({id:c(10)},e));return r.pages.push(t),r._activePageId=t.id,t},selectPage(e){r._activePageId=e,1===r._selectedPagesIds.length&&(r._selectedPagesIds=i([e]))},selectPages(e){r._selectedPagesIds=i(e),1===r._selectedPagesIds.length&&(r._activePageId=r._selectedPagesIds[0])},selectElements(e){const t=e.map(e=>r.getElementById(e)).sort((e,t)=>e.page.children.indexOf(e)-e.page.children.indexOf(t)).filter(e=>!!e).map(e=>e.id);r.selectedElementsIds=i(t)},toggleBleed(e){r.bleedVisible=null!=e?e:!r.bleedVisible},toggleRulers(e){r.rulesVisible=null!=e?e:!r.rulesVisible},toggleDistanceGuides(e){r.distanceGuidesVisible=null!=e?e:!r.distanceGuidesVisible},openSidePanel(e){r.openedSidePanel!==e&&(r.previousOpenedSidePanel=r.openedSidePanel,r.openedSidePanel=e)},restoreSidePanel(){const e=r.previousOpenedSidePanel;e&&e!==r.openedSidePanel?r.openedSidePanel=e:r.openedSidePanel="photos"},setScale(e){r.scale=e},_setScaleToFit(e){r.scaleToFit=e},setElementsPixelRatio(e){r._elementsPixelRatio=e},setSize(e,t,i){r.pages.forEach(o=>{o.setSize({width:e,height:t,useMagic:i,softChange:!0})}),r.width=e,r.height=t},setPageZIndex(e,t){const i=r.pages.find(t=>t.id===e);i&&(n(i),r.pages.remove(i),r.pages.splice(t,0,i))},deletePages(e){const t=r.pages.indexOf(r.activePage);e.forEach(e=>{const t=r.pages.find(t=>t.id===e);o(t)});const n=Math.min(r.pages.length-1,t),a=r.pages[n];a&&(r._activePageId=a.id),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},groupElements(e,t={}){const o=e.map(e=>r.getElementById(e)),a=o[0].page;if(o.forEach(e=>{e&&n(e)}),!o.length){return}const s=a.children.reduce((e,t)=>{if("group"===t.type){const i=t.name.match(/group-(\d+)/);if(i){const t=parseInt(i[1],10);return Math.max(e,t)}}return e},0),l=Object.assign({id:c(10),name:`group-${s+1}`,children:o,type:"group"},t);return a.children.push(l),r.selectedElementsIds=i([l.id]),a.children.find(e=>e.id===l.id)},ungroupElements(e){const t=e.map(e=>r.getElementById(e)),o=[];t.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)}}),r.selectedElementsIds=i(o)},deleteElements(e){const t=[];r.find(i=>(e.includes(i.id)&&t.push(i),!1)),t.forEach(e=>{o(e)}),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},on(e,t){if("change"===e){let e=O.toJSON();return s(r,i=>{const o=O.toJSON();!E(e,o)&&(e=o,t(o))})}},async _toCanvas({pixelRatio:e,ignoreBackground:t,pageId:i,mimeType:o,includeBleed:n,_skipTimeout:a,quickMode:s=!1,_exportCanvases:l}={}){var d;const c=e||1;i=i||(null===(d=r.pages[0])||void 0===d?void 0:d.id);const g=r.pages.find(e=>e.id===i);if(!g){throw new Error(`No page for export with id ${i}`)}const m=r._elementsPixelRatio;c>r._elementsPixelRatio&&O.setElementsPixelRatio(c),s?null==g||g.set({_forceMount:!0}):null==g||g.set({_exporting:!0});const u=await _(()=>{const e=p.stages.filter(e=>e.getAttr("pageId")===i);return 0===e.length?null:e});if(!u){throw null==g||g.set({_forceMount:!1,_exporting:!1}),O.setElementsPixelRatio(m),new Error(`Export is failed. Can not find stage for page ${i}. Looks like <Workspace /> component is not mounted, but it is required in order to process the export.`)}u.length>1&&console.error(`Polotno error: Detected several canvas elements for page "${i}" in the document. This is not supported and will lead to incorrect export. Make sure to use unique ids for all pages and make sure you unmount <Workspace /> when it is not needed.`);const f=u[0];await O.waitLoading({_skipTimeout:a});const h=f.findOne(".page-container");if(!h){throw O.setElementsPixelRatio(m),null==g||g.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const b=f.position();f.position({x:0,y:0}),f.find("Transformer").forEach(e=>{e.setAttr("oldVisible",e.visible()),e.visible(!1)}),h.find(".page-background").forEach(e=>e.shadowEnabled(!1)),h.find(".page-background").forEach(e=>e.strokeEnabled(!1)),h.find(".highlighter").forEach(e=>e.visible(!1));const y=h.findOne(".page-background-group"),v=y.clip();y.clip({x:null,y:null,width:null,height:null});const w=h.findOne(".elements-container"),x=w.clip();w.clip({x:null,y:null,width:null,height:null});const E=h.find(e=>!e.visible()&&e.getAttr("editModeEnabled")&&!e.getAttr("hideInExport"));E.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()});const k=h.find(e=>e.getAttr("hideInExport"));k.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()}),t&&h.find(".page-background").forEach(e=>e.hide());const I=n?g.bleed:0;let S=I;!r.bleedVisible&&n||(r.bleedVisible||n?r.bleedVisible&&n?S=0:r.bleedVisible&&!n&&(S=-g.bleed):S=0);const T=g.computedWidth+2*I,j=g.computedHeight+2*I,F=h.scale();h.scale({x:1,y:1});const R=P(h,{x:h.x()-S,y:h.y()-S,width:T,height:j,pixelRatio:c,sceneCanvas:null==l?void 0:l.sceneCanvas,bufferCanvas:null==l?void 0:l.bufferCanvas});h.scale(F);const C=R._canvas;if("image/jpeg"===o){const e=C.getContext("2d");e.save(),e.globalCompositeOperation="destination-over",e.fillStyle="white",e.fillRect(0,0,C.width,C.height),e.restore()}return t&&h.find(".page-background").forEach(e=>e.show()),k.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),E.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),h.find(".page-background").forEach(e=>e.shadowEnabled(!0)),h.find(".page-background").forEach(e=>e.strokeEnabled(!0)),f.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),h.find(".highlighter").forEach(e=>e.visible(!0)),y.clip(v),w.clip(x),f.position(b),null==g||g.set({_exporting:!1,_forceMount:!1}),await Promise.resolve(),O.setElementsPixelRatio(m),C},async toDataURL(t={}){var{mimeType:i,quality:o,dpi:n,dpiMetadata:a="auto"}=t,s=e(t,["mimeType","quality","dpi","dpiMetadata"]);const l=await O._toCanvas(Object.assign({mimeType:i},s)),d=i||"image/png",c=l.toDataURL(d,o);p.Util.releaseCanvas(l);const g=null!=n?n:r.dpi;return"image/png"!==d&&"image/jpeg"!==d||"never"===a||"auto"===a&&72===g?c:v(c,d,g)},async toBlob(t={}){var{mimeType:i,quality:o}=t,n=e(t,["mimeType","quality"]);const a=await O._toCanvas(Object.assign({mimeType:i},n)),s=await new Promise(e=>{a.toBlob(e,i,o)});return p.Util.releaseCanvas(a),s},async saveAsImage(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=(o.mimeType||"image/png").split("/")[1];m(await O.toDataURL(o),i||"polotno."+n)},async _toPDF(e){const t=e.dpi||r.dpi,i=e.parallel||1,o=e.unit||("px"===r.unit?"mm":r.unit),n=e.pixelRatio||1,a=e.pageIds||r.pages.map(e=>e.id),s=r.pages.filter(e=>a.includes(e.id)),l=await u(),d=e=>x({px:e,unit:o,dpi:t}),c=e.cropMarkSize||0,p=d(c),g=s[0]||{},m=e.includeBleed?g.bleed:0,f=d(g.computedWidth+2*m+2*p),h=d(g.computedHeight+2*m+2*p);var b=new l({unit:o,orientation:f>h?"landscape":"portrait",format:[f,h],compress:!0,putOnlyUsedFonts:!0});b.deletePage(1);const y=((e,t)=>{const i=[];for(let o=0;o<e.length;o+=t){i.push(e.slice(o,o+t))}return i})(s,i);let v=0;for(const r of y){const t=r.map(async t=>{const i=e.includeBleed?t.bleed:0,o=t.computedWidth+2*i+2*c,s=t.computedHeight+2*i+2*c,r=d(o),l=d(s);let p=0,g=n;for(;p<10;){p+=1;const i=await O.toDataURL(Object.assign(Object.assign({},e),{pageId:t.id,pixelRatio:g,dpiMetadata:"never"}));if(i.length>20){return g!==n&&console.error(`Polotno can not export PDF with current settings. Quality is automatically reduced. pixelRatio was reduced to ${parseFloat(g.toFixed(3))}.`),e.onProgress&&e.onProgress(++v/a.length*.9),{url:i,width:r,height:l,widthPx:o,heightPx:s}}g*=.8}});(await Promise.all(t)).filter(e=>void 0!==e).forEach(({url:e,width:t,height:i,widthPx:n,heightPx:a})=>{b.addPage([t,i],t>i?"landscape":"portrait");const s=b.getCurrentPageInfo();var r;switch(o){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;default:throw"Invalid unit: "+o}if(s.pageContext.cropBox={bottomLeftX:0,bottomLeftY:0,topRightX:t*r,topRightY:i*r},s.pageContext.artBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(n-c-m)*r,topRightY:d(a-c-m)*r},s.pageContext.bleedBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(n-c-m)*r,topRightY:d(a-c-m)*r},p){b.setLineWidth(d(1));const e=p+d(m);b.line(e,0,e,p),b.line(0,e,p,e),b.line(t-e,0,t-e,p),b.line(t,e,t-p,e),b.line(0,i-e,p,i-e),b.line(e,i,e,i-p),b.line(t,i-e,t-p,i-e),b.line(t-e,i,t-e,i-p)}b.addImage(e,p,p,t-2*p,i-2*p,void 0,"FAST")})}return b},toPDFDataURL:async e=>(await O._toPDF(Object.assign({mimeType:"image/jpeg"},e))).output("datauristring"),async toGIFDataURL(e={}){const t=e.pixelRatio||1,i=await f({width:r.width*t,height:r.height*t}),o=1e3/(e.fps||10),n=r.duration/o;for(let a=0;a<n-1;a++){const e=a*o||1;O.setCurrentTime(e);let n=0,s="";for(const t of r.pages){if(n+=t.duration,t.set({_rendering:n>e}),n>e){s=t.id;break}}const l=await O._toCanvas({pixelRatio:t,pageId:s,_skipTimeout:!0});i.addFrame(l.getContext("2d"),{delay:o,copy:!0})}for(const a of r.pages){a.set({_rendering:!1})}return O.stop(),i.render(),new Promise(e=>{i.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(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=await O.toGIFDataURL(o);m(n,i||"polotno.gif")},async toHTML({elementHook:e}={}){const t=O.toJSON();return k({json:t,elementHook:e})},async saveAsHTML({fileName:e,elementHook:t}={}){const i=await O.toHTML({elementHook:t}),o="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));m(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:t,fontEmbedding:i="inline"}={fontEmbedding:"inline"}){var o;const n=O.toJSON();t=t||(null===(o=n.pages[0])||void 0===o?void 0:o.id);const a=n.pages.find(e=>e.id===t);return I({json:Object.assign(Object.assign({},n),{pages:a?[a]:[]}),elementHook:e,fontEmbedding:i})},async saveAsSVG({fileName:e,elementHook:t,pageId:i,fontEmbedding:o="inline"}={}){const n=await O.toSVG({elementHook:t,pageId:i,fontEmbedding:o}),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(n)));m(a,e||"polotno.svg")},async saveAsPDF(t={}){var{fileName:i}=t,o=e(t,["fileName"]);(await O._toPDF(Object.assign({mimeType:"image/jpeg"},o))).save(i||"polotno.pdf")},async waitLoading({_skipTimeout:e=!1}={}){e||await new Promise(e=>setTimeout(e,50)),await w()},toJSON:()=>({width:r.width,height:r.height,fonts:a(r.fonts),pages:a(r.pages),audios:a(r.audios),unit:r.unit,dpi:r.dpi,custom:r.custom,schemaVersion:r.schemaVersion}),loadJSON(e,i=!1){var o,n,s;const l="boolean"==typeof i?i:null!==(o=null==i?void 0:i.keepHistory)&&void 0!==o&&o,d="boolean"!=typeof i&&null!==(n=null==i?void 0:i.modernizeTextBackground)&&void 0!==n&&n,c=JSON.parse(JSON.stringify(e)),p=c.schemaVersion||0;p<1&&y.htmlRenderEnabled&&T({children:c.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),p<2&&T({children:c.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)})}),p<3&&y.htmlRenderEnabled&&!d&&T({children:c.pages},e=>{"text"===e.type&&e.backgroundEnabled&&(e.legacyBackground=!0)}),delete c.schemaVersion;const g=r.activePage?r.pages.indexOf(r.activePage):0;let m=null===(s=c.pages[g]||c.pages[0])||void 0===s?void 0:s.id;c._activePageId=m;const u=Object.assign({},a(r));Object.assign(u,c),u.history=l?a(r.history):{history:[],undoIdx:-1,targetPath:""},t(r,u)},clear({keepHistory:e=!1}={}){const t=r.pages.map(e=>e.id);O.deletePages(t),r.custom=null,e||r.history.clear()},addFont(e){O.removeFont(e.fontFamily),r.fonts.push(e)},removeFont(e){r.fonts.filter(t=>t.fontFamily===e).forEach(e=>o(e))},addAudio(e){const t=j.create(Object.assign({id:c(10)},e));r.audios.push(t)},removeAudio(e){const t=r.audios.find(t=>t.id===e);t&&r.audios.remove(t)},async loadFont(e,t,i,o){const n=r.fonts.find(t=>t.fontFamily===e)||b.globalFonts.find(t=>t.fontFamily===e);let a=[{fontStyle:"normal",fontWeight:"normal"},{fontStyle:"normal",fontWeight:"bold"}];return n?(n.styles&&(a=n.styles.map(e=>({fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"normal"}))),b.injectCustomFont(n)):b.injectGoogleFont(e),t&&i&&!a.some(e=>e.fontStyle===t&&e.fontWeight===i)&&a.push({fontStyle:t,fontWeight:i}),Promise.all(a.map(t=>b.loadFont(e,t.fontStyle,t.fontWeight,o)))},validate:e=>Store.validate(e,[{path:"",type:Store}]).map(e=>({path:"store"+e.context.map(e=>e.path).join("."),message:e.message}))};return O});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{applySnapshot as t,cast as i,destroy as o,detach as n,getSnapshot as a,onSnapshot as s,setLivelinessChecking as r,types as l}from"mobx-state-tree";import{UndoManager as d}from"./history.js";import{nanoid as c}from"nanoid";import p from"konva";import{computed as g}from"mobx";import{downloadFile as m}from"../utils/download.js";import{getJsPDF as u}from"../utils/pdf.js";import{createGIF as f}from"../utils/gif-lib.js";import{validateKey as h}from"../utils/validate-key.js";import*as b from"../utils/fonts.js";import{flags as y}from"../utils/flags.js";import{addDpiMetadataToImage as v}from"../utils/image-dpi.js";import{nodeToCanvas as P}from"../utils/canvas.js";import{whenLoaded as w}from"../utils/loader.js";import{pxToUnit as E}from"../utils/unit.js";import{deepEqual as x}from"../utils/deep-equal.js";import{waitTillAvailable as _}from"../utils/wait.js";import{jsonToHTML as k}from"../utils/to-html.js";import{jsonToSVG as I}from"../utils/to-svg.js";import{Page as S}from"./page-model.js";import{forEveryChild as O,forEveryNode as T}from"./group-model.js";import{Audio as j}from"./audio-model.js";r("ignore");export const Font=l.model("Font",{fontFamily:l.string,url:l.optional(l.string,""),styles:l.frozen()}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}));export const ROLES={ADMIN:"admin",VIEWER:"viewer"};export const Store=l.model("Store",{role:"",pages:l.array(S),fonts:l.array(Font),audios:l.array(j),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:l.optional(l.enumeration("UnitType",["pt","mm","cm","in","px"]),"px"),dpi:72,schemaVersion:3,bleedVisible:!1,rulesVisible:!1,distanceGuidesVisible:!1,openedSidePanel:"",previousOpenedSidePanel:"",custom:l.frozen(),tool:l.optional(l.enumeration("Tool",["selection","draw","pan","text","eraser"]),"selection"),toolOptions:l.optional(l.model({brushType:l.optional(l.enumeration("BrushType",["brush","highlighter"]),"brush"),strokeWidth:l.optional(l.number,5),stroke:l.optional(l.string,"#000000"),opacity:l.optional(l.number,1)}),{}),selectedElementsIds:l.array(l.string),animatedElementsIds:l.array(l.string),history:l.optional(d,{targetPath:"../pages"}),_elementsPixelRatio:Math.min(2,"undefined"!=typeof window&&window.devicePixelRatio||1),_activePageId:"",_selectedPagesIds:l.array(l.string),_forceShowCredit:!1,_key:"",_validated:!1}).views(e=>{const t=g(()=>{const t={};return T({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 e=[];return O({children:this.selectedElements},t=>{"group"!==t.type&&e.push(t)}),e},get activePage(){return e.pages.slice().find(t=>t.id===e._activePageId)||(e.pages.length?e.pages[0]:null)},get selectedPages(){return e._selectedPagesIds.map(t=>e.pages.find(e=>e.id===t))},get duration(){let t=0;return e.pages.forEach(e=>{t+=e.duration}),t},get _hasCroppedImages(){return this.find(e=>"image"===e.type&&e._cropModeEnabled)},find(t){let i;return T({children:e.pages},e=>{if(!i&&t(e)){return i=e,!0}}),i},getElementById:t=>e._idsMap[t]})).actions(r=>{let l=0,d=null,g=!1;const O={afterCreate(){r.history.canUndo},setCurrentTime(e){r.currentTime=e},_togglePlaying(e=!r.isPlaying){r.isPlaying=e},play({animatedElementsIds:e=[],startTime:t=0,currentTime:o=0,endTime:n=r.duration,repeat:a=!1}={}){o&&(console.warn("currentTime property of store.play() is deprecated. Please use startTime instead."),t=o),r.animatedElementsIds=i(e),r.currentTime=t,r.isPlaying=!0,l=Date.now(),d=n,g=a,requestAnimationFrame(()=>O.seek())},checkActivePage(){let e=0;for(const t of r.pages){if(r.currentTime>=t.startTime&&r.currentTime<t.startTime+t.duration){O.selectPage(t.id);break}e+=t.duration}},seek(){if(!r.isPlaying){return}const e=Date.now(),t=e-l;l=e,r.currentTime+=t,O.checkActivePage();const i=d||r.duration;r.isPlaying&&r.currentTime<i?requestAnimationFrame(()=>O.seek()):r.isPlaying&&g?(r.currentTime=0,requestAnimationFrame(()=>O.seek())):O.stop()},stop(){r.isPlaying=!1,r.currentTime=0,r.animatedElementsIds=i([]),O.checkActivePage()},__(){r._validated||(h(r._key,r._forceShowCredit),r._validated=!0)},set(e){Object.assign(r,e)},setUnit({unit:e,dpi:t}){r.unit=e||r.unit,r.dpi=t||r.dpi},setRole(e){r.role=e},setTool(e){r.tool=e},setToolOptions(e){Object.assign(r.toolOptions,e)},addPage(e){const t=S.create(Object.assign({id:c(10)},e));return r.pages.push(t),r._activePageId=t.id,t},selectPage(e){r._activePageId=e,1===r._selectedPagesIds.length&&(r._selectedPagesIds=i([e]))},selectPages(e){r._selectedPagesIds=i(e),1===r._selectedPagesIds.length&&(r._activePageId=r._selectedPagesIds[0])},selectElements(e){const t=e.map(e=>r.getElementById(e)).sort((e,t)=>e.page.children.indexOf(e)-e.page.children.indexOf(t)).filter(e=>!!e).map(e=>e.id);r.selectedElementsIds=i(t)},toggleBleed(e){r.bleedVisible=null!=e?e:!r.bleedVisible},toggleRulers(e){r.rulesVisible=null!=e?e:!r.rulesVisible},toggleDistanceGuides(e){r.distanceGuidesVisible=null!=e?e:!r.distanceGuidesVisible},openSidePanel(e){r.openedSidePanel!==e&&(r.previousOpenedSidePanel=r.openedSidePanel,r.openedSidePanel=e)},restoreSidePanel(){const e=r.previousOpenedSidePanel;e&&e!==r.openedSidePanel?r.openedSidePanel=e:r.openedSidePanel="photos"},setScale(e){r.scale=e},_setScaleToFit(e){r.scaleToFit=e},setElementsPixelRatio(e){r._elementsPixelRatio=e},setSize(e,t,i){r.pages.forEach(o=>{o.setSize({width:e,height:t,useMagic:i,softChange:!0})}),r.width=e,r.height=t},setPageZIndex(e,t){const i=r.pages.find(t=>t.id===e);i&&(n(i),r.pages.remove(i),r.pages.splice(t,0,i))},deletePages(e){const t=r.pages.indexOf(r.activePage);e.forEach(e=>{const t=r.pages.find(t=>t.id===e);o(t)});const n=Math.min(r.pages.length-1,t),a=r.pages[n];a&&(r._activePageId=a.id),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},groupElements(e,t={}){const o=e.map(e=>r.getElementById(e)),a=o[0].page;if(o.forEach(e=>{e&&n(e)}),!o.length){return}const s=a.children.reduce((e,t)=>{if("group"===t.type){const i=t.name.match(/group-(\d+)/);if(i){const t=parseInt(i[1],10);return Math.max(e,t)}}return e},0),l=Object.assign({id:c(10),name:`group-${s+1}`,children:o,type:"group"},t);return a.children.push(l),r.selectedElementsIds=i([l.id]),a.children.find(e=>e.id===l.id)},ungroupElements(e){const t=e.map(e=>r.getElementById(e)),o=[];t.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)}}),r.selectedElementsIds=i(o)},deleteElements(e){const t=[];r.find(i=>(e.includes(i.id)&&t.push(i),!1)),t.forEach(e=>{o(e)}),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},on(e,t){if("change"===e){let e=O.toJSON();return s(r,i=>{const o=O.toJSON();!x(e,o)&&(e=o,t(o))})}},async _toCanvas({pixelRatio:e,ignoreBackground:t,pageId:i,mimeType:o,includeBleed:n,_skipTimeout:a,quickMode:s=!1,_exportCanvases:l}={}){var d;const c=e||1;i=i||(null===(d=r.pages[0])||void 0===d?void 0:d.id);const g=r.pages.find(e=>e.id===i);if(!g){throw new Error(`No page for export with id ${i}`)}const m=r._elementsPixelRatio;c>r._elementsPixelRatio&&O.setElementsPixelRatio(c),s?null==g||g.set({_forceMount:!0}):null==g||g.set({_exporting:!0});const u=await _(()=>{const e=p.stages.filter(e=>e.getAttr("pageId")===i);return 0===e.length?null:e});if(!u){throw null==g||g.set({_forceMount:!1,_exporting:!1}),O.setElementsPixelRatio(m),new Error(`Export is failed. Can not find stage for page ${i}. Looks like <Workspace /> component is not mounted, but it is required in order to process the export.`)}u.length>1&&console.error(`Polotno error: Detected several canvas elements for page "${i}" in the document. This is not supported and will lead to incorrect export. Make sure to use unique ids for all pages and make sure you unmount <Workspace /> when it is not needed.`);const f=u[0];await O.waitLoading({_skipTimeout:a});const h=f.findOne(".page-container");if(!h){throw O.setElementsPixelRatio(m),null==g||g.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const b=f.position();f.position({x:0,y:0}),f.find("Transformer").forEach(e=>{e.setAttr("oldVisible",e.visible()),e.visible(!1)}),h.find(".page-background").forEach(e=>e.shadowEnabled(!1)),h.find(".page-background").forEach(e=>e.strokeEnabled(!1)),h.find(".highlighter").forEach(e=>e.visible(!1));const y=h.findOne(".page-background-group"),v=y.clip();y.clip({x:null,y:null,width:null,height:null});const w=h.findOne(".elements-container"),E=w.clip();w.clip({x:null,y:null,width:null,height:null});const x=h.find(e=>!e.visible()&&e.getAttr("editModeEnabled")&&!e.getAttr("hideInExport"));x.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()});const k=h.find(e=>e.getAttr("hideInExport"));k.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()}),t&&h.find(".page-background").forEach(e=>e.hide());const I=n?g.bleed:0;let S=I;!r.bleedVisible&&n||(r.bleedVisible||n?r.bleedVisible&&n?S=0:r.bleedVisible&&!n&&(S=-g.bleed):S=0);const T=g.computedWidth+2*I,j=g.computedHeight+2*I,R=h.scale();h.scale({x:1,y:1});const F=P(h,{x:h.x()-S,y:h.y()-S,width:T,height:j,pixelRatio:c,sceneCanvas:null==l?void 0:l.sceneCanvas,bufferCanvas:null==l?void 0:l.bufferCanvas});h.scale(R);const C=F._canvas;if("image/jpeg"===o){const e=C.getContext("2d");e.save(),e.globalCompositeOperation="destination-over",e.fillStyle="white",e.fillRect(0,0,C.width,C.height),e.restore()}return t&&h.find(".page-background").forEach(e=>e.show()),k.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),x.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),h.find(".page-background").forEach(e=>e.shadowEnabled(!0)),h.find(".page-background").forEach(e=>e.strokeEnabled(!0)),f.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),h.find(".highlighter").forEach(e=>e.visible(!0)),y.clip(v),w.clip(E),f.position(b),null==g||g.set({_exporting:!1,_forceMount:!1}),await Promise.resolve(),O.setElementsPixelRatio(m),C},async toDataURL(t={}){var{mimeType:i,quality:o,dpi:n,dpiMetadata:a="auto"}=t,s=e(t,["mimeType","quality","dpi","dpiMetadata"]);const l=await O._toCanvas(Object.assign({mimeType:i},s)),d=i||"image/png",c=l.toDataURL(d,o);p.Util.releaseCanvas(l);const g=null!=n?n:r.dpi;return"image/png"!==d&&"image/jpeg"!==d||"never"===a||"auto"===a&&72===g?c:v(c,d,g)},async toBlob(t={}){var{mimeType:i,quality:o}=t,n=e(t,["mimeType","quality"]);const a=await O._toCanvas(Object.assign({mimeType:i},n)),s=await new Promise(e=>{a.toBlob(e,i,o)});return p.Util.releaseCanvas(a),s},async saveAsImage(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=(o.mimeType||"image/png").split("/")[1];m(await O.toDataURL(o),i||"polotno."+n)},async _toPDF(e){const t=e.dpi||r.dpi,i=e.parallel||1,o=e.unit||("px"===r.unit?"mm":r.unit),n=e.pixelRatio||1,a=e.pageIds||r.pages.map(e=>e.id),s=r.pages.filter(e=>a.includes(e.id)),l=await u(),d=e=>E({px:e,unit:o,dpi:t}),c=e.cropMarkSize||0,p=d(c),g=s[0]||{},m=e.includeBleed?g.bleed:0,f=d(g.computedWidth+2*m+2*p),h=d(g.computedHeight+2*m+2*p);var b=new l({unit:o,orientation:f>h?"landscape":"portrait",format:[f,h],compress:!0,putOnlyUsedFonts:!0});b.deletePage(1);const y=((e,t)=>{const i=[];for(let o=0;o<e.length;o+=t){i.push(e.slice(o,o+t))}return i})(s,i);let v=0;for(const r of y){const t=r.map(async t=>{const i=e.includeBleed?t.bleed:0,o=t.computedWidth+2*i+2*c,s=t.computedHeight+2*i+2*c,r=d(o),l=d(s);let p=0,g=n;for(;p<10;){p+=1;const i=await O.toDataURL(Object.assign(Object.assign({},e),{pageId:t.id,pixelRatio:g,dpiMetadata:"never"}));if(i.length>20){return g!==n&&console.error(`Polotno can not export PDF with current settings. Quality is automatically reduced. pixelRatio was reduced to ${parseFloat(g.toFixed(3))}.`),e.onProgress&&e.onProgress(++v/a.length*.9),{url:i,width:r,height:l,widthPx:o,heightPx:s}}g*=.8}});(await Promise.all(t)).filter(e=>void 0!==e).forEach(({url:e,width:t,height:i,widthPx:n,heightPx:a})=>{b.addPage([t,i],t>i?"landscape":"portrait");const s=b.getCurrentPageInfo();var r;switch(o){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;default:throw"Invalid unit: "+o}if(s.pageContext.cropBox={bottomLeftX:0,bottomLeftY:0,topRightX:t*r,topRightY:i*r},s.pageContext.artBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(n-c-m)*r,topRightY:d(a-c-m)*r},s.pageContext.bleedBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(n-c-m)*r,topRightY:d(a-c-m)*r},p){b.setLineWidth(d(1));const e=p+d(m);b.line(e,0,e,p),b.line(0,e,p,e),b.line(t-e,0,t-e,p),b.line(t,e,t-p,e),b.line(0,i-e,p,i-e),b.line(e,i,e,i-p),b.line(t,i-e,t-p,i-e),b.line(t-e,i,t-e,i-p)}b.addImage(e,p,p,t-2*p,i-2*p,void 0,"FAST")})}return b},toPDFDataURL:async e=>(await O._toPDF(Object.assign({mimeType:"image/jpeg"},e))).output("datauristring"),async toGIFDataURL(e={}){const t=e.pixelRatio||1,i=await f({width:r.width*t,height:r.height*t}),o=1e3/(e.fps||10),n=r.duration/o;for(let a=0;a<n-1;a++){const e=a*o||1;O.setCurrentTime(e);let n=0,s="";for(const t of r.pages){if(n+=t.duration,t.set({_rendering:n>e}),n>e){s=t.id;break}}const l=await O._toCanvas({pixelRatio:t,pageId:s,_skipTimeout:!0});i.addFrame(l.getContext("2d"),{delay:o,copy:!0})}for(const a of r.pages){a.set({_rendering:!1})}return O.stop(),i.render(),new Promise(e=>{i.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(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=await O.toGIFDataURL(o);m(n,i||"polotno.gif")},async toHTML({elementHook:e}={}){const t=O.toJSON();return k({json:t,elementHook:e})},async saveAsHTML({fileName:e,elementHook:t}={}){const i=await O.toHTML({elementHook:t}),o="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));m(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:t,fontEmbedding:i="inline"}={fontEmbedding:"inline"}){var o;const n=O.toJSON();t=t||(null===(o=n.pages[0])||void 0===o?void 0:o.id);const a=n.pages.find(e=>e.id===t);return I({json:Object.assign(Object.assign({},n),{pages:a?[a]:[]}),elementHook:e,fontEmbedding:i})},async saveAsSVG({fileName:e,elementHook:t,pageId:i,fontEmbedding:o="inline"}={}){const n=await O.toSVG({elementHook:t,pageId:i,fontEmbedding:o}),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(n)));m(a,e||"polotno.svg")},async saveAsPDF(t={}){var{fileName:i}=t,o=e(t,["fileName"]);(await O._toPDF(Object.assign({mimeType:"image/jpeg"},o))).save(i||"polotno.pdf")},async waitLoading({_skipTimeout:e=!1}={}){e||await new Promise(e=>setTimeout(e,50)),await w()},toJSON:()=>({width:r.width,height:r.height,fonts:a(r.fonts),pages:a(r.pages),audios:a(r.audios),unit:r.unit,dpi:r.dpi,custom:r.custom,schemaVersion:r.schemaVersion}),loadJSON(e,i=!1){var o,n,s;const l="boolean"==typeof i?i:null!==(o=null==i?void 0:i.keepHistory)&&void 0!==o&&o,d="boolean"!=typeof i&&null!==(n=null==i?void 0:i.modernizeTextBackground)&&void 0!==n&&n,c=JSON.parse(JSON.stringify(e)),p=c.schemaVersion||0;p<1&&y.htmlRenderEnabled&&T({children:c.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),p<2&&T({children:c.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)})}),p<3&&y.htmlRenderEnabled&&!d&&T({children:c.pages},e=>{"text"===e.type&&e.backgroundEnabled&&(e.legacyBackground=!0)}),delete c.schemaVersion;const g=r.activePage?r.pages.indexOf(r.activePage):0;let m=null===(s=c.pages[g]||c.pages[0])||void 0===s?void 0:s.id;c._activePageId=m;const u=Object.assign({},a(r));Object.assign(u,c),u.history=l?a(r.history):{history:[],undoIdx:-1,targetPath:""},t(r,u)},clear({keepHistory:e=!1}={}){const t=r.pages.map(e=>e.id);O.deletePages(t),r.custom=null,e||r.history.clear()},addFont(e){O.removeFont(e.fontFamily),r.fonts.push(e)},removeFont(e){r.fonts.filter(t=>t.fontFamily===e).forEach(e=>o(e))},addAudio(e){const t=j.create(Object.assign({id:c(10)},e));r.audios.push(t)},removeAudio(e){const t=r.audios.find(t=>t.id===e);t&&r.audios.remove(t)},async loadFont(e,t,i,o){const n=r.fonts.find(t=>t.fontFamily===e)||b.globalFonts.find(t=>t.fontFamily===e);let a=[{fontStyle:"normal",fontWeight:"normal"},{fontStyle:"normal",fontWeight:"bold"}];return n?(n.styles&&(a=n.styles.map(e=>({fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"normal"}))),b.injectCustomFont(n)):b.injectGoogleFont(e),t&&i&&!a.some(e=>e.fontStyle===t&&e.fontWeight===i)&&a.push({fontStyle:t,fontWeight:i}),Promise.all(a.map(t=>b.loadFont(e,t.fontStyle,t.fontWeight,o)))},validate:e=>Store.validate(e,[{path:"",type:Store}]).map(e=>({path:"store"+e.context.map(e=>e.path).join("."),message:e.message}))};return O});export function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){return Store.create({_forceShowCredit:t,_key:e})}export default createStore;
@@ -5,6 +5,13 @@ export type BorderAttrs = {
5
5
  width?: number;
6
6
  style?: string;
7
7
  };
8
+ export type BorderMode = 'all' | 'outer' | 'inner' | 'topBottom' | 'topOnly' | 'bottomOnly' | 'leftOnly' | 'rightOnly' | 'innerHorizontal' | 'innerVertical';
9
+ export type CellRange = {
10
+ minRow: number;
11
+ maxRow: number;
12
+ minCol: number;
13
+ maxCol: number;
14
+ };
8
15
  export declare const TableCell: import("mobx-state-tree").IModelType<{
9
16
  id: import("mobx-state-tree").ISimpleType<string>;
10
17
  type: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<"tablecell">, [undefined]>;
@@ -419,8 +426,6 @@ export declare const TableElement: import("mobx-state-tree").IModelType<{
419
426
  _cellContentHeights: import("mobx").ObservableMap<string, number>;
420
427
  _baseRowHeights: number[] | null;
421
428
  _baseHeight: number | null;
422
- _isResizingRows: boolean;
423
- _isTransforming: boolean;
424
429
  } & {
425
430
  afterCreate(): void;
426
431
  } & {
@@ -429,6 +434,7 @@ export declare const TableElement: import("mobx-state-tree").IModelType<{
429
434
  } & {
430
435
  getCell(row: number, col: number): TableCellType | undefined;
431
436
  readonly minWidth: number;
437
+ getRowContentOuterHeight(row: number): number;
432
438
  readonly minHeight: number;
433
439
  readonly actualHeight: number;
434
440
  getCellRect(row: number, col: number, rowSpan?: number, colSpan?: number): {
@@ -440,6 +446,7 @@ export declare const TableElement: import("mobx-state-tree").IModelType<{
440
446
  readonly visibleCells: TableCellType[];
441
447
  readonly focusedCells: TableCellType[];
442
448
  readonly editingCell: TableCellType | undefined;
449
+ getFocusedCellRange(): CellRange | null;
443
450
  readonly _fitRowsToContent: {
444
451
  rowHeights: number[];
445
452
  height: number;
@@ -448,22 +455,28 @@ export declare const TableElement: import("mobx-state-tree").IModelType<{
448
455
  setCellContentHeight(cellId: string, height: number): void;
449
456
  _applyFitRowsToContent(): void;
450
457
  focusCell(cellId: string, addToSelection?: boolean): void;
458
+ selectRowRange(startRow: number, endRow: number): void;
459
+ selectColumnRange(startCol: number, endCol: number): void;
460
+ selectRow(rowIndex: number): void;
461
+ selectColumn(colIndex: number): void;
451
462
  focusCellRange(targetRow: number, targetCol: number): void;
452
463
  clearCellFocus(): void;
453
464
  enterCellEdit(cellId: string): void;
454
465
  exitCellEdit(): void;
455
466
  _resetBaseRowHeights(): void;
456
- _setIsResizingRows(value: boolean): void;
457
- _setIsTransforming(value: boolean): void;
467
+ setHeightRedistribute(newHeight: number): void;
458
468
  addRow(index: number): void;
459
469
  removeRow(index: number): void;
460
470
  addColumn(index: number): void;
461
471
  removeColumn(index: number): void;
472
+ removeRowRange(minRow: number, maxRow: number): void;
473
+ removeColumnRange(minCol: number, maxCol: number): void;
462
474
  distributeRowsEvenly(): void;
463
475
  distributeColumnsEvenly(): void;
464
476
  resizeColumn(index: number, delta: number): void;
465
477
  resizeRow(index: number, delta: number): void;
466
478
  setCellBorders(cellIds: string[], sides: BorderSideName[], attrs: BorderAttrs): void;
479
+ applyBorderMode(mode: BorderMode, attrs: BorderAttrs): void;
467
480
  } & {
468
481
  clone(attrs?: any, { skipSelect }?: {
469
482
  skipSelect?: boolean | undefined;
@@ -1 +1 @@
1
- import{types as e,getParent as t,getSnapshot as o,isAlive as l,getRoot as r,cast as n}from"mobx-state-tree";import{observable as s}from"mobx";import{nanoid as i}from"nanoid";import{Shape as d}from"./shape-model.js";const c=.05,a=e.enumeration(["solid","dashed","dotted","none"]);function g(e){return t(e,2)}function u(e,t,o){const r=e[`_${t}`];return null!=r?r:l(e)?g(e)[t]:o}function h(e){return t(e,1)}const f=e.model("BorderSide",{color:e.maybe(e.string),width:e.maybe(e.number),style:e.maybe(a)}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){null!=l&&(t[o]=l)}return t}),b=e.model("CellBorders",{top:e.maybe(f),right:e.maybe(f),bottom:e.maybe(f),left:e.maybe(f)}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){null!=l&&"object"==typeof l&&Object.keys(l).length>0&&(t[o]=l)}return t}),w=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],p=new Set(w),m=["blurEnabled","blurRadius","brightnessEnabled","brightness","sepiaEnabled","grayscaleEnabled","filters","shadowEnabled","shadowBlur","shadowOffsetX","shadowOffsetY","shadowColor","shadowOpacity"],_=["id","type","text","opacity","rowSpan","colSpan","mergedInto","name","custom","borders"],y=new Set(["row","col","x","y","width","height","rotation","draggable","resizable","selectable","removable","contentEditable","visible","showInExport","alwaysOnTop","backgroundEnabled","backgroundOpacity","backgroundColor","backgroundCornerRadius","backgroundPadding","curveEnabled","curvePower","shadowEnabled","shadowBlur","shadowOffsetX","shadowOffsetY","shadowColor","shadowOpacity","blurEnabled","blurRadius","brightnessEnabled","brightness","sepiaEnabled","grayscaleEnabled","placeholder","animations","filters"]),C={opacity:1,rowSpan:1,colSpan:1,name:""},v=[];export const TableCell=e.model("TableCell",{id:e.identifier,type:e.optional(e.literal("tablecell"),"tablecell"),text:"",_fontSize:e.maybe(e.number),_fontFamily:e.maybe(e.string),_fontWeight:e.maybe(e.string),_fontStyle:e.maybe(e.string),_textDecoration:e.maybe(e.string),_textTransform:e.maybe(e.string),_fill:e.maybe(e.string),_align:e.maybe(e.string),_verticalAlign:e.maybe(e.string),_lineHeight:e.maybe(e.union(e.number,e.string)),_letterSpacing:e.maybe(e.number),_strokeWidth:e.maybe(e.number),_stroke:e.maybe(e.string),_cellBackground:e.maybe(e.string),_cellPadding:e.maybe(e.number),opacity:1,rowSpan:1,colSpan:1,mergedInto:e.maybe(e.string),borders:e.maybe(b),name:"",custom:e.frozen()}).volatile(()=>({_editModeEnabled:!1,filters:s.map()})).preProcessSnapshot(e=>{if(!e){return e}for(const o in e){null===e[o]&&(e[o]=void 0)}const t={};for(const o of _){o in e&&(t[o]=e[o])}for(const o of w){void 0!==e[o]&&(t[`_${o}`]=e[o])}return t}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){if(o.startsWith("_")){null!=l&&(t[o.slice(1)]=l)}else if("borders"===o){null!=l&&"object"==typeof l&&Object.keys(l).length>0&&(t.borders=l)}else{if(o in C&&l===C[o]){continue}t[o]=l}}return t}).views(e=>{const t={get row(){if(!l(e)){return 0}const t=g(e),o=h(e).indexOf(e);return-1===o?0:Math.floor(o/t.cols)},get col(){if(!l(e)){return 0}const t=g(e),o=h(e).indexOf(e);return-1===o?0:o%t.cols},get store(){return l(e)?r(e):null},get page(){if(!l(e)){return null}try{return g(e).page}catch(t){return null}},get fontSize(){return u(e,"fontSize",30)},get fontFamily(){return u(e,"fontFamily","Roboto")},get fontWeight(){return u(e,"fontWeight","normal")},get fontStyle(){return u(e,"fontStyle","normal")},get textDecoration(){return u(e,"textDecoration","")},get textTransform(){return u(e,"textTransform","none")},get fill(){return u(e,"fill","black")},get align(){return u(e,"align","left")},get verticalAlign(){return u(e,"verticalAlign","top")},get lineHeight(){return u(e,"lineHeight",1.2)},get letterSpacing(){return u(e,"letterSpacing",0)},get strokeWidth(){return u(e,"strokeWidth",0)},get stroke(){return u(e,"stroke","black")},get cellBackground(){return u(e,"cellBackground","transparent")},get cellPadding(){return u(e,"cellPadding",4)},get width(){if(!l(e)){return 100}try{return g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan).width}catch(o){return 100}},get height(){if(!l(e)){return 100}try{return g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan).height}catch(o){return 100}},get a(){var o;if(!l(e)){return{x:0,y:0,width:100,height:100,rotation:0,opacity:1,fontSize:16}}const r=g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan),n=t.cellPadding;return{x:r.x+n,y:r.y+n,width:r.width-2*n,height:r.height-2*n,rotation:0,opacity:null!==(o=e.opacity)&&void 0!==o?o:1,fontSize:t.fontSize}},getEffectiveBorder(t){var o,r,n,s,i,d,c;const a=l(e)?g(e):null,u=null===(o=e.borders)||void 0===o?void 0:o[t];return{color:null!==(n=null!==(r=null==u?void 0:u.color)&&void 0!==r?r:null==a?void 0:a.borderColor)&&void 0!==n?n:"#000000",width:null!==(i=null!==(s=null==u?void 0:u.width)&&void 0!==s?s:null==a?void 0:a.borderWidth)&&void 0!==i?i:1,style:null!==(c=null!==(d=null==u?void 0:u.style)&&void 0!==d?d:null==a?void 0:a.borderStyle)&&void 0!==c?c:"solid"}},get x(){return 0},get y(){return 0},get rotation(){return 0},get draggable(){return!1},get resizable(){return!1},get selectable(){return!1},get removable(){return!1},get contentEditable(){return!0},get visible(){return!0},get showInExport(){return!0},get alwaysOnTop(){return!1},get placeholder(){return""},get backgroundEnabled(){return!1},get backgroundOpacity(){return 1},get backgroundColor(){return"transparent"},get backgroundCornerRadius(){return 0},get backgroundPadding(){return 0},get curveEnabled(){return!1},get curvePower(){return 0},get shadowEnabled(){return!1},get shadowBlur(){return 0},get shadowOffsetX(){return 0},get shadowOffsetY(){return 0},get shadowColor(){return"black"},get shadowOpacity(){return 1},get blurEnabled(){return!1},get blurRadius(){return 0},get brightnessEnabled(){return!1},get brightness(){return 0},get sepiaEnabled(){return!1},get grayscaleEnabled(){return!1},get animations(){return v}};return t}).actions(e=>({toJSON:()=>Object.assign({},o(e)),set(t){null!=t.fontSize&&t.fontSize<1&&(t=Object.assign(Object.assign({},t),{fontSize:1}));const o={};for(const[e,l]of Object.entries(t)){p.has(e)?o[`_${e}`]=l:"borders"===e?o.borders=l?JSON.parse(JSON.stringify(l)):l:y.has(e)||(o[e]=l)}Object.assign(e,o)},setBorder(t,l){const r=e.borders?Object.assign({},o(e.borders)):{},s=r[t]||{},i=Object.assign({},s);void 0!==l.color&&(i.color=l.color),void 0!==l.width&&(i.width=l.width),void 0!==l.style&&(i.style=l.style),r[t]=i,e.borders=n(r)},toggleEditMode(t){const o=null!=t?t:!e._editModeEnabled;o!==e._editModeEnabled&&(e._editModeEnabled=o,e._editModeEnabled?e.store.history.startTransaction():e.store.history.endTransaction())}}));function S(e){return Array.from({length:e},()=>1/e)}function H(e){const t=e.reduce((e,t)=>e+t,0);return 0===t?S(e.length):e.map(e=>e/t)}export const TableElement=d.named("Table").props({type:"table",width:300,height:200,rows:3,cols:3,colWidths:e.array(e.number),rowHeights:e.array(e.number),cells:e.array(TableCell),borderColor:"#000000",borderWidth:1,borderStyle:e.optional(e.enumeration(["solid","dashed","dotted","none"]),"solid"),fontSize:30,fontFamily:"Roboto",fontWeight:"normal",fontStyle:"normal",textDecoration:"",textTransform:"none",fill:"black",align:"left",verticalAlign:"top",lineHeight:e.optional(e.union(e.number,e.string),1.2),letterSpacing:0,strokeWidth:0,stroke:"black",cellBackground:"transparent",cellPadding:4}).postProcessSnapshot(e=>{e.cells&&((e=Object.assign({},e)).cells=e.cells.map(t=>{const o={};for(const[l,r]of Object.entries(t)){p.has(l)&&r===e[l]||(o[l]=r)}return o}));for(const t of m){delete e[t]}return e}).volatile(()=>({_focusedCellIds:[],_editingCellId:void 0,_anchorCellId:void 0,_cellContentHeights:s.map(),_baseRowHeights:null,_baseHeight:null,_isResizingRows:!1,_isTransforming:!1})).actions(e=>({afterCreate(){const t=e.rows*e.cols;if(0===e.cells.length){e.cells.replace(n(function(e,t){const o=[];for(let l=0;l<e*t;l++){o.push({id:i(10),text:""})}return o}(e.rows,e.cols)))}else if(e.cells.length<t){for(;e.cells.length<t;){e.cells.push(n({id:i(10),text:""}))}}else{e.cells.length>t&&e.cells.splice(t)}0===e.colWidths.length&&e.colWidths.replace(S(e.cols)),0===e.rowHeights.length&&e.rowHeights.replace(S(e.rows))}})).views(e=>({get _cellMap(){const t=new Map,o=e.cols;return e.cells.forEach((e,l)=>{t.set(`${Math.floor(l/o)}:${l%o}`,e)}),t},getActualRowHeight:t=>e.rowHeights[t]*e.height})).views(e=>{const t={getCell:(t,o)=>e._cellMap.get(`${t}:${o}`),get minWidth(){return 20*e.cols},get minHeight(){return 20*e.rows},get actualHeight(){let t=0;for(let o=0;o<e.rows;o++){t+=e.getActualRowHeight(o)}return t},getCellRect(t,o,l=1,r=1){let n=0;for(let c=0;c<o;c++){n+=e.colWidths[c]*e.width}let s=0;for(let c=0;c<t;c++){s+=e.getActualRowHeight(c)}let i=0;for(let c=o;c<o+r;c++){i+=(e.colWidths[c]||0)*e.width}let d=0;for(let c=t;c<t+l;c++){d+=e.getActualRowHeight(c)}return{x:n,y:s,width:i,height:d}},get visibleCells(){return e.cells.filter(e=>!e.mergedInto)},get focusedCells(){return e.cells.filter(t=>e._focusedCellIds.includes(t.id))},get editingCell(){if(e._editingCellId){return e.cells.find(t=>t.id===e._editingCellId)}},get _fitRowsToContent(){var o,l;if(e._isResizingRows){return null}if(e._isTransforming){return null}if(0===e._cellContentHeights.size){return null}const r=null!==(o=e._baseHeight)&&void 0!==o?o:e.height,n=null!==(l=e._baseRowHeights)&&void 0!==l?l:[...e.rowHeights];let s=!1;const i=[];for(let c=0;c<e.rows;c++){const o=e.rowHeights[c]*e.height,l=n[c]*r;let d=0;for(let r=0;r<e.cols;r++){const o=t.getCell(c,r);if(!o){continue}const l=e._cellContentHeights.get(o.id);if(void 0!==l){const e=l+2*o.cellPadding;d=Math.max(d,e)}}const a=Math.max(d,l);Math.abs(a-o)>1?(i.push(a),s=!0):i.push(o)}if(!s){return null}const d=i.reduce((e,t)=>e+t,0);return{rowHeights:i.map(e=>e/d),height:d}}};return t}).actions(e=>{const t={setCellContentHeight(t,o){e._cellContentHeights.set(t,o)},_applyFitRowsToContent(){null===e._baseRowHeights&&(e._baseRowHeights=[...e.rowHeights],e._baseHeight=e.height);const t=e._fitRowsToContent;t&&(e.height=t.height,e.rowHeights.replace(t.rowHeights))},focusCell(t,o=!1){o?e._focusedCellIds.includes(t)||(e._focusedCellIds=[...e._focusedCellIds,t]):(e._focusedCellIds=[t],e._anchorCellId=t)},focusCellRange(t,o){const l=e.cells.find(t=>t.id===e._anchorCellId);if(!l){return}const r=Math.min(l.row,t),n=Math.max(l.row,t),s=Math.min(l.col,o),i=Math.max(l.col,o),d=[];for(const c of e.cells){c.row>=r&&c.row<=n&&c.col>=s&&c.col<=i&&d.push(c.id)}e._focusedCellIds=d},clearCellFocus(){if(l(e)){if(e._editingCellId){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1)}e._focusedCellIds=[],e._editingCellId=void 0,e._anchorCellId=void 0}},enterCellEdit(t){e._editingCellId=t,e._focusedCellIds.includes(t)||(e._focusedCellIds=[t]);const o=e.cells.find(e=>e.id===t);o&&o.toggleEditMode(!0)},exitCellEdit(){if(e._editingCellId){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1)}e._editingCellId=void 0},_resetBaseRowHeights(){e._baseRowHeights=null,e._baseHeight=null},_setIsResizingRows(t){e._isResizingRows=t},_setIsTransforming(t){e._isTransforming=t},addRow(o){t._resetBaseRowHeights();const l=o>0?o-1:0,r=(e.rowHeights[l]||1/(e.rows+1))*e.height,s=e.height+r,d=[];for(let t=0;t<e.rows;t++){d.push(e.rowHeights[t]*e.height/s)}d.splice(o,0,r/s);const c=o*e.cols,a=Array.from({length:e.cols},()=>({id:i(10),text:""}));e.cells.splice(c,0,...n(a)),e.rows+=1,e.height=s,e.rowHeights.replace(H(d))},removeRow(o){if(e.rows<=1){return}t._resetBaseRowHeights();const l=o*e.cols,r=[];for(let t=l;t<l+e.cols;t++){r.push(e.cells[t].id)}if(e._editingCellId&&r.includes(e._editingCellId)){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1),e._editingCellId=void 0}e._focusedCellIds=e._focusedCellIds.filter(e=>!r.includes(e)),r.forEach(t=>e._cellContentHeights.delete(t)),e.cells.splice(l,e.cols);const n=[...e.rowHeights];n.splice(o,1),e.rows-=1,e.rowHeights.replace(H(n))},addColumn(t){const o=t>0?t-1:0,l=(e.colWidths[o]||1/(e.cols+1))*e.width,r=e.width+l,s=[];for(let n=0;n<e.cols;n++){s.push(e.colWidths[n]*e.width/r)}s.splice(t,0,l/r);const d=e.cols;for(let c=e.rows-1;c>=0;c--){e.cells.splice(c*d+t,0,n({id:i(10),text:""}))}e.cols+=1,e.width=r,e.colWidths.replace(H(s))},removeColumn(t){if(e.cols<=1){return}const o=e.cols,l=[];for(let n=0;n<e.rows;n++){l.push(e.cells[n*o+t].id)}if(e._editingCellId&&l.includes(e._editingCellId)){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1),e._editingCellId=void 0}e._focusedCellIds=e._focusedCellIds.filter(e=>!l.includes(e)),l.forEach(t=>e._cellContentHeights.delete(t));for(let n=e.rows-1;n>=0;n--){e.cells.splice(n*o+t,1)}const r=[...e.colWidths];r.splice(t,1),e.cols-=1,e.colWidths.replace(H(r))},distributeRowsEvenly(){t._resetBaseRowHeights(),e.rowHeights.replace(S(e.rows))},distributeColumnsEvenly(){e.colWidths.replace(S(e.cols))},resizeColumn(t,o){if(t>=e.cols-1){return}const l=[...e.colWidths],r=l[t]+l[t+1],n=l[t]+o,s=l[t+1]-o;n<c?(l[t]=c,l[t+1]=r-c):s<c?(l[t+1]=c,l[t]=r-c):(l[t]=n,l[t+1]=s),e.colWidths.replace(l)},resizeRow(t,o){if(t>=e.rows-1){return}const l=[...e.rowHeights],r=l[t]+l[t+1],n=l[t]+o,s=l[t+1]-o;n<c?(l[t]=c,l[t+1]=r-c):s<c?(l[t+1]=c,l[t]=r-c):(l[t]=n,l[t+1]=s),e.rowHeights.replace(l)},setCellBorders(t,o,l){const r={top:{side:"bottom",dr:-1,dc:0},bottom:{side:"top",dr:1,dc:0},left:{side:"right",dr:0,dc:-1},right:{side:"left",dr:0,dc:1}};for(const n of t){const t=e.cells.find(e=>e.id===n);if(t){for(const n of o){t.setBorder(n,l);const o=r[n],s=t.row+o.dr,i=t.col+o.dc,d=e.getCell(s,i);d&&d.setBorder(o.side,l)}}}}};return t}).actions(e=>({clone(t={},{skipSelect:o=!1}={}){const l=JSON.parse(JSON.stringify(e.toJSON()));if(t.id=t.id||i(10),l.cells){const e=new Map;l.cells.forEach(t=>{const o=t.id,l=i(10);e.set(o,l),t.id=l}),l.cells.forEach(t=>{t.mergedInto&&e.has(t.mergedInto)&&(t.mergedInto=e.get(t.mergedInto))})}return Object.assign(l,t),e.page.addElement(l,{skipSelect:o})}}));
1
+ import{types as e,getParent as t,getSnapshot as o,isAlive as l,getRoot as r,cast as n}from"mobx-state-tree";import{observable as s}from"mobx";import{nanoid as i}from"nanoid";import{Shape as c}from"./shape-model.js";const d=.05,a=e.enumeration(["solid","dashed","dotted","none"]);function g(e){return t(e,2)}function u(e,t,o){const r=e[`_${t}`];return null!=r?r:l(e)?g(e)[t]:o}function h(e){return t(e,1)}const f=e.model("BorderSide",{color:e.maybe(e.string),width:e.maybe(e.number),style:e.maybe(a)}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){null!=l&&(t[o]=l)}return t}),b=e.model("CellBorders",{top:e.maybe(f),right:e.maybe(f),bottom:e.maybe(f),left:e.maybe(f)}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){null!=l&&"object"==typeof l&&Object.keys(l).length>0&&(t[o]=l)}return t}),w=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],m=new Set(w),p=["blurEnabled","blurRadius","brightnessEnabled","brightness","sepiaEnabled","grayscaleEnabled","filters","shadowEnabled","shadowBlur","shadowOffsetX","shadowOffsetY","shadowColor","shadowOpacity"],C=["id","type","text","opacity","rowSpan","colSpan","mergedInto","name","custom","borders"],_=new Set(["row","col","x","y","width","height","rotation","draggable","resizable","selectable","removable","contentEditable","visible","showInExport","alwaysOnTop","backgroundEnabled","backgroundOpacity","backgroundColor","backgroundCornerRadius","backgroundPadding","curveEnabled","curvePower","shadowEnabled","shadowBlur","shadowOffsetX","shadowOffsetY","shadowColor","shadowOpacity","blurEnabled","blurRadius","brightnessEnabled","brightness","sepiaEnabled","grayscaleEnabled","placeholder","animations","filters"]),y={opacity:1,rowSpan:1,colSpan:1,name:""},v=[];export const TableCell=e.model("TableCell",{id:e.identifier,type:e.optional(e.literal("tablecell"),"tablecell"),text:"",_fontSize:e.maybe(e.number),_fontFamily:e.maybe(e.string),_fontWeight:e.maybe(e.string),_fontStyle:e.maybe(e.string),_textDecoration:e.maybe(e.string),_textTransform:e.maybe(e.string),_fill:e.maybe(e.string),_align:e.maybe(e.string),_verticalAlign:e.maybe(e.string),_lineHeight:e.maybe(e.union(e.number,e.string)),_letterSpacing:e.maybe(e.number),_strokeWidth:e.maybe(e.number),_stroke:e.maybe(e.string),_cellBackground:e.maybe(e.string),_cellPadding:e.maybe(e.number),opacity:1,rowSpan:1,colSpan:1,mergedInto:e.maybe(e.string),borders:e.maybe(b),name:"",custom:e.frozen()}).volatile(()=>({_editModeEnabled:!1,filters:s.map()})).preProcessSnapshot(e=>{if(!e){return e}for(const o in e){null===e[o]&&(e[o]=void 0)}const t={};for(const o of C){o in e&&(t[o]=e[o])}for(const o of w){void 0!==e[o]&&(t[`_${o}`]=e[o])}return t}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){if(o.startsWith("_")){null!=l&&(t[o.slice(1)]=l)}else if("borders"===o){null!=l&&"object"==typeof l&&Object.keys(l).length>0&&(t.borders=l)}else{if(o in y&&l===y[o]){continue}t[o]=l}}return t}).views(e=>{const t={get row(){if(!l(e)){return 0}const t=g(e),o=h(e).indexOf(e);return-1===o?0:Math.floor(o/t.cols)},get col(){if(!l(e)){return 0}const t=g(e),o=h(e).indexOf(e);return-1===o?0:o%t.cols},get store(){return l(e)?r(e):null},get page(){if(!l(e)){return null}try{return g(e).page}catch(t){return null}},get fontSize(){return u(e,"fontSize",30)},get fontFamily(){return u(e,"fontFamily","Roboto")},get fontWeight(){return u(e,"fontWeight","normal")},get fontStyle(){return u(e,"fontStyle","normal")},get textDecoration(){return u(e,"textDecoration","")},get textTransform(){return u(e,"textTransform","none")},get fill(){return u(e,"fill","black")},get align(){return u(e,"align","left")},get verticalAlign(){return u(e,"verticalAlign","top")},get lineHeight(){return u(e,"lineHeight",1.2)},get letterSpacing(){return u(e,"letterSpacing",0)},get strokeWidth(){return u(e,"strokeWidth",0)},get stroke(){return u(e,"stroke","black")},get cellBackground(){return u(e,"cellBackground","transparent")},get cellPadding(){return u(e,"cellPadding",4)},get width(){if(!l(e)){return 100}try{return g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan).width}catch(o){return 100}},get height(){if(!l(e)){return 100}try{return g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan).height}catch(o){return 100}},get a(){var o;if(!l(e)){return{x:0,y:0,width:100,height:100,rotation:0,opacity:1,fontSize:16}}const r=g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan),n=t.cellPadding,s=e=>"none"===e.style?0:e.width,i=s(t.getEffectiveBorder("top")),c=s(t.getEffectiveBorder("right")),d=s(t.getEffectiveBorder("bottom")),a=s(t.getEffectiveBorder("left"));return{x:r.x+a+n,y:r.y+i+n,width:Math.max(0,r.width-a-c-2*n),height:Math.max(0,r.height-i-d-2*n),rotation:0,opacity:null!==(o=e.opacity)&&void 0!==o?o:1,fontSize:t.fontSize}},getEffectiveBorder(t){var o,r,n,s,i,c,d;const a=l(e)?g(e):null,u=null===(o=e.borders)||void 0===o?void 0:o[t];return{color:null!==(n=null!==(r=null==u?void 0:u.color)&&void 0!==r?r:null==a?void 0:a.borderColor)&&void 0!==n?n:"#000000",width:null!==(i=null!==(s=null==u?void 0:u.width)&&void 0!==s?s:null==a?void 0:a.borderWidth)&&void 0!==i?i:1,style:null!==(d=null!==(c=null==u?void 0:u.style)&&void 0!==c?c:null==a?void 0:a.borderStyle)&&void 0!==d?d:"solid"}},get x(){return 0},get y(){return 0},get rotation(){return 0},get draggable(){return!1},get resizable(){return!1},get selectable(){return!1},get removable(){return!1},get contentEditable(){return!0},get visible(){return!0},get showInExport(){return!0},get alwaysOnTop(){return!1},get placeholder(){return""},get backgroundEnabled(){return!1},get backgroundOpacity(){return 1},get backgroundColor(){return"transparent"},get backgroundCornerRadius(){return 0},get backgroundPadding(){return 0},get curveEnabled(){return!1},get curvePower(){return 0},get shadowEnabled(){return!1},get shadowBlur(){return 0},get shadowOffsetX(){return 0},get shadowOffsetY(){return 0},get shadowColor(){return"black"},get shadowOpacity(){return 1},get blurEnabled(){return!1},get blurRadius(){return 0},get brightnessEnabled(){return!1},get brightness(){return 0},get sepiaEnabled(){return!1},get grayscaleEnabled(){return!1},get animations(){return v}};return t}).actions(e=>({toJSON:()=>Object.assign({},o(e)),set(t){null!=t.fontSize&&t.fontSize<1&&(t=Object.assign(Object.assign({},t),{fontSize:1}));const o={};for(const[e,l]of Object.entries(t)){m.has(e)?o[`_${e}`]=l:"borders"===e?o.borders=l?JSON.parse(JSON.stringify(l)):l:_.has(e)||(o[e]=l)}Object.assign(e,o)},setBorder(t,l){const r=e.borders?Object.assign({},o(e.borders)):{},s=r[t]||{},i=Object.assign({},s);void 0!==l.color&&(i.color=l.color),void 0!==l.width&&(i.width=l.width),void 0!==l.style&&(i.style=l.style),r[t]=i,e.borders=n(r)},toggleEditMode(t){const o=null!=t?t:!e._editModeEnabled;o!==e._editModeEnabled&&(e._editModeEnabled=o,e._editModeEnabled?e.store.history.startTransaction():e.store.history.endTransaction())}}));function H(e,t){const l=[];for(const r of e){const e={id:i(10),text:""};if(!r){l.push(e);continue}for(const t of w){const o=r[`_${t}`];null!=o&&(e[t]=o)}const n=r.borders;if(n){const l={},r=t?["left","right","top"]:["top","bottom","left"];for(const e of r){const t=n[e];t&&(l[e]=o(t))}Object.keys(l).length>0&&(e.borders=l)}l.push(e)}return l}function I(e){return Array.from({length:e},()=>1/e)}function R(e){const t=e.reduce((e,t)=>e+t,0);return 0===t?I(e.length):e.map(e=>e/t)}export const TableElement=c.named("Table").props({type:"table",width:300,height:200,rows:3,cols:3,colWidths:e.array(e.number),rowHeights:e.array(e.number),cells:e.array(TableCell),borderColor:"#000000",borderWidth:1,borderStyle:e.optional(e.enumeration(["solid","dashed","dotted","none"]),"solid"),fontSize:30,fontFamily:"Roboto",fontWeight:"normal",fontStyle:"normal",textDecoration:"",textTransform:"none",fill:"black",align:"center",verticalAlign:"middle",lineHeight:e.optional(e.union(e.number,e.string),1.2),letterSpacing:0,strokeWidth:0,stroke:"black",cellBackground:"transparent",cellPadding:4}).postProcessSnapshot(e=>{e.cells&&((e=Object.assign({},e)).cells=e.cells.map(t=>{const o={};for(const[l,r]of Object.entries(t)){m.has(l)&&r===e[l]||(o[l]=r)}return o}));for(const t of p){delete e[t]}return e}).volatile(()=>({_focusedCellIds:[],_editingCellId:void 0,_anchorCellId:void 0,_cellContentHeights:s.map(),_baseRowHeights:null,_baseHeight:null})).actions(e=>({afterCreate(){const t=e.rows*e.cols;if(0===e.cells.length){e.cells.replace(n(function(e,t){const o=[];for(let l=0;l<e*t;l++){o.push({id:i(10),text:""})}return o}(e.rows,e.cols)))}else if(e.cells.length<t){for(;e.cells.length<t;){e.cells.push(n({id:i(10),text:""}))}}else{e.cells.length>t&&e.cells.splice(t)}0===e.colWidths.length&&e.colWidths.replace(I(e.cols)),0===e.rowHeights.length&&e.rowHeights.replace(I(e.rows))}})).views(e=>({get _cellMap(){const t=new Map,o=e.cols;return e.cells.forEach((e,l)=>{t.set(`${Math.floor(l/o)}:${l%o}`,e)}),t},getActualRowHeight:t=>e.rowHeights[t]*e.height})).views(e=>{const t={getCell:(t,o)=>e._cellMap.get(`${t}:${o}`),get minWidth(){return 20*e.cols},getRowContentOuterHeight(o){let l=0;for(let r=0;r<e.cols;r++){const n=t.getCell(o,r);if(!n){continue}const s=e._cellContentHeights.get(n.id);void 0!==s&&(l=Math.max(l,s+2*n.cellPadding))}return l},get minHeight(){const o=20*e.rows;if(0===e._cellContentHeights.size){return o}let l=0;for(let r=0;r<e.rows;r++){l+=t.getRowContentOuterHeight(r)}return Math.max(o,l)},get actualHeight(){let t=0;for(let o=0;o<e.rows;o++){t+=e.getActualRowHeight(o)}return t},getCellRect(t,o,l=1,r=1){let n=0;for(let d=0;d<o;d++){n+=e.colWidths[d]*e.width}let s=0;for(let d=0;d<t;d++){s+=e.getActualRowHeight(d)}let i=0;for(let d=o;d<o+r;d++){i+=(e.colWidths[d]||0)*e.width}let c=0;for(let d=t;d<t+l;d++){c+=e.getActualRowHeight(d)}return{x:n,y:s,width:i,height:c}},get visibleCells(){return e.cells.filter(e=>!e.mergedInto)},get focusedCells(){return e.cells.filter(t=>e._focusedCellIds.includes(t.id))},get editingCell(){if(e._editingCellId){return e.cells.find(t=>t.id===e._editingCellId)}},getFocusedCellRange(){if(0===e._focusedCellIds.length){return null}let t=1/0,o=-1/0,l=1/0,r=-1/0;const n=new Set(e._focusedCellIds);for(const s of e.cells){n.has(s.id)&&(s.row<t&&(t=s.row),s.row>o&&(o=s.row),s.col<l&&(l=s.col),s.col>r&&(r=s.col))}return t===1/0?null:{minRow:t,maxRow:o,minCol:l,maxCol:r}},get _fitRowsToContent(){var o,l;if(0===e._cellContentHeights.size){return null}const r=null!==(o=e._baseHeight)&&void 0!==o?o:e.height,n=null!==(l=e._baseRowHeights)&&void 0!==l?l:[...e.rowHeights];let s=!1;const i=[];for(let d=0;d<e.rows;d++){const o=e.rowHeights[d]*e.height,l=n[d]*r;let c=0;for(let r=0;r<e.cols;r++){const o=t.getCell(d,r);if(!o){continue}const l=e._cellContentHeights.get(o.id);if(void 0!==l){const e=l+2*o.cellPadding;c=Math.max(c,e)}}const a=Math.max(c,l);Math.abs(a-o)>1?(i.push(a),s=!0):i.push(o)}if(!s){return null}const c=i.reduce((e,t)=>e+t,0);return{rowHeights:i.map(e=>e/c),height:c}}};return t}).actions(e=>{const t={setCellContentHeight(t,o){e._cellContentHeights.set(t,o)},_applyFitRowsToContent(){null===e._baseRowHeights&&(e._baseRowHeights=[...e.rowHeights],e._baseHeight=e.height);const t=e._fitRowsToContent;t&&(e.height=t.height,e.rowHeights.replace(t.rowHeights))},focusCell(t,o=!1){o?e._focusedCellIds.includes(t)||(e._focusedCellIds=[...e._focusedCellIds,t]):(e._focusedCellIds=[t],e._anchorCellId=t)},selectRowRange(t,o){const l=Math.max(0,Math.min(t,o)),r=Math.min(e.rows-1,Math.max(t,o)),n=[];for(let s=l;s<=r;s++){for(let t=0;t<e.cols;t++){const o=e.getCell(s,t);o&&n.push(o.id)}}e._focusedCellIds=n,e._anchorCellId=n[0]},selectColumnRange(t,o){const l=Math.max(0,Math.min(t,o)),r=Math.min(e.cols-1,Math.max(t,o)),n=[];for(let s=0;s<e.rows;s++){for(let t=l;t<=r;t++){const o=e.getCell(s,t);o&&n.push(o.id)}}e._focusedCellIds=n,e._anchorCellId=n[0]},selectRow(e){t.selectRowRange(e,e)},selectColumn(e){t.selectColumnRange(e,e)},focusCellRange(t,o){const l=e.cells.find(t=>t.id===e._anchorCellId);if(!l){return}const r=Math.min(l.row,t),n=Math.max(l.row,t),s=Math.min(l.col,o),i=Math.max(l.col,o),c=[];for(const d of e.cells){d.row>=r&&d.row<=n&&d.col>=s&&d.col<=i&&c.push(d.id)}e._focusedCellIds=c},clearCellFocus(){if(l(e)){if(e._editingCellId){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1)}e._focusedCellIds=[],e._editingCellId=void 0,e._anchorCellId=void 0}},enterCellEdit(t){e._editingCellId=t,e._focusedCellIds.includes(t)||(e._focusedCellIds=[t]);const o=e.cells.find(e=>e.id===t);o&&o.toggleEditMode(!0)},exitCellEdit(){if(e._editingCellId){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1)}e._editingCellId=void 0},_resetBaseRowHeights(){e._baseRowHeights=null,e._baseHeight=null},setHeightRedistribute(t){const o=e.rows;if(0===o||t<=0){return void(e.height=t)}const l=e.height;if(l<=0||t>=l){return void(e.height=t)}const r=[],n=[];let s=0;for(let u=0;u<o;u++){r.push(e.rowHeights[u]*l);const t=e.getRowContentOuterHeight(u);n.push(t),s+=t}if(t<=s||s<=0){return void(e.height=t)}const i=t-s;let c=0;const d=[];for(let e=0;e<o;e++){const t=Math.max(0,r[e]-n[e]);d.push(t),c+=t}const a=[];if(c<=0){const e=t/l;for(let t=0;t<o;t++){a.push(r[t]*e)}}else{for(let e=0;e<o;e++){a.push(n[e]+d[e]/c*i)}}const g=a.map(e=>e/t);e.height=t,e.rowHeights.replace(g)},addRow(o){t._resetBaseRowHeights();const l=o>0?o-1:0,r=(e.rowHeights[l]||1/(e.rows+1))*e.height,s=e.height+r,i=[];for(let t=0;t<e.rows;t++){i.push(e.rowHeights[t]*e.height/s)}i.splice(o,0,r/s);const c=o>0?o-1:0,d=[];for(let t=0;t<e.cols;t++){d.push(e.cells[c*e.cols+t])}const a=o*e.cols,g=H(d,!0);e.cells.splice(a,0,...n(g)),e.rows+=1,e.height=s,e.rowHeights.replace(R(i))},removeRow(o){if(e.rows<=1){return}t._resetBaseRowHeights();const l=o*e.cols,r=[];for(let t=l;t<l+e.cols;t++){r.push(e.cells[t].id)}if(e._editingCellId&&r.includes(e._editingCellId)){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1),e._editingCellId=void 0}e._focusedCellIds=e._focusedCellIds.filter(e=>!r.includes(e)),r.forEach(t=>e._cellContentHeights.delete(t)),e.cells.splice(l,e.cols);const n=[...e.rowHeights];n.splice(o,1),e.rows-=1,e.rowHeights.replace(R(n))},addColumn(t){const o=t>0?t-1:0,l=(e.colWidths[o]||1/(e.cols+1))*e.width,r=e.width+l,s=[];for(let n=0;n<e.cols;n++){s.push(e.colWidths[n]*e.width/r)}s.splice(t,0,l/r);const i=e.cols,c=t>0?t-1:0,d=[];for(let n=0;n<e.rows;n++){d.push(e.cells[n*i+c])}const a=H(d,!1);for(let g=e.rows-1;g>=0;g--){e.cells.splice(g*i+t,0,n(a[g]))}e.cols+=1,e.width=r,e.colWidths.replace(R(s))},removeColumn(t){if(e.cols<=1){return}const o=e.cols,l=[];for(let n=0;n<e.rows;n++){l.push(e.cells[n*o+t].id)}if(e._editingCellId&&l.includes(e._editingCellId)){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1),e._editingCellId=void 0}e._focusedCellIds=e._focusedCellIds.filter(e=>!l.includes(e)),l.forEach(t=>e._cellContentHeights.delete(t));for(let n=e.rows-1;n>=0;n--){e.cells.splice(n*o+t,1)}const r=[...e.colWidths];r.splice(t,1),e.cols-=1,e.colWidths.replace(R(r))},removeRowRange(o,l){for(let r=l;r>=o&&!(e.rows<=1);r--){t.removeRow(r)}},removeColumnRange(o,l){for(let r=l;r>=o&&!(e.cols<=1);r--){t.removeColumn(r)}},distributeRowsEvenly(){t._resetBaseRowHeights(),e.rowHeights.replace(I(e.rows))},distributeColumnsEvenly(){e.colWidths.replace(I(e.cols))},resizeColumn(t,o){if(t>=e.cols-1){return}const l=[...e.colWidths],r=l[t]+l[t+1],n=l[t]+o,s=l[t+1]-o;n<d?(l[t]=d,l[t+1]=r-d):s<d?(l[t+1]=d,l[t]=r-d):(l[t]=n,l[t+1]=s),e.colWidths.replace(l)},resizeRow(t,o){if(t>=e.rows-1){return}const l=[...e.rowHeights],r=l[t]+l[t+1],n=e.height,s=n>0?e.getRowContentOuterHeight(t)/n:0,i=n>0?e.getRowContentOuterHeight(t+1)/n:0,c=Math.max(d,s),a=Math.max(d,i),g=l[t]+o,u=l[t+1]-o;g<c?(l[t]=c,l[t+1]=r-c):u<a?(l[t+1]=a,l[t]=r-a):(l[t]=g,l[t+1]=u),e.rowHeights.replace(l)},setCellBorders(t,o,l){const r={top:{side:"bottom",dr:-1,dc:0},bottom:{side:"top",dr:1,dc:0},left:{side:"right",dr:0,dc:-1},right:{side:"left",dr:0,dc:1}};for(const n of t){const t=e.cells.find(e=>e.id===n);if(t){for(const n of o){t.setBorder(n,l);const o=r[n],s=t.row+o.dr,i=t.col+o.dc,c=e.getCell(s,i);c&&c.setBorder(o.side,l)}}}},applyBorderMode(o,l){var r;const n=function(e,t,o){const{minRow:l,maxRow:r,minCol:n,maxCol:s}=t,i=(e,t,l,r)=>{const n=[];for(let s=e;s<=t;s++){for(let e=l;e<=r;e++){const t=o(s,e);t&&n.push(t.id)}}return n};if("all"===e){return[{cellIds:i(l,r,n,s),sides:["top","right","bottom","left"]}]}const c=[],d="outer"===e||"topOnly"===e||"topBottom"===e,a="outer"===e||"bottomOnly"===e||"topBottom"===e,g="outer"===e||"leftOnly"===e,u="outer"===e||"rightOnly"===e;if(d){const e=i(l,l,n,s);e.length&&c.push({cellIds:e,sides:["top"]})}if(a){const e=i(r,r,n,s);e.length&&c.push({cellIds:e,sides:["bottom"]})}if(g){const e=i(l,r,n,n);e.length&&c.push({cellIds:e,sides:["left"]})}if(u){const e=i(l,r,s,s);e.length&&c.push({cellIds:e,sides:["right"]})}if(d||a||g||u){return c}if(("inner"===e||"innerHorizontal"===e)&&r>l){const e=i(l,r-1,n,s);e.length&&c.push({cellIds:e,sides:["bottom"]})}if(("inner"===e||"innerVertical"===e)&&s>n){const e=i(l,r,n,s-1);e.length&&c.push({cellIds:e,sides:["right"]})}return c}(o,null!==(r=e.getFocusedCellRange())&&void 0!==r?r:{minRow:0,maxRow:e.rows-1,minCol:0,maxCol:e.cols-1},(t,o)=>e.getCell(t,o));for(const{cellIds:e,sides:s}of n){t.setCellBorders(e,s,l)}}};return t}).actions(e=>({clone(t={},{skipSelect:o=!1}={}){const l=JSON.parse(JSON.stringify(e.toJSON()));if(t.id=t.id||i(10),l.cells){const e=new Map;l.cells.forEach(t=>{const o=t.id,l=i(10);e.set(o,l),t.id=l}),l.cells.forEach(t=>{t.mergedInto&&e.has(t.mergedInto)&&(t.mergedInto=e.get(t.mergedInto))})}return Object.assign(l,t),e.page.addElement(l,{skipSelect:o})}}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polotno",
3
- "version": "2.40.0",
3
+ "version": "2.40.2",
4
4
  "description": "Design Editor Framework",
5
5
  "author": "Anton Lavrenov",
6
6
  "keywords": [
@@ -67,7 +67,7 @@
67
67
  "functions-have-names": "^1.2.3",
68
68
  "gifuct-js": "^2.1.2",
69
69
  "gradient-parser": "^1.1.1",
70
- "konva": "^10.2.5",
70
+ "konva": "^10.3.0",
71
71
  "mediabunny": "^1.24.1",
72
72
  "mensch": "^0.3.4",
73
73
  "mobx": "6.15.0",
@@ -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: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})))});
1
+ import e from"react";import{observer as t}from"mobx-react-lite";import{ROLES as r}from"../model/store.js";import{ElementTrack as n,ELEMENT_ROW_HEIGHT as o}from"./element-track.js";import{forEveryChild as a}from"../model/group-model.js";export const ElementsTimeline=t(({store:t,scale:l,width:s})=>{const i=t.pages.slice();if(!i.length){return null}const m=i.flatMap(e=>(e=>{const t=[];for(const r of e.children){"group"===r.type?a(r,e=>{"group"!==e.type&&t.push(e)}):t.push(r)}return t})(e).map(t=>({element:t,page:e}))).filter(({element:e})=>e.selectable||t.role===r.ADMIN);if(!m.length){return null}const p=(e=>{const t=[],r=[];return e.map(({element:e,page:t})=>{const r=((e,t)=>{var r,n;const o=t.duration,a=e.animations.find(e=>"enter"===e.type),l=e.animations.find(e=>"exit"===e.type),s=Math.max(0,Math.min(o,null!==(r=null==a?void 0:a.delay)&&void 0!==r?r:0));return{start:s,end:Math.max(s+50,Math.min(o,o-(null!==(n=null==l?void 0:l.delay)&&void 0!==n?n:0)))}})(e,t);return{element:e,page:t,start:t.startTime+r.start,end:t.startTime+r.end}}).sort((e,t)=>e.start-t.start).forEach(e=>{if(e.end-e.start<50){return}let n=0;for(;n<r.length&&r[n]>e.start;){n++}t.push({element:e.element,page:e.page,row:n,start:e.start,end:e.end}),r[n]=e.end}),t})(m);if(!p.length){return null}const d=(p.reduce((e,t)=>Math.max(e,t.row),-1)+1)*o;return e.createElement("div",{style:{position:"relative",minWidth:s+"px",height:d+"px",marginTop:"12px"},className:"polotno-elements-container"},p.map(({element:r,row:o,page:a})=>e.createElement(n,{key:`${a.id}-${r.id}`,element:r,store:t,page:a,scale:l,row:o})))});