polotno 2.40.1 → 2.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/canvas/context-menu/context-menu.js +1 -1
- package/canvas/element.js +1 -1
- package/canvas/figure-element.js +1 -1
- package/canvas/gif-element.js +1 -1
- package/canvas/hotkeys.js +1 -1
- package/canvas/html-element.js +2 -2
- package/canvas/image-element.js +1 -1
- package/canvas/line-element.js +1 -1
- package/canvas/page-controls.js +1 -1
- package/canvas/page.d.ts +3 -1
- package/canvas/page.js +1 -1
- package/canvas/table-element.js +1 -1
- package/canvas/text-element.js +1 -1
- package/canvas/tooltip.js +1 -1
- package/canvas/video-element.js +1 -1
- package/canvas/workspace-canvas.d.ts +3 -1
- package/canvas/workspace-canvas.js +1 -1
- package/model/group-model.d.ts +28 -12
- package/model/group-model.js +1 -1
- package/model/node-model.js +1 -1
- package/model/page-model.d.ts +15 -17
- package/model/page-model.js +1 -1
- package/model/store.d.ts +140 -153
- package/model/store.js +1 -1
- package/model/table-model.d.ts +27 -0
- package/model/table-model.js +1 -1
- package/model/text-model.d.ts +1 -12
- package/package.json +3 -3
- package/pages-timeline/elements.js +1 -1
- package/pages-timeline/page-preview.d.ts +4 -0
- package/pages-timeline/page-preview.js +2 -2
- package/polotno.bundle.js +245 -245
- package/side-panel/layers-panel.js +1 -1
- package/toolbar/position-picker.js +1 -1
- package/toolbar/table-toolbar.js +1 -1
- package/toolbar/toolbar.js +5 -5
- package/utils/html-to-svg/xhtml.js +1 -1
- package/utils/l10n.d.ts +11 -6
- package/utils/l10n.js +1 -1
- package/utils/text-html.js +1 -1
- package/utils/to-html.js +1 -1
- package/utils/to-svg.js +1 -1
- package/utils/validate-key.js +1 -1
- package/utils/xml.d.ts +1 -0
- package/utils/xml.js +7 -0
package/canvas/table-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
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})))});
|
package/canvas/text-element.js
CHANGED
|
@@ -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 r,Text as o,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 y,getCurvePath as S,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 k}from"../utils/screen.js";import{isAlive as O,getParent as A}from"mobx-state-tree";import{getLimitedFontSize as R}from"./text-element/max-font-size.js";import{getOptimalCaretColor as M}from"./text-element/caret-color.js";let F;function j(){return F||(F=document.getElementById("polotno-text-style"),F||(F=document.createElement("style"),F.id="polotno-text-style",document.head.appendChild(F)),F)}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 T=e(({textNodeRef:e,element:n,onBlur:r,selectAll:o,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=M(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,r=j();r.innerHTML="",r.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,o&&(null==e||e.select(),document.execCommand("selectAll",!1,void 0))},[]),t.useEffect(()=>{window.addEventListener("blur",r);const t=t=>{var e;(null===(e=c.current)||void 0===e?void 0:e.contains(t.target))||r()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",r),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:y(f),style:Object.assign(Object.assign(Object.assign({},C),a),{paddingTop:d+"px"}),value:f,onChange:t=>{const e=R({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:r})}),L=e=>t.createElement(a,null,t.createElement(T,Object.assign({},e)));export const useFontLoader=(e,n,r,o,i)=>{const[a,l]=t.useReducer(t=>t+1,0),s=t.useRef(x(n,r,o)),c=t.useRef(null);return t.useLayoutEffect(()=>{if(s.current=x(n,r,o),s.current){return}let t=!0;return(async()=>{s.current=!1,l();const a=p(`text ${n}`);await e.loadFont(n,r,o,i),t?(c.current=a,s.current=!0,l()):a()})(),()=>{c.current&&(c.current(),c.current=null),t=!1}},[n,r,o]),t.useEffect(()=>{s.current&&setTimeout(()=>{c.current&&(c.current(),c.current=null)})},[s.current]),[s.current]};export const getLineHeight=({fontLoaded:e,fontFamily:n,fontSize:r,lineHeight:o})=>t.useMemo(()=>E({fontFamily:n,fontSize:r,lineHeight:o}),[e,n,r,o]);export function usePrevious(e){const n=t.useRef(e),r=t.useRef(e);return t.useMemo(()=>{r.current=n.current,n.current=e},[e]),r.current}function H(t,e,n=!1){const r=t.fontSize(),o=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 r=e.a.height&&t.height()>e.a.height;let o=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=o.find(t=>!l.includes(t)||(l=l.replace(t,""),!1));if(!(r||s&&!n)){break}a-=.5,t.fontSize(a)}return t.fontSize(r),t.height(o),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),R=t.useRef(null),M=t.useRef([]),[,F]=t.useReducer(t=>t+1,0),{editorEnabled:j,selectAll:C}=(e=>{const[n,r]=t.useState(!1),o=t.useRef(!1);return t.useEffect(()=>{var t=!0;return setTimeout(()=>{t&&(e._editModeEnabled&&(o.current=!0),r(!0),setTimeout(()=>{o.current=!1},50))},50),()=>{t=!1}},[]),{editorEnabled:n&&e._editModeEnabled,selectAll:o.current}})(e),[T,X]=t.useState(!1),[Y,W]=t.useState(!1),P=t.useRef(e.a.height),B=t.useRef(0),D=t.useRef(""),$=t.useRef(0),I=e.isSelected,N=usePrevious(I),{textVerticalResizeEnabled:J}=w,_=w.autoDeleteEmptyText,V=usePrevious(e.fontFamily),[q,U]=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(q)&&U(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(()=>{N&&!I&&_&&""===e.text&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[_,e.placeholder,e.removable,e.text,I,N]);const Z=()=>{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(!Y){return l(()=>{Z()})}}),t.useEffect(()=>{const t=M.current;t.length>0&&(M.current=[],t.forEach(t=>t()))});let G=v(e.text);"uppercase"===e.textTransform&&(G=G.toUpperCase());const[K]=useFontLoader(a,e.fontFamily,e.fontStyle,e.fontWeight,e.text||e.placeholder),Q=()=>{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(!K){return}if("tablecell"===e.type){const{textOverflow:t}=w;if("resize"===t){const t=Q(),n=O(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,r=(t,n,r,o)=>{const i=p(`text ${e.id}`),l=()=>{a.history.ignore(t,n,r).then(()=>{M.current.push(i),F()})};o?queueMicrotask(l):l()};if(!e.height){const t=Q();return void r(()=>{e.height||e.set({height:t})},void 0,void 0,!0)}if(!a.isPlaying){if("change-font-size"!==t||T){if("resize"===t){const t=Q();J&&e.height<t&&!T&&r(()=>{var n;O(e)&&e.set({height:t}),null===(n=x.current)||void 0===n||n.height(t)},!1,!0),J||e.height===t||T||r(()=>{var n;O(e)&&e.set({height:t}),null===(n=x.current)||void 0===n||n.height(t)},!1,!0)}}else{const t=x.current,o=e.curveEnabled?e.fontSize:H(t,e,n);if(o!==e.fontSize){return void r(()=>{e.set({fontSize:o})},!1,!0)}const i=Q();e.height===i||J||r(()=>{e.set({height:i})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(K&&e.curveEnabled){const n=null===(t=E.current)||void 0===t?void 0:t.getSelfRect().width;if(n){const t=n-e.a.width,r=e.a.rotation*Math.PI/180,o=-t/2*Math.cos(r),i=-t/2*Math.sin(r);e.set({width:n,x:e.a.x+o,y:e.a.y+i})}}},[K,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(),Z())},[K]);const tt=t.useRef(null),et=t.useRef(0),nt=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(et.current=function(t){var e;const n=t.target,r=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var n=t.getStage().getPointerPosition();return e.point(n)}(n),o=n.textArr,i=Math.floor(r.y/(n.fontSize()*n.lineHeight())),a=o.slice(0,i).reduce((t,e)=>t+e.text.length,i),l=null!==(e=o[i])&&void 0!==e?e:o[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((r.x-s)/l.width*l.text.length)}(t),e.toggleEditMode())},rt=!G&&e.placeholder?.6:e.a.opacity;z(x,rt);const ot=getLineHeight({fontLoaded:K,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),it=e.selectable||a.role===m.ADMIN,at=h(e),lt=h(e,e.stroke,"stroke"),st=t.useMemo(()=>e.backgroundEnabled?e.curveEnabled?function({width:t,height:e,padding:n=0,cornerRadius:r=0}){const o=-n,i=-n,a=t+n,l=e+n,s=c(`M ${o} ${i} L ${a} ${i} L ${a} ${l} L ${o} ${l} Z`);return d(s,r).path}({width:e.a.width,height:e.a.height,cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*ot*.5),padding:e.backgroundPadding*(e.a.fontSize*ot*.5)}):function({lines:t,lineHeight:e,width:n,align:r="left",padding:o=0,cornerRadius:i=0}){const a=f({lines:t,lineHeight:e,width:n,align:r});return u({rects:a,padding:o,cornerRadius:i})}({lines:JSON.parse(JSON.stringify(q)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*ot*.5),lineHeight:ot*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*ot*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.curveEnabled,e.backgroundCornerRadius,e.a.fontSize,e.a.height,ot,e.backgroundPadding,e.a.width,e.align,q]),ct=k();let dt=0;e.curveEnabled||("middle"===e.verticalAlign?dt=(e.a.height-q.length*ot*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(dt=e.a.height-q.length*ot*e.a.fontSize));const ut=e.curveEnabled?S(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",ft=K?'"'+e.fontFamily+'"':V===e.fontFamily?"Arial":'"'+V+'"',ht=y(G);return t.createElement(t.Fragment,null,t.createElement(r,{ref:R,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*rt,data:st,fill:e.backgroundColor,offsetY:-dt}),t.createElement(r,{data:ut,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:ut,text:G||e.placeholder,listening:!1,align:"center",textBaseline:"middle",direction:ht},at,lt,{strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${V}"`,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:rt,hideInExport:!e.showInExport,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity})),t.createElement(o,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:G||e.placeholder,direction:ht},at,lt,{lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:ft,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:ct?e.draggable&&I:e.draggable,preventDefault:!ct||I,opacity:e.curveEnabled?0:rt,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:ot,letterSpacing:e.letterSpacing*e.a.fontSize,listening:!!e.selectable&&it,onDragStart:()=>{W(!0)},onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{W(!1),e.set({x:t.target.x(),y:t.target.y()})},onClick:nt,onTap:nt,onTransformStart:()=>{var t,e;X(!0);const n=x.current;P.current=n.height(),B.current=n.rotation(),$.current=n.height();const r=null===(t=n.getStage())||void 0===t?void 0:t.findOne("Transformer");D.current=null!==(e=null==r?void 0:r.getActiveAnchor())&&void 0!==e?e:""},onTransform:t=>{var n,r,o;const i=t.target;null===(n=R.current)||void 0===n||n.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(r=i.getStage())||void 0===r?void 0:r.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),n=i.width()*t,r=e.a.fontSize;let o=n;n<r&&(o=r,tt.current&&i.position(tt.current)),i.width(o),i.scaleX(1),i.scaleY(1);let a=Q();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):Q();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),i.skewX(0),i.skewY(0),Z()}if("top-center"===a||"bottom-center"===a){const n="resize"===w.textOverflow?Q():ot*e.a.fontSize,r=t.target.height()*t.target.scaleY();if(r<n){if(t.target.height(n),tt.current){if("top-center"===D.current){const e=B.current*Math.PI/180,r=$.current-n;t.target.x(tt.current.x-r*Math.sin(e)),t.target.y(tt.current.y+r*Math.cos(e))}else{t.target.position(tt.current)}}}else{t.target.height(r)}t.target.scaleY(1),t.target.scaleX(1),t.target.rotation(B.current),t.target.skewX(0),t.target.skewY(0),$.current=Math.max(n,r)}tt.current=t.target.position();const l=t.target.scaleX();null===(o=R.current)||void 0===o||o.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 r=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:Math.round(e.a.fontSize*r),width:Math.ceil(t.target.width()*r),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*r,shadowBlur:e.shadowBlur*r,shadowOffsetX:e.shadowOffsetX*r,shadowOffsetY:e.shadowOffsetY*r,strokeWidth:e.strokeWidth*r}),null===(n=R.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),X(!1)}})),j&&e.contentEditable&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement(L,{textNodeRef:x,element:e,selectAll:C,cursorPosition:et.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
|
package/canvas/tooltip.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import t from"react";import{observer as e}from"mobx-react-lite";import{Html as n}from"react-konva-utils";import{Navbar as o,NavbarGroup as l}from"@blueprintjs/core";import{getTotalClientRect as r}from"../utils/math.js";import{extendToolbar as i}from"../toolbar/element-container.js";import{TextAiWrite as s}from"../toolbar/text-ai-write.js";import{flags as a}from"../utils/flags.js";import{DuplicateButton as u}from"../toolbar/duplicate-button.js";import{RemoveButton as c}from"../toolbar/remove-button.js";import{PositionPicker as d}from"../toolbar/position-picker.js";import{GroupButton as m}from"../toolbar/group-button.js";function f(t,e){return t.classList.contains(e)?t:t.parentElement?f(t.parentElement,e):null}const p=()=>null;export const Tooltip=e(({store:e,page:v,components:h,stageRef:g,tooltipSafeArea:b})=>{var E,y,k;const x=e.selectedShapes.every(t=>t.page===v),C=t.useRef(null),[w,j]=t.useState(!1),I=e._hasCroppedImages;e.selectedElements.length,t.useEffect(()=>{var t,e,n;const o=()=>{j(!0)},l=()=>{j(!1)};null===(t=null==g?void 0:g.current)||void 0===t||t.on("dragstart",o),null===(e=null==g?void 0:g.current)||void 0===e||e.on("dragend",l);const r=null===(n=null==g?void 0:g.current)||void 0===n?void 0:n.findOne("Transformer");return null==r||r.on("transformstart",o),null==r||r.on("transformend",l),()=>{var t,e;null===(t=null==g?void 0:g.current)||void 0===t||t.off("dragstart",o),null===(e=null==g?void 0:g.current)||void 0===e||e.off("dragend",l),null==r||r.off("transformstart",o),null==r||r.off("transformend",l)}},[]);const[N,R]=t.useState({fit:!0,needCalculate:!1,token:Math.random()});function M(){if(!C.current){return}if(!N.needCalculate){return}const t=f(C.current,"polotno-workspace-container");if(!t){return}const e=t.getBoundingClientRect(),n=C.current.getBoundingClientRect(),o=(n.right,e.left,n.top-e.top),l=(n.left,e.left,n.bottom-e.top),r=(null==b?void 0:b.top)||0,i=(null==b?void 0:b.bottom)||0,s=null==g?void 0:g.current;let a=-1/0,u=1/0;if(s){const t=s.container().getBoundingClientRect(),n=s.scaleY();a=t.top+s.y()+T.y*n-e.top,u=t.top+s.y()+(T.y+T.height)*n-e.top}const c=o>=20+r&&a-l>=48,d=l-e.height<=-20-i&&o-u>=48;R(c?{fit:!0,needCalculate:!1,token:N.token}:d?{fit:!1,needCalculate:!1,token:N.token}:{fit:N.fit,needCalculate:!1,token:N.token})}if(t.useEffect(()=>{0!==e.selectedElements.length&&R({fit:!0,needCalculate:!0,token:Math.random()})},[e.selectedElements,w,e.scale]),t.useLayoutEffect(()=>{const t=setTimeout(()=>{M()},100);return()=>{clearTimeout(t)}},[N.needCalculate,C.current,N.token]),t.useEffect(()=>{if(!g.current){return}const t=f(g.current.content,"polotno-workspace-inner");if(!t){return}const n=()=>{e.selectedElements.length&&R({fit:!0,needCalculate:!0,token:Math.random()})};return null==t||t.addEventListener("scroll",n),()=>{null==t||t.removeEventListener("scroll",n)}},[]),0===e.selectedShapes.length){return null}if(w){return null}if(!x){return null}if(e.activePage!==v){return null}if(I){return null}const T=r(e.selectedShapes),O=(null==h?void 0:h.Position)||d,S=(null==h?void 0:h.Duplicate)||u,B=(null==h?void 0:h.Remove)||c,Y=(null==h?void 0:h.Group)||m,F=(null==h?void 0:h.Lock)||p,L=null===(E=e.selectedElements[0])||void 0===E?void 0:E.type,P=Object.assign(Object.assign({},a.aiTextEnabled?{TextAiWrite:s}:{}),h||{}),X=i({components:P,type:L,usedItems:[]}),_=(null===(k=null===(y=null==g?void 0:g.current)||void 0===y?void 0:y.findOne("Transformer"))||void 0===k?void 0:k.rotation())||0;let A=80;return Math.abs(_)<30&&N.fit&&(A=80),Math.abs(_)>140&&!N.fit&&(A=80),t.createElement(n,{parentNodeFunc:({stage:t})=>{var e,n;return(null===(e=null==t?void 0:t.container())||void 0===e?void 0:e.closest(".polotno-workspace-container"))||(null===(n=null==t?void 0:t.container())||void 0===n?void 0:n.parentNode)},transformFunc:t=>{var e;const n=T.x+T.width/2,o=null===(e=null==g?void 0:g.current)||void 0===e?void 0:e.container(),l=(null==o?void 0:o.getBoundingClientRect())||{left:0,top:0,width:0,height:0,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},r=null==o?void 0:o.closest(".polotno-workspace-container"),i=(null==r?void 0:r.getBoundingClientRect())||{left:0,top:0,width:Number.POSITIVE_INFINITY,height:Number.POSITIVE_INFINITY,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},s=l.left-i.left,a=l.top-i.top,u=C.current?C.current.getBoundingClientRect().height:34,c=((null==b?void 0:b.top)||0)+8,d=a+t.y+T.y*t.scaleY;let m=N.fit;if(m){const t=d-A,e=c+u/2;Math.max(e,t)+u/2>d-48&&(m=!1)}const f=m?T.y*t.scaleY-A:T.y*t.scaleY+T.height*t.scaleY+A;let p=s+t.x+n*t.scaleX,v=p-T.width*t.scaleX/2,h=p+T.width*t.scaleX/2;const E=Math.min(50,T.width/2*t.scaleX),y=h>=E&&v<=i.width-E,k=C.current?C.current.getBoundingClientRect().width:0,x=(null==b?void 0:b.left)||0,w=(null==b?void 0:b.right)||0;if(Number.isFinite(i.width)&&k>0&&y){const t=8+k/2+x,e=i.width-8-k/2-w;e>=t&&(p=Math.max(t,Math.min(p,e)))}h<E&&(p-=k+8),v>i.width-E&&(p+=k+8);let j=a+t.y+f;const I=C.current?C.current.getBoundingClientRect().height:34,R=((null==b?void 0:b.top)||0)+8,M=((null==b?void 0:b.bottom)||0)+8;return Number.isFinite(i.height)&&(j=Math.max(R+I/2,j),j=Math.min(i.height-M-I/2,j)),Object.assign(Object.assign({},t),{x:p,y:j,scaleX:1,scaleY:1})},divProps:{style:{pointerEvents:"none",position:"absolute",visibility:N.needCalculate?"hidden":"visible",zIndex:9}}},t.createElement("div",{ref:t=>{C.current=t,!C.current&&t&&M()},style:{pointerEvents:"none"}},t.createElement(o,{style:{padding:"2px",borderRadius:"5px",height:"34px",transform:"translate(-50%, -50%)",pointerEvents:"auto"}},t.createElement(l,{style:{height:"30px"}},X.map(n=>{const o=P[n];return t.createElement(o,{elements:e.selectedElements,element:e.selectedElements[0],store:e,key:n})}),t.createElement(Y,{store:e}),t.createElement(F,{store:e}),t.createElement(S,{store:e}),t.createElement(B,{store:e}),t.createElement(O,{store:e})))))});
|
package/canvas/video-element.js
CHANGED
|
@@ -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})))))});
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { StoreType } from '../model/store.js';
|
|
3
3
|
import type { TransformerConfig } from 'konva/lib/shapes/Transformer';
|
|
4
4
|
import type { RectConfig } from 'konva/lib/shapes/Rect';
|
|
5
|
+
export type GroupClickBehavior = 'select-child' | 'select-group';
|
|
5
6
|
export type WorkspaceProps = {
|
|
6
7
|
store: StoreType;
|
|
7
8
|
layout?: 'vertical' | 'horizontal';
|
|
@@ -50,6 +51,7 @@ export type WorkspaceProps = {
|
|
|
50
51
|
paddingY?: number;
|
|
51
52
|
pageGap?: number;
|
|
52
53
|
altCloneEnabled?: boolean;
|
|
54
|
+
groupClickBehavior?: GroupClickBehavior;
|
|
53
55
|
visiblePagesOffset?: number;
|
|
54
56
|
renderOnlyActivePage?: boolean;
|
|
55
57
|
scrollToPageThreshold?: number;
|
|
@@ -60,7 +62,7 @@ export type WorkspaceProps = {
|
|
|
60
62
|
right?: number;
|
|
61
63
|
};
|
|
62
64
|
};
|
|
63
|
-
export declare const WorkspaceCanvas: (({ store, layout, pageControlsEnabled, backgroundColor, transparencyBackgroundColor, pageBorderColor, activePageBorderColor, bleedColor, snapGuideStroke, snapGuideStrokeWidth, snapGuideDash, selectionRectFill, selectionRectStroke, selectionRectStrokeWidth, transformLabelFill, transformLabelTextFill, cropOverlayFill, transformerStyle, innerImageCropTransformerStyle, outerImageCropTransformerStyle, highlighterStyle, mediaLoadingStyle, mediaErrorStyle, textOverflowIndicatorStyle, distanceGuideStroke, distanceLabelFill, distanceLabelTextFill, rulerBackgroundColor, rulerTextColor, rulerBorderColor, rulerBorderSize, rulerTickColor, rulerTickSize, components, onKeyDown, paddingX, paddingY, pageGap, altCloneEnabled, visiblePagesOffset, renderOnlyActivePage, scrollToPageThreshold, tooltipSafeArea, }: WorkspaceProps) => React.JSX.Element) & {
|
|
65
|
+
export declare const WorkspaceCanvas: (({ store, layout, pageControlsEnabled, backgroundColor, transparencyBackgroundColor, pageBorderColor, activePageBorderColor, bleedColor, snapGuideStroke, snapGuideStrokeWidth, snapGuideDash, selectionRectFill, selectionRectStroke, selectionRectStrokeWidth, transformLabelFill, transformLabelTextFill, cropOverlayFill, transformerStyle, innerImageCropTransformerStyle, outerImageCropTransformerStyle, highlighterStyle, mediaLoadingStyle, mediaErrorStyle, textOverflowIndicatorStyle, distanceGuideStroke, distanceLabelFill, distanceLabelTextFill, rulerBackgroundColor, rulerTextColor, rulerBorderColor, rulerBorderSize, rulerTickColor, rulerTickSize, components, onKeyDown, paddingX, paddingY, pageGap, altCloneEnabled, groupClickBehavior, visiblePagesOffset, renderOnlyActivePage, scrollToPageThreshold, tooltipSafeArea, }: WorkspaceProps) => React.JSX.Element) & {
|
|
64
66
|
displayName: string;
|
|
65
67
|
};
|
|
66
68
|
export default WorkspaceCanvas;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{observer as t}from"mobx-react-lite";import r from"./page.js";import{TopRules as o}from"./rules.js";import{AudioElement as n}from"./audio.js";import{handleHotkey as l}from"./hotkeys.js";import{t as i}from"../utils/l10n.js";import{WorkspaceStyleProvider as a,useResolvedWorkspaceStyle as s}from"./workspace-style.js";const c=(e,t,r)=>Math.max(t,Math.min(r,e)),u=(e,t)=>Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2)),d=({store:t})=>e.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},e.createElement("p",null,i("workspace.noPages")),e.createElement("button",{onClick:()=>{t.addPage()}},i("workspace.addPage"))),h=({width:t,height:r,xPadding:o,yPadding:n,backgroundColor:l})=>e.createElement("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:o+"px",paddingRight:o+"px",paddingTop:n+"px",paddingBottom:n+"px",flexShrink:0}},e.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}}));export const WorkspaceCanvas=t(({store:t,layout:i="vertical",pageControlsEnabled:g,backgroundColor:p,transparencyBackgroundColor:f,pageBorderColor:m,activePageBorderColor:v,bleedColor:y,snapGuideStroke:x,snapGuideStrokeWidth:k,snapGuideDash:w,selectionRectFill:T,selectionRectStroke:b,selectionRectStrokeWidth:E,transformLabelFill:S,transformLabelTextFill:L,cropOverlayFill:C,transformerStyle:M,innerImageCropTransformerStyle:P,outerImageCropTransformerStyle:R,highlighterStyle:F,mediaLoadingStyle:W,mediaErrorStyle:B,textOverflowIndicatorStyle:O,distanceGuideStroke:z,distanceLabelFill:H,distanceLabelTextFill:N,rulerBackgroundColor:j,rulerTextColor:G,rulerBorderColor:I,rulerBorderSize:_,rulerTickColor:Y,rulerTickSize:D,components:X,onKeyDown:A,paddingX:K,paddingY:q,pageGap:V,altCloneEnabled:J=!0,visiblePagesOffset:Q,renderOnlyActivePage:U,scrollToPageThreshold:Z=.5,tooltipSafeArea:$})=>{var ee;const te="horizontal"===i,re=null!=K?K:20,oe=null!=q?q:55,[ne,le]=e.useState({width:100,height:100}),ie=e.useRef(ne),ae=e.useRef(null),se=e.useRef(null),ce=e.useRef(0),ue=t.bleedVisible?Math.max(0,...t.pages.map(e=>e.bleed)):0,de=Math.max(...t.pages.map(e=>e.computedWidth)),he=Math.max(...t.pages.map(e=>e.computedHeight)),ge=(null===(ee=t.activePage)||void 0===ee?void 0:ee.computedHeight)||0,pe=de+2*ue,fe=(U?ge:he)+2*ue,me=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===ae.current){return}const r=ae.current.getBoundingClientRect();0!==r.width&&0!==r.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(ae.current));const o=se.current.clientWidth||r.width,n={width:o,height:r.height};(ie.current.width!==n.width||ie.current.height!==n.height)&&(le(n),ie.current=n);const l=(o-2*re)/pe,i=t.pages.length>1?3.1:2,a=(r.height-oe*i)/fe,s=t.pages.length>1?3.1:2,c=(o-re*s)/pe,u=(r.height-2*oe)/fe,d=t.pages.length?Math.max(Math.min(te?c:l,te?u:a),.01):1;t.scaleToFit!==d&&(t.setScale(d),t._setScaleToFit(d))};e.useLayoutEffect(()=>{me({skipTimeout:!0})},[]),e.useEffect(()=>{me()},[pe,fe,q,K]),e.useLayoutEffect(()=>{me({skipTimeout:!0})},[t.openedSidePanel]),e.useEffect(()=>{t.__()},[]),e.useEffect(()=>{const e=ae.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{me({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{me({skipTimeout:!0})},100);return()=>clearInterval(e)}},[pe,fe]);const ve=U?1:t.pages.length;let ye,xe;if(te){const e=pe*t.scale*ve;ye=Math.max(re,(ne.width-e)/ve/2),xe=Math.max(oe,(ne.height-fe*t.scale)/2)}else{ye=Math.max(re,(ne.width-pe*t.scale)/2);const e=fe*t.scale*ve;xe=Math.max(oe,(ne.height-e)/ve/2)}Number.isNaN(ye)&&(ye=re),Number.isNaN(xe)&&(xe=oe),e.useEffect(()=>{const e=e=>{(A||l)(e,t)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),e.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const r=Math.max(5,t.scaleToFit);let o=Math.min(.1,t.scaleToFit);te&&pe>0&&Number.isFinite(pe)&&(o=Math.max(o,300/pe)),o=Math.max(o,.01);const n=.03,l=c(e.deltaY<0?t.scale*(1+n):t.scale/(1+n),o,r);return void t.setScale(l)}},r=se.current;return null==r||r.addEventListener("wheel",e),()=>null==r?void 0:r.removeEventListener("wheel",e)},[te,pe,t]),e.useEffect(()=>{const e=se.current;if(!e){return}const r=e=>{2===e.touches.length&&(ce.current=u(e.touches[0],e.touches[1]))},o=r=>{if(2===r.touches.length&&ce.current>0){r.preventDefault();const o=u(r.touches[0],r.touches[1]),n=o/ce.current,l=Math.max(5,t.scaleToFit);let i=Math.min(.1,t.scaleToFit);te&&pe>0&&Number.isFinite(pe)&&(i=Math.max(i,300/pe)),i=Math.max(i,.01);const a=t.scale,s=c(a*n,i,l),d=s/a,h=e.getBoundingClientRect(),g=(r.touches[0].clientX+r.touches[1].clientX)/2-h.left,p=(r.touches[0].clientY+r.touches[1].clientY)/2-h.top,f=e.scrollLeft+g,m=e.scrollTop+p;Le.current=!0,t.setScale(s),e.scrollLeft=f*d-g,e.scrollTop=m*d-p,ce.current=o}},n=()=>{ce.current=0};return e.addEventListener("touchstart",r,{passive:!0}),e.addEventListener("touchmove",o,{passive:!1}),e.addEventListener("touchend",n,{passive:!0}),()=>{e.removeEventListener("touchstart",r),e.removeEventListener("touchmove",o),e.removeEventListener("touchend",n)}},[te,pe,t]);const ke=void 0!==V,we=t.pages.map(e=>{if(te){const r=(e.computedWidth+2*ue)*t.scale;return ke?r+V:r+2*ye}{const r=(e.computedHeight+2*ue)*t.scale;return ke?r+V:r+2*xe}}),Te=[];let be=ke?te?ye:xe:0;for(let e=0;e<we.length;e++){Te.push(be),be+=we[e]}const Ee=we.reduce((e,t)=>e+t,0),Se=ke?Ee+(te?2*ye:2*xe):Ee,Le=e.useRef(!1),[,Ce]=e.useReducer(e=>e+1,0);((t,r,o,n,l)=>{const i=e.useRef(0),a=e.useRef(0),s=e.useRef(null),u=e.useRef(null),d=e.useRef(!1),h=e.useRef(n.pages.length);d.current=h.current!==n.pages.length,h.current=n.pages.length,e.useEffect(()=>{const e=t.current,r=()=>{i.current=e.scrollLeft,a.current=e.scrollTop,s.current=e.scrollWidth,u.current=e.scrollHeight};return e.addEventListener("scroll",r),r(),()=>{e.removeEventListener("scroll",r)}},[]),e.useLayoutEffect(()=>{if(!t.current){return}if(d.current){return}const e=t.current,r=s.current,o=u.current;if(null===r||null===o){return s.current=e.scrollWidth,u.current=e.scrollHeight,i.current=e.scrollLeft,void(a.current=e.scrollTop)}l.current=!0;const n=e.offsetWidth,h=e.offsetHeight,g=(i.current+n/2)/r,p=(a.current+h/2)/o,f=Math.max(0,e.scrollWidth-n),m=Math.max(0,e.scrollHeight-h);e.scrollLeft=c(g*e.scrollWidth-n/2,0,f),e.scrollTop=c(p*e.scrollHeight-h/2,0,m),s.current=e.scrollWidth,u.current=e.scrollHeight,i.current=e.scrollLeft,a.current=e.scrollTop},[o,r])})(se,Se,t.scale,t,Le);const{handleScroll:Me}=((t,r,o,n,l,i,a,s,c,u)=>{const d=e.useRef(!1),h=e.useRef(null),g=e.useRef(!1),p="horizontal"===c;e.useEffect(()=>{const e=t.current,r=()=>{a.current};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[]);const f=n.pages.indexOf(n.activePage);return e.useLayoutEffect(()=>{if(s){return}if(!n.activePage){return}if(!t.current){return}if(d.current){return}const e=t.current,i=n.pages.indexOf(n.activePage),a=r[i]||0,c=p?e.scrollLeft:e.scrollTop,h=p?e.scrollWidth-e.clientWidth:e.scrollHeight-e.clientHeight,f=Math.min(a,Math.max(0,h)),m=o[i]||o[0]||0;let v=()=>{};return(Math.abs(f-c)>m*l||g.current)&&(g.current=!0,v=(({element:e,scrollTop:t,scrollLeft:r,duration:o=300,onFinish:n=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,a=l?t:r,s=a-i;let c=0,u=!1;if(0===o){return l?e.scrollTop=a:e.scrollLeft=a,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,s,o);l?e.scrollTop=t:e.scrollLeft=t,c<o?setTimeout(d,20):n()},h=(e,t,r,o)=>(e/=o/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:e},p?{scrollLeft:f}:{scrollTop:f}),{onFinish:()=>{g.current=!1,null==u||u()},duration:n.isPlaying?0:300}))),v},[n.activePage,f,n.isPlaying,s,c,r,o]),{handleScroll:e=>{if(s){return}if(g.current){return}d.current=!0,clearTimeout(h.current),h.current=setTimeout(()=>{d.current=!1},300);const t=(p?e.currentTarget.scrollLeft:e.currentTarget.scrollTop)+(p?i.width:i.height)/3;let o=0;for(let n=r.length-1;n>=0;n--){if(t>=r[n]){o=n;break}}const l=n.pages[o];l&&n.activePage!==l&&l.select()}}})(se,Te,we,t,Z,ne,Le,U,i,Ce),Pe=ne.width>=pe*t.scale+2*ye,Re=ne.height>=fe*t.scale+2*xe,Fe=p||"rgba(232, 232, 232, 0.9)",We=(null==X?void 0:X.NoPages)||d,Be=te?ne.width:ne.height,Oe=se.current?te?se.current.scrollLeft:se.current.scrollTop:0,ze=e=>{for(let t=Te.length-1;t>=0;t--){if(e>=Te[t]){return t}}return 0},He=Math.max(0,ze(Oe)),Ne=Math.min(t.pages.length-1,ze(Oe+Be)),je=null!=Q?Q:1,Ge=Math.max(0,He-je),Ie=Math.min(t.pages.length-1,Ne+je),_e=s({cropOverlayFill:C,workspaceBackgroundColor:p,pageBorderColor:m,activePageBorderColor:v,bleedColor:y,transparencyBackgroundColor:f,transformerStyle:M,innerImageCropTransformerStyle:P,outerImageCropTransformerStyle:R,highlighterStyle:F,snapGuideStroke:x,snapGuideStrokeWidth:k,snapGuideDash:w,selectionRectFill:T,selectionRectStroke:b,selectionRectStrokeWidth:E,transformLabelFill:S,transformLabelTextFill:L,distanceGuideStroke:z,distanceLabelFill:H,distanceLabelTextFill:N,mediaLoadingStyle:W,mediaErrorStyle:B,textOverflowIndicatorStyle:O,rulerBackgroundColor:j,rulerTextColor:G,rulerBorderColor:I,rulerBorderSize:_,rulerTickColor:Y,rulerTickSize:D});return e.createElement(a,{value:_e},e.createElement("div",{ref:ae,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:Fe,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container"},e.createElement("div",{ref:se,onScroll:Me,style:Object.assign({position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:te?"row":"column",overflow:"auto",overflowX:te?"auto":Pe?"hidden":"auto",overflowY:te&&Re?"hidden":"auto"},ke&&{paddingTop:te?0:xe,paddingBottom:te?0:xe,paddingLeft:te?ye:0,paddingRight:te?ye:0,boxSizing:"border-box"}),className:"polotno-workspace-inner"},t.pages.map((o,n)=>{const l=o===t.activePage;if(U&&!l&&!o._exportingOrRendering&&!o._forceMount){return null}const a=l||n>=Ge&&n<=Ie||o._exportingOrRendering||o._forceMount,s=te?we[n]:pe*t.scale+2*ye,c=te?fe*t.scale+2*xe:we[n];if(!a){return e.createElement("div",{key:o.id,style:{flexShrink:0}},e.createElement(h,{width:s,height:c,backgroundColor:Fe,xPadding:ye,yPadding:xe}))}const u=e.createElement(r,{key:o.id,page:o,xPadding:ye,yPadding:xe,width:s,height:c,store:t,pageControlsEnabled:g,altCloneEnabled:J,components:X,viewportSize:ne,layout:i,tooltipSafeArea:$});return(o._exportingOrRendering||o._forceMount)&&!l&&U?e.createElement("div",{style:{display:"none",flexShrink:0},key:o.id},u):u}),t.rulesVisible&&e.createElement(o,{store:t,xPadding:ye,yPadding:xe,width:pe*t.scale+2*ye,height:fe*t.scale+2*xe,pageSizes:we,layout:i,renderOnlyActivePage:U}),0===t.pages.length&&e.createElement(We,{store:t}),t.audios.map(r=>e.createElement(n,{key:r.id,audio:r,store:t})))))});export default WorkspaceCanvas;
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import r from"./page.js";import{TopRules as o}from"./rules.js";import{AudioElement as n}from"./audio.js";import{handleHotkey as l}from"./hotkeys.js";import{t as i}from"../utils/l10n.js";import{WorkspaceStyleProvider as a,useResolvedWorkspaceStyle as s}from"./workspace-style.js";const c=(e,t,r)=>Math.max(t,Math.min(r,e)),u=(e,t)=>Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2)),d=({store:t})=>e.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},e.createElement("p",null,i("workspace.noPages")),e.createElement("button",{onClick:()=>{t.addPage()}},i("workspace.addPage"))),h=({width:t,height:r,xPadding:o,yPadding:n,backgroundColor:l})=>e.createElement("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:o+"px",paddingRight:o+"px",paddingTop:n+"px",paddingBottom:n+"px",flexShrink:0}},e.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}}));export const WorkspaceCanvas=t(({store:t,layout:i="vertical",pageControlsEnabled:g,backgroundColor:p,transparencyBackgroundColor:f,pageBorderColor:m,activePageBorderColor:v,bleedColor:y,snapGuideStroke:k,snapGuideStrokeWidth:x,snapGuideDash:w,selectionRectFill:T,selectionRectStroke:b,selectionRectStrokeWidth:E,transformLabelFill:S,transformLabelTextFill:L,cropOverlayFill:C,transformerStyle:M,innerImageCropTransformerStyle:P,outerImageCropTransformerStyle:R,highlighterStyle:F,mediaLoadingStyle:W,mediaErrorStyle:B,textOverflowIndicatorStyle:O,distanceGuideStroke:z,distanceLabelFill:H,distanceLabelTextFill:N,rulerBackgroundColor:j,rulerTextColor:G,rulerBorderColor:I,rulerBorderSize:_,rulerTickColor:Y,rulerTickSize:D,components:X,onKeyDown:A,paddingX:K,paddingY:q,pageGap:V,altCloneEnabled:J=!0,groupClickBehavior:Q="select-child",visiblePagesOffset:U,renderOnlyActivePage:Z,scrollToPageThreshold:$=.5,tooltipSafeArea:ee})=>{var te;const re="horizontal"===i,oe=null!=K?K:20,ne=null!=q?q:55,[le,ie]=e.useState({width:100,height:100}),ae=e.useRef(le),se=e.useRef(null),ce=e.useRef(null),ue=e.useRef(0),de=t.bleedVisible?Math.max(0,...t.pages.map(e=>e.bleed)):0,he=Math.max(...t.pages.map(e=>e.computedWidth)),ge=Math.max(...t.pages.map(e=>e.computedHeight)),pe=(null===(te=t.activePage)||void 0===te?void 0:te.computedHeight)||0,fe=he+2*de,me=(Z?pe:ge)+2*de,ve=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===se.current){return}const r=se.current.getBoundingClientRect();0!==r.width&&0!==r.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(se.current));const o=ce.current.clientWidth||r.width,n={width:o,height:r.height};(ae.current.width!==n.width||ae.current.height!==n.height)&&(ie(n),ae.current=n);const l=(o-2*oe)/fe,i=t.pages.length>1?3.1:2,a=(r.height-ne*i)/me,s=t.pages.length>1?3.1:2,c=(o-oe*s)/fe,u=(r.height-2*ne)/me,d=t.pages.length?Math.max(Math.min(re?c:l,re?u:a),.01):1;t.scaleToFit!==d&&(t.setScale(d),t._setScaleToFit(d))};e.useLayoutEffect(()=>{ve({skipTimeout:!0})},[]),e.useEffect(()=>{ve()},[fe,me,q,K]),e.useLayoutEffect(()=>{ve({skipTimeout:!0})},[t.openedSidePanel]),e.useEffect(()=>{t.__()},[]),e.useEffect(()=>{const e=se.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{ve({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{ve({skipTimeout:!0})},100);return()=>clearInterval(e)}},[fe,me]);const ye=Z?1:t.pages.length;let ke,xe;if(re){const e=fe*t.scale*ye;ke=Math.max(oe,(le.width-e)/ye/2),xe=Math.max(ne,(le.height-me*t.scale)/2)}else{ke=Math.max(oe,(le.width-fe*t.scale)/2);const e=me*t.scale*ye;xe=Math.max(ne,(le.height-e)/ye/2)}Number.isNaN(ke)&&(ke=oe),Number.isNaN(xe)&&(xe=ne),e.useEffect(()=>{const e=e=>{(A||l)(e,t)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),e.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const r=Math.max(5,t.scaleToFit);let o=Math.min(.1,t.scaleToFit);re&&fe>0&&Number.isFinite(fe)&&(o=Math.max(o,300/fe)),o=Math.max(o,.01);const n=.03,l=c(e.deltaY<0?t.scale*(1+n):t.scale/(1+n),o,r);return void t.setScale(l)}},r=ce.current;return null==r||r.addEventListener("wheel",e),()=>null==r?void 0:r.removeEventListener("wheel",e)},[re,fe,t]),e.useEffect(()=>{const e=ce.current;if(!e){return}const r=e=>{2===e.touches.length&&(ue.current=u(e.touches[0],e.touches[1]))},o=r=>{if(2===r.touches.length&&ue.current>0){r.preventDefault();const o=u(r.touches[0],r.touches[1]),n=o/ue.current,l=Math.max(5,t.scaleToFit);let i=Math.min(.1,t.scaleToFit);re&&fe>0&&Number.isFinite(fe)&&(i=Math.max(i,300/fe)),i=Math.max(i,.01);const a=t.scale,s=c(a*n,i,l),d=s/a,h=e.getBoundingClientRect(),g=(r.touches[0].clientX+r.touches[1].clientX)/2-h.left,p=(r.touches[0].clientY+r.touches[1].clientY)/2-h.top,f=e.scrollLeft+g,m=e.scrollTop+p;Ce.current=!0,t.setScale(s),e.scrollLeft=f*d-g,e.scrollTop=m*d-p,ue.current=o}},n=()=>{ue.current=0};return e.addEventListener("touchstart",r,{passive:!0}),e.addEventListener("touchmove",o,{passive:!1}),e.addEventListener("touchend",n,{passive:!0}),()=>{e.removeEventListener("touchstart",r),e.removeEventListener("touchmove",o),e.removeEventListener("touchend",n)}},[re,fe,t]);const we=void 0!==V,Te=t.pages.map(e=>{if(re){const r=(e.computedWidth+2*de)*t.scale;return we?r+V:r+2*ke}{const r=(e.computedHeight+2*de)*t.scale;return we?r+V:r+2*xe}}),be=[];let Ee=we?re?ke:xe:0;for(let e=0;e<Te.length;e++){be.push(Ee),Ee+=Te[e]}const Se=Te.reduce((e,t)=>e+t,0),Le=we?Se+(re?2*ke:2*xe):Se,Ce=e.useRef(!1),[,Me]=e.useReducer(e=>e+1,0);((t,r,o,n,l)=>{const i=e.useRef(0),a=e.useRef(0),s=e.useRef(null),u=e.useRef(null),d=e.useRef(!1),h=e.useRef(n.pages.length);d.current=h.current!==n.pages.length,h.current=n.pages.length,e.useEffect(()=>{const e=t.current,r=()=>{i.current=e.scrollLeft,a.current=e.scrollTop,s.current=e.scrollWidth,u.current=e.scrollHeight};return e.addEventListener("scroll",r),r(),()=>{e.removeEventListener("scroll",r)}},[]),e.useLayoutEffect(()=>{if(!t.current){return}if(d.current){return}const e=t.current,r=s.current,o=u.current;if(null===r||null===o){return s.current=e.scrollWidth,u.current=e.scrollHeight,i.current=e.scrollLeft,void(a.current=e.scrollTop)}l.current=!0;const n=e.offsetWidth,h=e.offsetHeight,g=(i.current+n/2)/r,p=(a.current+h/2)/o,f=Math.max(0,e.scrollWidth-n),m=Math.max(0,e.scrollHeight-h);e.scrollLeft=c(g*e.scrollWidth-n/2,0,f),e.scrollTop=c(p*e.scrollHeight-h/2,0,m),s.current=e.scrollWidth,u.current=e.scrollHeight,i.current=e.scrollLeft,a.current=e.scrollTop},[o,r])})(ce,Le,t.scale,t,Ce);const{handleScroll:Pe}=((t,r,o,n,l,i,a,s,c,u)=>{const d=e.useRef(!1),h=e.useRef(null),g=e.useRef(!1),p="horizontal"===c;e.useEffect(()=>{const e=t.current,r=()=>{a.current};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[]);const f=n.pages.indexOf(n.activePage);return e.useLayoutEffect(()=>{if(s){return}if(!n.activePage){return}if(!t.current){return}if(d.current){return}const e=t.current,i=n.pages.indexOf(n.activePage),a=r[i]||0,c=p?e.scrollLeft:e.scrollTop,h=p?e.scrollWidth-e.clientWidth:e.scrollHeight-e.clientHeight,f=Math.min(a,Math.max(0,h)),m=o[i]||o[0]||0;let v=()=>{};return(Math.abs(f-c)>m*l||g.current)&&(g.current=!0,v=(({element:e,scrollTop:t,scrollLeft:r,duration:o=300,onFinish:n=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,a=l?t:r,s=a-i;let c=0,u=!1;if(0===o){return l?e.scrollTop=a:e.scrollLeft=a,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,s,o);l?e.scrollTop=t:e.scrollLeft=t,c<o?setTimeout(d,20):n()},h=(e,t,r,o)=>(e/=o/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:e},p?{scrollLeft:f}:{scrollTop:f}),{onFinish:()=>{g.current=!1,null==u||u()},duration:n.isPlaying?0:300}))),v},[n.activePage,f,n.isPlaying,s,c,r,o]),{handleScroll:e=>{if(s){return}if(g.current){return}d.current=!0,clearTimeout(h.current),h.current=setTimeout(()=>{d.current=!1},300);const t=(p?e.currentTarget.scrollLeft:e.currentTarget.scrollTop)+(p?i.width:i.height)/3;let o=0;for(let n=r.length-1;n>=0;n--){if(t>=r[n]){o=n;break}}const l=n.pages[o];l&&n.activePage!==l&&l.select()}}})(ce,be,Te,t,$,le,Ce,Z,i,Me),Re=le.width>=fe*t.scale+2*ke,Fe=le.height>=me*t.scale+2*xe,We=p||"rgba(232, 232, 232, 0.9)",Be=(null==X?void 0:X.NoPages)||d,Oe=re?le.width:le.height,ze=ce.current?re?ce.current.scrollLeft:ce.current.scrollTop:0,He=e=>{for(let t=be.length-1;t>=0;t--){if(e>=be[t]){return t}}return 0},Ne=Math.max(0,He(ze)),je=Math.min(t.pages.length-1,He(ze+Oe)),Ge=null!=U?U:1,Ie=Math.max(0,Ne-Ge),_e=Math.min(t.pages.length-1,je+Ge),Ye=s({cropOverlayFill:C,workspaceBackgroundColor:p,pageBorderColor:m,activePageBorderColor:v,bleedColor:y,transparencyBackgroundColor:f,transformerStyle:M,innerImageCropTransformerStyle:P,outerImageCropTransformerStyle:R,highlighterStyle:F,snapGuideStroke:k,snapGuideStrokeWidth:x,snapGuideDash:w,selectionRectFill:T,selectionRectStroke:b,selectionRectStrokeWidth:E,transformLabelFill:S,transformLabelTextFill:L,distanceGuideStroke:z,distanceLabelFill:H,distanceLabelTextFill:N,mediaLoadingStyle:W,mediaErrorStyle:B,textOverflowIndicatorStyle:O,rulerBackgroundColor:j,rulerTextColor:G,rulerBorderColor:I,rulerBorderSize:_,rulerTickColor:Y,rulerTickSize:D});return e.createElement(a,{value:Ye},e.createElement("div",{ref:se,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:We,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container"},e.createElement("div",{ref:ce,onScroll:Pe,style:Object.assign({position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:re?"row":"column",overflow:"auto",overflowX:re?"auto":Re?"hidden":"auto",overflowY:re&&Fe?"hidden":"auto"},we&&{paddingTop:re?0:xe,paddingBottom:re?0:xe,paddingLeft:re?ke:0,paddingRight:re?ke:0,boxSizing:"border-box"}),className:"polotno-workspace-inner"},t.pages.map((o,n)=>{const l=o===t.activePage;if(Z&&!l&&!o._exportingOrRendering&&!o._forceMount){return null}const a=l||n>=Ie&&n<=_e||o._exportingOrRendering||o._forceMount,s=re?Te[n]:fe*t.scale+2*ke,c=re?me*t.scale+2*xe:Te[n];if(!a){return e.createElement("div",{key:o.id,style:{flexShrink:0}},e.createElement(h,{width:s,height:c,backgroundColor:We,xPadding:ke,yPadding:xe}))}const u=e.createElement(r,{key:o.id,page:o,xPadding:ke,yPadding:xe,width:s,height:c,store:t,pageControlsEnabled:g,altCloneEnabled:J,groupClickBehavior:Q,components:X,viewportSize:le,layout:i,tooltipSafeArea:ee});return(o._exportingOrRendering||o._forceMount)&&!l&&Z?e.createElement("div",{style:{display:"none",flexShrink:0},key:o.id},u):u}),t.rulesVisible&&e.createElement(o,{store:t,xPadding:ke,yPadding:xe,width:fe*t.scale+2*ke,height:me*t.scale+2*xe,pageSizes:Te,layout:i,renderOnlyActivePage:Z}),0===t.pages.length&&e.createElement(Be,{store:t}),t.audios.map(r=>e.createElement(n,{key:r.id,audio:r,store:t})))))});export default WorkspaceCanvas;
|
package/model/group-model.d.ts
CHANGED
|
@@ -10,6 +10,19 @@ import { GifElementType } from './gif-model.js';
|
|
|
10
10
|
import { TableElementType } from './table-model.js';
|
|
11
11
|
export declare const forEveryChild: (node: any, cb: any) => void;
|
|
12
12
|
export declare const forEveryNode: (node: any, cb: any) => void;
|
|
13
|
+
export declare function zIndexOps(self: {
|
|
14
|
+
children: any;
|
|
15
|
+
}): {
|
|
16
|
+
canMoveElementsUp(ids: Array<string>): boolean;
|
|
17
|
+
canMoveElementsTop(ids: Array<string>): boolean;
|
|
18
|
+
canMoveElementsDown(ids: Array<string>): boolean;
|
|
19
|
+
canMoveElementsBottom(ids: Array<string>): boolean;
|
|
20
|
+
moveElementsUp(ids: Array<string>): void;
|
|
21
|
+
moveElementsDown(ids: Array<string>): void;
|
|
22
|
+
moveElementsTop(ids: Array<string>): void;
|
|
23
|
+
moveElementsBottom(ids: Array<string>): void;
|
|
24
|
+
setElementZIndex(id: string, zIndex: number): void;
|
|
25
|
+
};
|
|
13
26
|
export declare const ElementTypes: any;
|
|
14
27
|
type ElementUnion = (SVGElementType & {
|
|
15
28
|
type: 'svg';
|
|
@@ -364,18 +377,7 @@ export declare const TYPES_MAP: {
|
|
|
364
377
|
set(attrs: any): void;
|
|
365
378
|
afterCreate(): void;
|
|
366
379
|
toggleEditMode(editing?: boolean): void;
|
|
367
|
-
}, import("mobx-state-tree").
|
|
368
|
-
id: string;
|
|
369
|
-
type: string | undefined;
|
|
370
|
-
name: string | undefined;
|
|
371
|
-
opacity: number | undefined;
|
|
372
|
-
custom: any;
|
|
373
|
-
visible: boolean | undefined;
|
|
374
|
-
selectable: boolean | undefined;
|
|
375
|
-
removable: boolean | undefined;
|
|
376
|
-
alwaysOnTop: boolean | undefined;
|
|
377
|
-
showInExport: boolean | undefined;
|
|
378
|
-
}>, import("mobx-state-tree").ModelSnapshotType<{
|
|
380
|
+
}, any, import("mobx-state-tree").ModelSnapshotType<{
|
|
379
381
|
id: import("mobx-state-tree").ISimpleType<string>;
|
|
380
382
|
type: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
381
383
|
name: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
@@ -1384,6 +1386,12 @@ export declare const TYPES_MAP: {
|
|
|
1384
1386
|
readonly cellPadding: number;
|
|
1385
1387
|
readonly width: number;
|
|
1386
1388
|
readonly height: number;
|
|
1389
|
+
readonly borderInsets: {
|
|
1390
|
+
top: number;
|
|
1391
|
+
right: number;
|
|
1392
|
+
bottom: number;
|
|
1393
|
+
left: number;
|
|
1394
|
+
};
|
|
1387
1395
|
readonly a: {
|
|
1388
1396
|
x: number;
|
|
1389
1397
|
y: number;
|
|
@@ -1564,6 +1572,7 @@ export declare const TYPES_MAP: {
|
|
|
1564
1572
|
readonly visibleCells: import("./table-model.js").TableCellType[];
|
|
1565
1573
|
readonly focusedCells: import("./table-model.js").TableCellType[];
|
|
1566
1574
|
readonly editingCell: import("./table-model.js").TableCellType | undefined;
|
|
1575
|
+
getFocusedCellRange(): import("./table-model.js").CellRange | null;
|
|
1567
1576
|
readonly _fitRowsToContent: {
|
|
1568
1577
|
rowHeights: number[];
|
|
1569
1578
|
height: number;
|
|
@@ -1572,6 +1581,10 @@ export declare const TYPES_MAP: {
|
|
|
1572
1581
|
setCellContentHeight(cellId: string, height: number): void;
|
|
1573
1582
|
_applyFitRowsToContent(): void;
|
|
1574
1583
|
focusCell(cellId: string, addToSelection?: boolean): void;
|
|
1584
|
+
selectRowRange(startRow: number, endRow: number): void;
|
|
1585
|
+
selectColumnRange(startCol: number, endCol: number): void;
|
|
1586
|
+
selectRow(rowIndex: number): void;
|
|
1587
|
+
selectColumn(colIndex: number): void;
|
|
1575
1588
|
focusCellRange(targetRow: number, targetCol: number): void;
|
|
1576
1589
|
clearCellFocus(): void;
|
|
1577
1590
|
enterCellEdit(cellId: string): void;
|
|
@@ -1582,11 +1595,14 @@ export declare const TYPES_MAP: {
|
|
|
1582
1595
|
removeRow(index: number): void;
|
|
1583
1596
|
addColumn(index: number): void;
|
|
1584
1597
|
removeColumn(index: number): void;
|
|
1598
|
+
removeRowRange(minRow: number, maxRow: number): void;
|
|
1599
|
+
removeColumnRange(minCol: number, maxCol: number): void;
|
|
1585
1600
|
distributeRowsEvenly(): void;
|
|
1586
1601
|
distributeColumnsEvenly(): void;
|
|
1587
1602
|
resizeColumn(index: number, delta: number): void;
|
|
1588
1603
|
resizeRow(index: number, delta: number): void;
|
|
1589
1604
|
setCellBorders(cellIds: string[], sides: import("./table-model.js").BorderSideName[], attrs: import("./table-model.js").BorderAttrs): void;
|
|
1605
|
+
applyBorderMode(mode: import("./table-model.js").BorderMode, attrs: import("./table-model.js").BorderAttrs): void;
|
|
1590
1606
|
} & {
|
|
1591
1607
|
clone(attrs?: any, { skipSelect }?: {
|
|
1592
1608
|
skipSelect?: boolean | undefined;
|
package/model/group-model.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__rest||function(e,t){var r={};for(var o in e){Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var
|
|
1
|
+
var e=this&&this.__rest||function(e,t){var r={};for(var o in e){Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[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])&&(r[o[n]]=e[o[n]])}}return r};import{detach as t,types as r}from"mobx-state-tree";import{nanoid as o}from"nanoid";import{Node as n}from"./node-model.js";import{Shape as i}from"./shape-model.js";import{TextElement as l}from"./text-model.js";import{ImageElement as s}from"./image-model.js";import{VideoElement as d}from"./video-model.js";import{LineElement as c}from"./line-model.js";import{SVGElement as a}from"./svg-model.js";import{FigureElement as m}from"./figure-model.js";import{GifElement as p}from"./gif-model.js";import{TableElement as f}from"./table-model.js";export const forEveryChild=(e,t)=>{if(e.children){for(const r of e.children){if(!0===t(r)){break}forEveryChild(r,t)}}};export const forEveryNode=(e,t)=>{if(e.children){for(const r of e.children){if(!0===t(r)){break}forEveryNode(r,t)}}if(e.cells){for(const r of e.cells){if(!0===t(r)){break}}}};export function zIndexOps(e){const r=(t,r,o)=>{const n=t.map(t=>e.children.findIndex(e=>e.id===t)).filter(e=>-1!==e).sort((e,t)=>(t-e)*r);for(const i of n){const n=e.children[i+r];!n||t.indexOf(n.id)>=0||o(i)}},o=(e,t)=>{let o=!1;return r(e,t,()=>{o=!0}),o},n=(o,n)=>{r(o,n,r=>{const o=e.children[r];t(o),e.children.splice(r+n,0,o)})},i=(t,r)=>{const o=[],n=[];e.children.forEach(e=>{(t.indexOf(e.id)>=0?o:n).push(e)}),e.children.replace(r?n.concat(o):o.concat(n))};return{canMoveElementsUp:e=>o(e,1),canMoveElementsTop:e=>o(e,1),canMoveElementsDown:e=>o(e,-1),canMoveElementsBottom:e=>o(e,-1),moveElementsUp(e){n(e,1)},moveElementsDown(e){n(e,-1)},moveElementsTop(e){i(e,!0)},moveElementsBottom(e){i(e,!1)},setElementZIndex(r,o){const n=e.children.find(e=>e.id===r);n&&(t(n),e.children.remove(n),e.children.splice(o,0,n))}}}const E=[...new Array(20)].map((e,t)=>r.late(()=>h[t]));export const ElementTypes=r.union({dispatcher:e=>{const t=TYPES_MAP[e.type];if(!t){throw new Error(`Unknown element type: "${e.type}"`)}return t}},a,l,s,c,d,m,p,f,r.late(()=>GroupElement),...E);export const GroupElement=n.named("Group").props({type:"group",children:r.array(ElementTypes)}).views(e=>({get draggable(){let t=!0;return forEveryChild(e,e=>{e.draggable||(t=!1)}),t},get resizable(){let t=!0;return forEveryChild(e,e=>{e.resizable||(t=!1)}),t},get contentEditable(){let t=!0;return forEveryChild(e,e=>{e.contentEditable||(t=!1)}),t},get styleEditable(){let t=!0;return forEveryChild(e,e=>{e.styleEditable||(t=!1)}),t},get locked(){let t=!0;return forEveryChild(e,e=>{e.locked||(t=!1)}),t}})).actions(t=>Object.assign(Object.assign({set(r){var{draggable:o,contentEditable:n,styleEditable:i,resizable:l}=r,s=e(r,["draggable","contentEditable","styleEditable","resizable"]);void 0!==o&&forEveryChild(t,e=>{e.set({draggable:o})}),void 0!==n&&forEveryChild(t,e=>{e.set({contentEditable:n})}),void 0!==i&&forEveryChild(t,e=>{e.set({styleEditable:i})}),void 0!==l&&forEveryChild(t,e=>{e.set({resizable:l})}),Object.assign(t,s)},addElement(e,{skipSelect:r=!1}={}){const n=TYPES_MAP[e.type];if(!n){return void console.error("Can not find model with type "+e.type)}e.children&&e.children.forEach(e=>{e.id=e.id||o(10)});const i=n.create(Object.assign({id:o(10)},e));return t.children.push(i),i.selectable&&!r&&t.store.selectElements([i.id]),i}},zIndexOps(t)),{setAnimation(e,r){forEveryChild(t,t=>{t.setAnimation(e,r)})}}));const h=[];export const TYPES_MAP={svg:a,text:l,image:s,group:GroupElement,line:c,video:d,figure:m,gif:p,table:f};export function registerShapeModel(e,t){const r=e.type;if(!r){throw new Error('You must pass "type" attribute to custom model.')}let o=i.named(r).props(e);t&&(o=t(o)),TYPES_MAP[r]=o,h.push(o)}
|
package/model/node-model.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{types as e,getParentOfType as t,getSnapshot as
|
|
1
|
+
import{types as e,getParentOfType as t,getSnapshot as n,hasParentOfType as o}from"mobx-state-tree";import{nanoid as r}from"nanoid";import{Store as s}from"./store.js";import{Page as i}from"./page-model.js";import{GroupElement as a,forEveryNode as l}from"./group-model.js";export const Node=e.model("Node",{id:e.identifier,type:"none",name:"",opacity:1,custom:e.frozen(),visible:!0,selectable:!0,removable:!0,alwaysOnTop:!1,showInExport:!0}).preProcessSnapshot(e=>{for(var t in e){null===e[t]&&(e[t]=void 0)}return e}).postProcessSnapshot(e=>{const t=Object.assign({},e),n={};for(var o in t){"_"!==o[0]&&(n[o]=e[o])}return n}).views(e=>({get page(){return t(e,i)},get store(){return t(e,s)},get top(){let n=e;for(;;){if(!o(n,a)){return n}n=t(n,a)}},get parent(){if(o(e,a)){const n=t(e,a);return n&&n.children&&n.children.length,n}if(o(e,i)){const n=t(e,i);return n&&n.children&&n.children.length,n}if(o(e,s)){const n=t(e,s);return n&&n.pages&&n.pages.length,n}return null},get zIndex(){return e.parent.children.indexOf(e)}})).actions(e=>({toJSON:()=>Object.assign({},n(e))})).actions(e=>({clone(t={},{skipSelect:n=!1}={}){const o=JSON.parse(JSON.stringify(e.toJSON()));t.id=t.id||r(10);const s=new Map;return l(o,e=>{const t=e.id,n=r(10);s.set(t,n),e.id=n}),l(o,e=>{e.mergedInto&&s.has(e.mergedInto)&&(e.mergedInto=s.get(e.mergedInto))}),Object.assign(o,t),e.page.addElement(o,{skipSelect:n})},set(t){Object.assign(e,t)},moveUp(){var t;null===(t=e.parent)||void 0===t||t.moveElementsUp([e.id])},moveTop(){var t;null===(t=e.parent)||void 0===t||t.moveElementsTop([e.id])},moveDown(){var t;null===(t=e.parent)||void 0===t||t.moveElementsDown([e.id])},moveBottom(){var t;null===(t=e.parent)||void 0===t||t.moveElementsBottom([e.id])},setZIndex(t){e.parent.setElementZIndex(e.id,t)},beforeDestroy(){}}));
|
package/model/page-model.d.ts
CHANGED
|
@@ -23,9 +23,22 @@ export declare const Page: import("mobx-state-tree").IModelType<{
|
|
|
23
23
|
readonly computedHeight: any;
|
|
24
24
|
} & {
|
|
25
25
|
toJSON(): any;
|
|
26
|
-
_forEachElementUp(ids: Array<string>, callback: Function): void;
|
|
27
|
-
_forEachElementDown(ids: Array<string>, callback: Function): false;
|
|
28
26
|
} & {
|
|
27
|
+
setSize({ width, height, useMagic, softChange, }: {
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
useMagic?: boolean;
|
|
31
|
+
softChange?: boolean;
|
|
32
|
+
}): void;
|
|
33
|
+
canMoveElementsUp(ids: Array<string>): boolean;
|
|
34
|
+
canMoveElementsTop(ids: Array<string>): boolean;
|
|
35
|
+
canMoveElementsDown(ids: Array<string>): boolean;
|
|
36
|
+
canMoveElementsBottom(ids: Array<string>): boolean;
|
|
37
|
+
moveElementsUp(ids: Array<string>): void;
|
|
38
|
+
moveElementsDown(ids: Array<string>): void;
|
|
39
|
+
moveElementsTop(ids: Array<string>): void;
|
|
40
|
+
moveElementsBottom(ids: Array<string>): void;
|
|
41
|
+
setElementZIndex(id: string, zIndex: number): void;
|
|
29
42
|
clone(attrs?: {}): any;
|
|
30
43
|
setZIndex(zIndex: any): void;
|
|
31
44
|
set(attrs: any): void;
|
|
@@ -39,21 +52,6 @@ export declare const Page: import("mobx-state-tree").IModelType<{
|
|
|
39
52
|
}): T extends ElementType["type"] ? Extract<ElementType, {
|
|
40
53
|
type: T;
|
|
41
54
|
}> : NodeType;
|
|
42
|
-
canMoveElementsUp(ids: Array<string>): boolean;
|
|
43
|
-
moveElementsUp(ids: Array<string>): void;
|
|
44
|
-
canMoveElementsTop(ids: Array<string>): boolean;
|
|
45
|
-
moveElementsTop(ids: Array<string>): void;
|
|
46
|
-
canMoveElementsDown(ids: Array<string>): boolean;
|
|
47
|
-
moveElementsDown(ids: Array<string>): void;
|
|
48
|
-
canMoveElementsBottom(ids: Array<string>): boolean;
|
|
49
|
-
moveElementsBottom(ids: Array<string>): void;
|
|
50
|
-
setElementZIndex(id: any, zIndex: any): void;
|
|
51
|
-
setSize({ width, height, useMagic, softChange, }: {
|
|
52
|
-
width: number;
|
|
53
|
-
height: number;
|
|
54
|
-
useMagic?: boolean;
|
|
55
|
-
softChange?: boolean;
|
|
56
|
-
}): void;
|
|
57
55
|
} & {
|
|
58
56
|
moveElementUp(id: any): void;
|
|
59
57
|
moveElementDown(id: any): void;
|
package/model/page-model.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{getParentOfType as e,getSnapshot as t,types as i}from"mobx-state-tree";import{nanoid as o}from"nanoid";import{ElementTypes as n,forEveryChild as r,forEveryNode as s,TYPES_MAP as d,zIndexOps as a}from"./group-model.js";import{Store as m}from"./store.js";import{getTotalClientRect as h}from"../utils/math.js";export const Page=i.model("Page",{id:i.identifier,children:i.array(i.late(()=>n)),width:i.optional(i.union(i.number,i.literal("auto")),"auto"),height:i.optional(i.union(i.number,i.literal("auto")),"auto"),background:"white",bleed:0,custom:i.frozen(),duration:5e3,_exporting:!1,_rendering:!1,_forceMount:!1}).postProcessSnapshot(e=>{const t=Object.assign({},e),i={};for(var o in t){"_"!==o[0]&&(i[o]=e[o])}return i}).views(t=>({get store(){return e(t,m)}})).views(e=>({get startTime(){let t=0;for(const i of e.store.pages){if(i.id===e.id){return t}t+=i.duration}return t},get _exportingOrRendering(){return e._exporting||e._rendering}})).views(e=>({get computedWidth(){return"auto"===e.width?e.store.width:e.width},get computedHeight(){return"auto"===e.height?e.store.height:e.height}})).actions(e=>({toJSON:()=>JSON.parse(JSON.stringify(t(e)))})).actions(e=>Object.assign(Object.assign({clone(t={}){const i=e.toJSON(),n=new Map;i.children.forEach(e=>{const t=e.id,i=o(10);n.set(t,i),e.id=i,s(e,e=>{const t=e.id,i=o(10);n.set(t,i),e.id=i})}),i.children.forEach(e=>{e.cells&&e.cells.forEach(e=>{e.mergedInto&&n.has(e.mergedInto)&&(e.mergedInto=n.get(e.mergedInto))})});const r=Object.assign(Object.assign(Object.assign({},i),{id:o(10)}),t),d=e.store.addPage(r),a=e.store.pages.indexOf(e);return d.setZIndex(a+1),d.select(),d},setZIndex(t){e.store.setPageZIndex(e.id,t)},set(t){Object.assign(e,t)},select(){e.store.selectPage(e.id)},addElement(t,{skipSelect:i=!1}={}){const n=d[t.type];if(!n){return void console.error("Can not find model with type "+t.type)}"children"in t&&Array.isArray(t.children)&&s(t,e=>{e.id=e.id||o(10)});const r=e.children.reduce((e,i)=>{if("group"===i.type){const o=i.children.reduce((e,i)=>{var o;const n=null===(o=i.name)||void 0===o?void 0:o.match(new RegExp(`${t.type}-(\\d+)`));if(n){const t=parseInt(n[1],10);return Math.max(e,t||0)}},0);return Math.max(e,o||0)}{const o=i.name.match(new RegExp(`${t.type}-(\\d+)`));if(o){const t=parseInt(o[1],10);return Math.max(e,t||0)}}return e},0),a=n.create(Object.assign({id:o(10),name:`${t.type}-${r+1}`},t));return e.children.push(a),a.selectable&&!i&&e.store.selectElements([a.id]),a}},a(e)),{setSize({width:t,height:i,useMagic:o,softChange:n}){if(o){const o=[],n=t=>"image"===t.type&&t.x<1&&t.y<1&&t.width>=e.computedWidth-2&&t.height>=e.computedHeight-2;r(e,e=>{"group"!==e.type&&(n(e)||o.push(e))});const s=o.length?h(o):{x:0,y:0,width:e.computedWidth,height:e.computedHeight},d=1/4,a=Math.max(0,Math.min(s.x,e.computedWidth-s.x-s.width)),m=e.computedWidth*d,c=Math.max(0,a-m),p=Math.max(0,Math.min(s.y,e.computedHeight-s.y-s.height)),l=e.computedHeight*d,g=Math.max(0,p-l),u=e.computedWidth-2*c,f=e.computedHeight-2*g,w=t/u,y=i/f,v=Math.min(w,y),x=(t-u*v)/2-c*v,b=(i-f*v)/2-g*v;r(e,e=>{var t;if("group"!==e.type){if(n(e)){e.set({x:e.x*v,y:e.y*v,width:e.width*w,height:e.height*y,cropX:0,cropY:0,cropWidth:1,cropHeight:1})}else if(e.set({x:x+e.x*v,y:b+e.y*v,width:e.width*v,height:e.height*v}),"text"===e.type){e.set({fontSize:e.fontSize*v})}else if("figure"===e.type){e.set({strokeWidth:e.strokeWidth*v})}else if("table"===e.type){e.set({borderWidth:e.borderWidth*v});for(const i of e.cells){const e={fontSize:i.fontSize*v,cellPadding:i.cellPadding*v};if(i.borders){const o=JSON.parse(JSON.stringify(i.borders));for(const e of["top","right","bottom","left"]){null!=(null===(t=o[e])||void 0===t?void 0:t.width)&&(o[e]=Object.assign(Object.assign({},o[e]),{width:o[e].width*v}))}e.borders=o}i.set(e)}}}})}n||(e.width=t),n||(e.height=i)}})).actions(e=>({moveElementUp(t){console.warn("page.moveElementUp(id) is deprecated. Please use page.moveElementsUp([id1, id2]) instead."),e.moveElementsUp([t])},moveElementDown(t){console.warn("page.moveElementDown(id) is deprecated. Please use page.moveElementsDown([id1, id2]) instead."),e.moveElementsDown([t])},moveElementTop(t){console.warn("page.moveElementTop(id) is deprecated. Please use page.moveElementsTop([id1, id2]) instead."),e.moveElementsTop([t])},moveElementBottom(t){console.warn("page.moveElementBottom(id) is deprecated. Please use page.moveElementsBottom([id1, id2]) instead."),e.moveElementsBottom([t])},play(){e.store.play({startTime:e.startTime,endTime:e.startTime+e.duration})}}));
|