polotno 2.40.2 → 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/hotkeys.js +1 -1
- package/canvas/image-element.js +1 -1
- package/canvas/page.d.ts +3 -1
- package/canvas/page.js +1 -1
- package/canvas/text-element.js +1 -1
- package/canvas/tooltip.js +1 -1
- package/canvas/workspace-canvas.d.ts +3 -1
- package/canvas/workspace-canvas.js +1 -1
- package/model/group-model.d.ts +20 -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 +136 -153
- package/model/store.js +1 -1
- package/model/table-model.d.ts +12 -0
- package/model/table-model.js +1 -1
- package/model/text-model.d.ts +1 -12
- package/package.json +2 -2
- package/pages-timeline/page-preview.d.ts +4 -0
- package/pages-timeline/page-preview.js +2 -2
- package/polotno.bundle.js +101 -101
- package/side-panel/layers-panel.js +1 -1
- package/toolbar/position-picker.js +1 -1
- package/utils/html-to-svg/xhtml.js +1 -1
- package/utils/validate-key.js +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{observer as e}from"mobx-react-lite";import{ContextMenuPopover as t,Menu as o,MenuDivider as l,MenuItem as n}from"@blueprintjs/core";import r from"react";import{t as
|
|
1
|
+
import{observer as e}from"mobx-react-lite";import{ContextMenuPopover as t,Menu as o,MenuDivider as l,MenuItem as n}from"@blueprintjs/core";import r from"react";import{t as s}from"../../utils/l10n.js";import{useDuplicateElement as a}from"../../toolbar/use-duplicate-element.js";import{ChevronDown as i,ChevronUp as m,DoubleChevronDown as c,DoubleChevronUp as d,Duplicate as u,Layers as E,Lock as b,Trash as v,Unlock as p}from"@blueprintjs/icons";import{useRemoveElement as C}from"../../toolbar/use-remove-element.js";import{useCopyStyle as x}from"../../toolbar/use-copy-style.js";import{useLock as w}from"../../toolbar/use-lock.js";export const ContextMenu=e(({store:e,isOpen:f,offset:k,setIsOpen:h})=>{var R;const{disabled:y,duplicate:g}=a({store:e}),{disabled:M,remove:j}=C({store:e}),{setElementToCopy:D}=x(e),{disabled:P,lock:B,locked:F}=w({store:e}),O=F?r.createElement(b,null):r.createElement(p,null);return 0===e.selectedElements.length?null:r.createElement(t,{isOpen:f,onClose:()=>{h(!1)},content:r.createElement(o,null,r.createElement(n,{shouldDismissPopover:!1,icon:O,text:s(F?"contextMenu.unlock":"contextMenu.lock"),onClick:B,disabled:P}),r.createElement(n,{icon:r.createElement(u,null),text:s("contextMenu.duplicate"),onClick:g,disabled:y}),r.createElement(n,{icon:r.createElement(v,null),text:s("contextMenu.remove"),onClick:j,disabled:M}),r.createElement(l,null),r.createElement(n,{icon:r.createElement(E,null),text:s("toolbar.layering")},r.createElement(n,{shouldDismissPopover:!1,icon:r.createElement(d,null),text:s("toolbar.toForward"),disabled:!e.selectedElements.some(e=>{var t;return null===(t=e.parent)||void 0===t?void 0:t.canMoveElementsTop([e.id])}),onClick:()=>e.selectedElements.forEach(e=>e.moveTop())}),r.createElement(n,{shouldDismissPopover:!1,icon:r.createElement(m,null),text:s("toolbar.up"),disabled:!e.selectedElements.some(e=>{var t;return null===(t=e.parent)||void 0===t?void 0:t.canMoveElementsUp([e.id])}),onClick:()=>e.selectedElements.forEach(e=>e.moveUp())}),r.createElement(n,{shouldDismissPopover:!1,icon:r.createElement(i,null),text:s("toolbar.down"),disabled:!e.selectedElements.some(e=>{var t;return null===(t=e.parent)||void 0===t?void 0:t.canMoveElementsDown([e.id])}),onClick:()=>e.selectedElements.forEach(e=>e.moveDown())}),r.createElement(n,{shouldDismissPopover:!1,icon:r.createElement(c,null),text:s("toolbar.toBottom"),disabled:!e.selectedElements.some(e=>{var t;return null===(t=e.parent)||void 0===t?void 0:t.canMoveElementsBottom([e.id])}),onClick:()=>e.selectedElements.forEach(e=>e.moveBottom())})),"table"===(null===(R=e.selectedElements[0])||void 0===R?void 0:R.type)&&(()=>{var t;const o=e.selectedElements[0],a=o.focusedCells[0],i=null!=a,m=null!==(t=o.getFocusedCellRange())&&void 0!==t?t:a?{minRow:a.row,maxRow:a.row,minCol:a.col,maxCol:a.col}:{minRow:0,maxRow:0,minCol:0,maxCol:0},{minRow:c,maxRow:d,minCol:u,maxCol:E}=m,b=d>c,v=E>u;return r.createElement(r.Fragment,null,i&&r.createElement(r.Fragment,null,r.createElement(l,null),r.createElement(n,{text:s("toolbar.insertRowAbove"),onClick:()=>{e.history.transaction(()=>{o.addRow(c)})}}),r.createElement(n,{text:s("toolbar.insertRowBelow"),onClick:()=>{e.history.transaction(()=>{o.addRow(d+1)})}}),r.createElement(n,{text:s(b?"toolbar.deleteRows":"toolbar.deleteRow"),disabled:o.rows<=d-c+1,onClick:()=>{e.history.transaction(()=>{o.removeRowRange(c,d)})}}),r.createElement(l,null),r.createElement(n,{text:s("toolbar.insertColumnLeft"),onClick:()=>{e.history.transaction(()=>{o.addColumn(u)})}}),r.createElement(n,{text:s("toolbar.insertColumnRight"),onClick:()=>{e.history.transaction(()=>{o.addColumn(E+1)})}}),r.createElement(n,{text:s(v?"toolbar.deleteColumns":"toolbar.deleteColumn"),disabled:o.cols<=E-u+1,onClick:()=>{e.history.transaction(()=>{o.removeColumnRange(u,E)})}})),r.createElement(l,null),r.createElement(n,{text:s("toolbar.distributeRowsEvenly"),onClick:()=>{e.history.transaction(()=>{o.distributeRowsEvenly()})}}),r.createElement(n,{text:s("toolbar.distributeColumnsEvenly"),onClick:()=>{e.history.transaction(()=>{o.distributeColumnsEvenly()})}}))})()),targetOffset:{top:k.y,left:k.x}})});
|
package/canvas/element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{observer as t}from"mobx-react-lite";import{ROLES as o}from"../model/store.js";import r from"konva";import{TextElement as n}from"./text-element.js";import{ImageElement as i}from"./image-element.js";import{HTMLElement as m}from"./html-element.js";import{LineElement as
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import{ROLES as o}from"../model/store.js";import r from"konva";import{TextElement as n}from"./text-element.js";import{ImageElement as i}from"./image-element.js";import{HTMLElement as m}from"./html-element.js";import{LineElement as s}from"./line-element.js";import{VideoElement as l}from"./video-element.js";import{FigureElement as a}from"./figure-element.js";import{GifElement as f}from"./gif-element.js";import{TableElement as c}from"./table-element.js";import{Group as d}from"react-konva";import{Highlighter as p}from"./highlighter.js";import{forEveryChild as u}from"../model/group-model.js";import{flags as g}from"../utils/flags.js";const h={text:n,image:i,svg:i,line:s,video:l,figure:a,group:t(t=>{const{element:r,store:n}=t,{children:i}=r,m=r.selectable||n.role===o.ADMIN;return e.createElement(d,{opacity:r.opacity,listening:m,hideInExport:!r.showInExport,id:r.id},i.map(o=>e.createElement(v,Object.assign({},t,{key:o.id,store:n,element:o}))))}),gif:f,table:c};export function registerShapeComponent(e,t){h[e]=t}const y=(e,t)=>{const o=[];u(e,e=>{"group"!==e.type&&o.push(e.a)});const n=[];o.forEach(e=>{const t=[{x:0,y:0},{x:0+e.width,y:0},{x:0+e.width,y:0+e.height},{x:0,y:0+e.height}],o=new r.Transform;o.translate(e.x,e.y),o.rotate(r.Util.degToRad(e.rotation)),t.forEach(e=>{const t=o.point(e);n.push(t)})});const i=new r.Transform;i.rotate(-r.Util.degToRad(t));let m=1/0,s=1/0,l=-1/0,a=-1/0;n.forEach(e=>{const t=i.point(e);m=Math.min(m,t.x),s=Math.min(s,t.y),l=Math.max(l,t.x),a=Math.max(a,t.y)}),i.invert();const f=i.point({x:m,y:s});return{x:f.x,y:f.y,width:l-m,height:a-s,rotation:t}},v=t(t=>{var o,n;const{element:i,store:s}=t,[l,a]=e.useState(!1),f=i.isSelectedDirectly,c="group"===(null===(o=i.parent)||void 0===o?void 0:o.type),u="group"!==i.type||c?null:s.selectedElements,v=!!u&&1===u.length&&u[0]!==i&&u[0].top===i,[x,E]=e.useState(!1),j=(t=>{const[o,n]=e.useState();return e.useEffect(()=>{const e=setTimeout(()=>{const e=t.page.id,o=r.stages.find(t=>t.getAttr("pageId")===e);o||console.error("No stage is found for element",t.id),n(o)});return()=>clearTimeout(e)},[t.id]),o})(i),b=e.useRef(),T=()=>(b.current||(b.current=null==j?void 0:j.findOne("Transformer")),b.current);e.useEffect(()=>{if(j){const e=e=>{const t=e.target.findAncestor(".element",!0),o=s.getElementById(null==t?void 0:t.id()),r=null==o?void 0:o.top,n=null==r?void 0:r.id;a(n===i.id)};j.on("mouseover",e);const t=()=>{a(!1)};return j.on("mouseleave",t),()=>{j.off("mouseover",e),j.off("mouseleave",t)}}},[j]),e.useEffect(()=>{if(!v){return}const e=T();if(!j||!e){return}E(!1);const t=()=>E(!0),o=()=>E(!1);return j.on("dragstart",t),j.on("dragend",o),e.on("transformstart",t),e.on("transformend",o),()=>{j.off("dragstart",t),j.off("dragend",o),e.off("transformstart",t),e.off("transformend",o)}},[j,v]);let w=h[t.element.type];return"text"===t.element.type&&g.htmlRenderEnabled&&(w=m),t.element.visible?w?e.createElement(d,{name:"element-container"},e.createElement(w,Object.assign({},t)),(l||v)&&!f&&!c&&!x&&e.createElement(p,{element:"group"===i.type?{a:y(i,v?"rotation"in u[0]?u[0].rotation:0:(null===(n=T())||void 0===n?void 0:n.rotation())||0)}:i})):(console.error("Can not find component for "+t.element.type),null):null});export default v;
|
package/canvas/figure-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import{Group as a,Rect as r,Path as s}from"react-konva";import{ROLES as o}from"../model/store.js";import{subTypeToPathDataFunc as i}from"../utils/figure-to-svg.js";import{isTouchDevice as h}from"../utils/screen.js";import{useColor as n}from"./use-color.js";const l={};export const FigureElement=t(({element:c,store:d})=>{const g=e.useRef(null),m=c.selectable||d.role===o.ADMIN,f=h(),p=c.isSelected,w=Math.min(c.strokeWidth,c.width/2,c.height/2),u=Math.max(0,Math.min(c.width/2,c.height/2,c.cornerRadius)),b=n(c,c.a.fill,"fill"),x=Object.assign(Object.assign({width:c.a.width,height:c.a.height},b),{cornerRadius:u,shadowEnabled:c.shadowEnabled,shadowBlur:c.shadowBlur,shadowOffsetX:c.shadowOffsetX,shadowOffsetY:c.shadowOffsetY,shadowColor:c.shadowColor,shadowOpacity:c.shadowOpacity,preventDefault:!f||p,hideInExport:!c.showInExport}),y=n(c,c.stroke,"stroke"),k=Object.assign(Object.assign({visible:w>0,x:w/2,y:w/2,width:c.a.width-w,height:c.a.height-w},y),{strokeWidth:w,cornerRadius:Math.max(0,u-w),dash:c.dash.map(e=>e*w),hideInExport:!c.showInExport,listening:!1}),E=Math.max(0,10-Math.min(c.a.width,c.a.height)),v=(O=c.subType,l[O]||(l[O]=(j=i(O),t(({element:t,fillProps:o,strokeProps:i,hitStrokeWidth:h})=>{let n=j({width:t.a.width,height:t.a.height,cornerRadius:t.cornerRadius}),l=1,c=1;"string"!=typeof n&&(l=n.scaleX,c=n.scaleY,n=n.path);const d=e.useRef(null);return e.createElement(e.Fragment,null,e.createElement(r,{width:t.a.width,height:t.a.height,fill:"transparent",hitStrokeWidth:h}),e.createElement(s,Object.assign({},o,{ref:d,data:n,scaleX:l,scaleY:c})),e.createElement(a,{clipFunc:e=>{const t=d.current;if(t){var a=t.dataArray;e.beginPath();for(var r=0;r<a.length;r++){var s=a[r].command,o=a[r].points;switch(s){case"L":e.lineTo(o[0],o[1]);break;case"M":e.moveTo(o[0],o[1]);break;case"C":e.bezierCurveTo(o[0],o[1],o[2],o[3],o[4],o[5]);break;case"Q":e.quadraticCurveTo(o[0],o[1],o[2],o[3]);break;case"A":var i=o[0],h=o[1],n=o[2],l=o[3],c=o[4],g=o[5],m=o[6],f=o[7],p=n>l?n:l,w=n>l?1:n/l,u=n>l?l/n:1;e.translate(i,h),e.rotate(m),e.scale(w,u),e.arc(0,0,p,c,c+g,!f),e.scale(1/w,1/u),e.rotate(-m),e.translate(-i,-h);break;case"z":e.closePath()}}}},scaleX:l,scaleY:c},e.createElement(s,Object.assign({},i,{x:0,y:0,data:n,strokeWidth:2*i.strokeWidth,dash:i.dash.map(e=>e)}))))}))),l[O]||a);var O,j;return e.createElement(e.Fragment,null,e.createElement(a,{ref:g,id:c.id,x:c.a.x,y:c.a.y,rotation:c.a.rotation,opacity:c.a.opacity,listening:m,draggable:f?c.draggable&&p:c.draggable,name:"element",onDragMove:e=>{c.set({x:e.target.x(),y:e.target.y()})},onDragEnd:e=>{c.set({x:e.target.x(),y:e.target.y()})},onTransform:e=>{const t=e.target.scale();e.target.scaleX(1),e.target.scaleY(1),c.set({width:c.width*t.x,height:c.height*t.y,x:e.target.x(),y:e.target.y(),rotation:e.target.rotation()})}},e.createElement(v,{element:c,fillProps:x,strokeProps:k,hitStrokeWidth:E})))});
|
package/canvas/hotkeys.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ROLES as e}from"../model/store.js";import{copy as t,cut as o,paste as l}from"../utils/clipboard.js";import{duplicateElements as
|
|
1
|
+
import{ROLES as e}from"../model/store.js";import{copy as t,cut as o,paste as l}from"../utils/clipboard.js";import{duplicateElements as r}from"../utils/duplicate.js";import{alignBottom as n,alignCenter as i,alignLeft as c,alignMiddle as a,alignRight as s,alignTop as f}from"../utils/alignment.js";import{removeTags as d}from"../utils/text.js";const u="rgba(191, 191, 191, 100)";function y(e,t,o){const l=e.getCell(t,o);l&&e.focusCell(l.id)}function p(e,t,o){const l=e.getCell(t,o);l&&e.enterCellEdit(l.id)}export function handleHotkey(v,h){var m,w,g,D,E,K,k,C,x,R,A;if(h.role===e.VIEWER){return}const b=document.activeElement,S=document.querySelector(".polotno-workspace-container"),T="INPUT"===(null==b?void 0:b.tagName)||"TEXTAREA"===(null==b?void 0:b.tagName)||!!(null==b?void 0:b.isContentEditable),L=!(!b||!(null==S?void 0:S.contains(b))),M=T&&!L,P=function(e){if(1!==e.selectedElements.length){return null}const t=e.selectedElements[0];return"table"!==t.type?null:t}(h);if(!M&&P&&function(e,t,o){const l=t._focusedCellIds.length>0,r=!!t._editingCellId;if(!l&&!r){return!1}if(r){if("Escape"===e.key){return e.preventDefault(),t.exitCellEdit(),!0}if("Tab"===e.key){e.preventDefault();const o=t.editingCell;if(t.exitCellEdit(),o){if(e.shiftKey){let e=o.col-1,l=o.row;e<0&&(l-=1,e=t.cols-1),l<0&&(l=t.rows-1,e=t.cols-1),p(t,l,e)}else{let e=o.col+1,l=o.row;e>=t.cols&&(l+=1,e=0),l>=t.rows&&(l=0,e=0),p(t,l,e)}}return!0}if(e.metaKey||e.ctrlKey){const o=t.editingCell;if(o){if("b"===e.key){return e.preventDefault(),o.set({fontWeight:"bold"===o.fontWeight?"normal":"bold"}),!0}if("i"===e.key){return e.preventDefault(),o.set({fontStyle:"italic"===o.fontStyle?"normal":"italic"}),!0}if("u"===e.key){e.preventDefault();const t=o.textDecoration.split(" ").filter(Boolean),l=t.includes("underline");return o.set({textDecoration:l?t.filter(e=>"underline"!==e).join(" "):[...t,"underline"].join(" ")}),!0}}}return!0}if("Escape"===e.key){return e.preventDefault(),t.clearCellFocus(),!0}const n=t.focusedCells[0];if(!n){return!1}const i=n.row,c=n.col;if("Enter"===e.key){return e.preventDefault(),t.enterCellEdit(n.id),!0}if("Tab"===e.key){if(e.preventDefault(),e.shiftKey){let e=c-1,o=i;e<0&&(o-=1,e=t.cols-1),o<0&&(o=t.rows-1,e=t.cols-1),y(t,o,e)}else{let e=c+1,o=i;e>=t.cols&&(o+=1,e=0),o>=t.rows&&(o=0,e=0),y(t,o,e)}return!0}if("ArrowRight"===e.key||"ArrowLeft"===e.key||"ArrowDown"===e.key||"ArrowUp"===e.key){if(e.preventDefault(),e.shiftKey){const o=function(e){const t=e.cells.find(t=>t.id===e._anchorCellId);if(!t){return null}const o=e.focusedCells;if(o.length<=1){return{row:t.row,col:t.col}}let l=1/0,r=-1,n=1/0,i=-1;for(const c of o){c.row<l&&(l=c.row),c.row>r&&(r=c.row),c.col<n&&(n=c.col),c.col>i&&(i=c.col)}return{row:t.row===l?r:l,col:t.col===n?i:n}}(t)||{row:i,col:c};let l=o.row,r=o.col;"ArrowRight"===e.key&&(r=Math.min(o.col+1,t.cols-1)),"ArrowLeft"===e.key&&(r=Math.max(o.col-1,0)),"ArrowDown"===e.key&&(l=Math.min(o.row+1,t.rows-1)),"ArrowUp"===e.key&&(l=Math.max(o.row-1,0)),t.focusCellRange(l,r)}else{"ArrowRight"===e.key&&y(t,i,Math.min(c+1,t.cols-1)),"ArrowLeft"===e.key&&y(t,i,Math.max(c-1,0)),"ArrowDown"===e.key&&y(t,Math.min(i+1,t.rows-1),c),"ArrowUp"===e.key&&y(t,Math.max(i-1,0),c)}return!0}const a=e.ctrlKey||e.metaKey;if(!(a||e.shiftKey||e.altKey||"Delete"!==e.key&&"Backspace"!==e.key)){return e.preventDefault(),t.focusedCells.forEach(e=>{e.set({text:""})}),!0}if(a&&e.shiftKey&&!e.altKey&&"Equal"===e.code){e.preventDefault();const l=t.getFocusedCellRange(),r=l?l.maxRow+1:i+1;return o.history.transaction(()=>{t.addRow(r)}),!0}if(a&&e.shiftKey&&e.altKey&&"Equal"===e.code){e.preventDefault();const l=t.getFocusedCellRange(),r=l?l.maxCol+1:c+1;return o.history.transaction(()=>{t.addColumn(r)}),!0}if(a&&!e.shiftKey&&"Backspace"===e.code){const l=t.getFocusedCellRange();if(l&&0===l.minCol&&l.maxCol===t.cols-1&&t.rows>1){return e.preventDefault(),o.history.transaction(()=>{t.removeRowRange(l.minRow,l.maxRow)}),!0}}if(a&&e.shiftKey&&"Backspace"===e.code){const l=t.getFocusedCellRange();if(l&&0===l.minRow&&l.maxRow===t.rows-1&&t.cols>1){return e.preventDefault(),o.history.transaction(()=>{t.removeColumnRange(l.minCol,l.maxCol)}),!0}}if(a&&"KeyC"===e.code){e.preventDefault();const o=t.focusedCells.map(e=>d(e.text));return navigator.clipboard.writeText(o.join("\n")),!0}return a&&"KeyV"===e.code?(e.preventDefault(),navigator.clipboard.readText().then(e=>{const o=t.focusedCells[0];o&&o.set({text:e})}),!0):!(!a||"KeyA"!==e.code||(e.preventDefault(),t.cells.forEach(e=>{t.focusCell(e.id,!0)}),0))}(v,P,h)){return}if(T){return}const j=document.activeElement===S||L;if(!j){const e=window.getSelection();if(e&&e.toString().length>0){return}}if("Alt"===v.key){const e=S;return void((j||h.distanceGuidesVisible||e&&e.matches(":hover"))&&v.preventDefault())}const W=h.selectedElements.filter(e=>e.removable).map(e=>e.id);46!==v.keyCode&&8!==v.keyCode||h.deleteElements(W);const B=v.ctrlKey||v.metaKey,F=v.shiftKey,U=v.altKey;if("Escape"===v.key){return v.preventDefault(),void("draw"===h.tool?h.setTool("selection"):h.selectElements([]))}if(!B||F||"z"!==v.key.toLowerCase()&&"y"!==v.key.toLowerCase()||(v.preventDefault(),h.history.undo()),B&&F&&("z"===v.key.toLowerCase()||"y"===v.key.toLowerCase())&&(v.preventDefault(),h.history.redo()),B&&"KeyA"===v.code){v.preventDefault();const e=null===(m=h.activePage)||void 0===m?void 0:m.children.filter(e=>e.selectable),t=(null==e?void 0:e.map(e=>e.id))||[];h.selectElements(t)}if(B&&"KeyC"===v.code&&(v.preventDefault(),t(h)),B&&"KeyX"===v.code&&(v.preventDefault(),o(h)),B&&"KeyV"===v.code&&(v.preventDefault(),l(h)),"ArrowDown"===v.code){v.preventDefault();const e=v.shiftKey?10:1;h.selectedShapes.forEach(t=>{t.draggable&&t.set({y:t.y+e})})}if("ArrowUp"===v.code){v.preventDefault();const e=v.shiftKey?10:1;h.selectedShapes.forEach(t=>{t.draggable&&t.set({y:t.y-e})})}if("ArrowLeft"===v.code){v.preventDefault();const e=v.shiftKey?10:1;h.selectedShapes.forEach(t=>{t.draggable&&t.set({x:t.x-e})})}if("ArrowRight"===v.code){v.preventDefault();const e=v.shiftKey?10:1;h.selectedShapes.forEach(t=>{t.draggable&&t.set({x:t.x+e})})}if(B&&"KeyG"===v.code){v.preventDefault();const e=h.selectedElements[0];if(e&&"group"===e.type){const t=e;h.ungroupElements([t.id])}else{h.groupElements(h.selectedElements.map(e=>e.id))}}if(B&&"KeyD"===v.code&&(v.preventDefault(),r(h.selectedElements,h)),"KeyT"===v.code&&!B){v.preventDefault();const e=30,t=h.width/2,o=h.width/2-t/2,l=h.height/2-e/2,r=2160,n=(h.width+h.height)/r;null===(w=h.activePage)||void 0===w||w.addElement({type:"text",x:o,y:l,width:t,fontSize:e*n,text:"Sample Text",fontFamily:"Roboto"})}if("KeyR"===v.code&&!B){v.preventDefault();const e={type:"figure",x:h.width/4,y:h.height/4,width:300,height:300,fill:u,stroke:"#0c0c0c",strokeWidth:0,subType:"rect"};null===(g=h.activePage)||void 0===g||g.addElement(e)}if("KeyL"===v.code&&!B){v.preventDefault();const e=(null!==(E=null===(D=h.activePage)||void 0===D?void 0:D.computedWidth)&&void 0!==E?E:0)/3,t={type:"line",x:(null!==(k=null===(K=h.activePage)||void 0===K?void 0:K.computedWidth)&&void 0!==k?k:0)/2-e/2,y:(null!==(x=null===(C=h.activePage)||void 0===C?void 0:C.computedHeight)&&void 0!==x?x:0)/2,width:e,color:u};null===(R=h.activePage)||void 0===R||R.addElement(t)}if("KeyO"===v.code&&!B){v.preventDefault(),v.preventDefault();const e={type:"figure",x:h.width/4,y:h.height/4,width:300,height:300,fill:u,stroke:"#0c0c0c",strokeWidth:0,subType:"circle"};null===(A=h.activePage)||void 0===A||A.addElement(e)}B&&"Equal"===v.code&&(v.preventDefault(),h.setScale(h.scale+.1)),B&&"Minus"===v.code&&(v.preventDefault(),h.setScale(h.scale-.1)),U&&("KeyA"===v.code&&(v.preventDefault(),c(h)),"KeyD"===v.code&&(v.preventDefault(),s(h)),"KeyS"===v.code&&(v.preventDefault(),n(h)),"KeyW"===v.code&&(v.preventDefault(),f(h)),"KeyV"===v.code&&(v.preventDefault(),a(h)),"KeyH"===v.code&&(v.preventDefault(),i(h))),"BracketRight"===v.code&&(v.preventDefault(),h.selectedElements.forEach(e=>B?e.moveUp():e.moveTop())),"BracketLeft"===v.code&&(v.preventDefault(),h.selectedElements.forEach(e=>B?e.moveDown():e.moveBottom()))}
|
package/canvas/image-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"react";import{observer as e}from"mobx-react-lite";import{autorun as r}from"mobx";import{Arc as a,Group as o,Image as i,Rect as n,Text as h,Transformer as c}from"react-konva";import{ROLES as s}from"../model/store.js";import d from"use-image";import l from"konva";import{Portal as g}from"react-konva-utils";import{useWorkspaceStyle as u}from"./workspace-style.js";import{incrementLoader as m,triggerLoadError as f}from"../utils/loader.js";import*as p from"../utils/svg.js";import{flags as w}from"../utils/flags.js";import{trySetCanvasSize as x}from"../utils/canvas.js";import{applyFilter as y}from"./apply-filters.js";import{useFadeIn as M}from"./use-fadein.js";import{isTouchDevice as v}from"../utils/screen.js";import{useDelayer as E}from"./use-delayer.js";import{useColor as b}from"./use-color.js";function S(){return document.createElement("canvas")}const I=t=>t.indexOf("data:image/svg+xml")>=0||t.indexOf(".svg")>=0;export const useSizeFixer=e=>{const[r,a]=t.useState(e);return t.useEffect(()=>{(async()=>{const t=await async function(t){if(!I(t)){return t}const e=await p.urlToString(t),r=p.fixSize(e);return p.svgToURL(r)}(e);t!==r&&a(t)})()},[e]),r};function R(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}const C=["top-left","top-right","bottom-left","bottom-right"],X=(t,e)=>e.width<5||e.height<5?t:e,Y={enabledAnchors:C,keepRatio:!1,rotateEnabled:!1,boundBoxFunc:X},O={enabledAnchors:C,rotateEnabled:!1,borderEnabled:!1,boundBoxFunc:X};const T=(t,e,r)=>Math.max(e,Math.min(r,t));export const useCornerRadiusAndCrop=(e,r,a,o,i=0,n=!1,h=!0)=>{const c=Math.floor(T(e.a.width*o,1,1e4)),s=Math.floor(T(e.a.height*o,1,1e4)),d=Math.min(i*o,c/2,s/2),g=Math.max(e.a.width/a.width,e.a.height/a.height)*o,u=e.page._exportingOrRendering&&w.imageDownScalingEnabled&&g<1&&!n,m=0===a.x&&0===a.y&&a.width===(null==r?void 0:r.width)&&a.height===(null==r?void 0:r.height),f=t.useMemo(()=>{if(r&&r.width&&r.height){return m&&0===d&&!u?void 0:S()}},[r,d,u,m]);return t.useLayoutEffect(()=>{if(!f||!r){return}x(f,c,s);const t=f.getContext("2d");if(!t){return}d&&(t.beginPath(),t.moveTo(d,0),t.lineTo(c-d,0),t.arc(c-d,d,d,3*Math.PI/2,0,!1),t.lineTo(c,s-d),t.arc(c-d,s-d,d,0,Math.PI/2,!1),t.lineTo(d,s),t.arc(d,s-d,d,Math.PI/2,Math.PI,!1),t.lineTo(0,d),t.arc(d,d,d,Math.PI,3*Math.PI/2,!1),t.clip());const e=u?function(t,e){var r,a;const o=S();o.width=t.width,o.height=t.height;const i=Math.max(1,Math.floor(o.width*e)),n=Math.max(1,Math.floor(o.height*e));null===(r=o.getContext("2d"))||void 0===r||r.drawImage(t,0,0,o.width,o.height);const h=function(t,e,r,a,o,i,n){for(var h=new ImageData(e,r),c=new Int32Array(t.data.buffer),s=t.width,d=new Int32Array(h.data.buffer),l=h.width,g=e/i,u=r/n,m=Math.round(1/g),f=Math.round(1/u),p=m*f,w=0;w<h.height;w++){for(var x=0;x<l;x++){for(var y=0+Math.round(x/g)+(0+Math.round(w/u))*s,M=0,v=0,E=0,b=0,S=0;S<f;S++){for(var I=0;I<m;I++){var R=c[y+I+S*s];M+=R<<24>>>24,v+=R<<16>>>24,E+=R<<8>>>24,b+=R>>>24}}M=Math.round(M/p),v=Math.round(v/p),E=Math.round(E/p),b=Math.round(b/p),d[x+w*l]=b<<24|E<<16|v<<8|M}}return h}(o.getContext("2d").getImageData(0,0,o.width,o.height),i,n,0,0,o.width,o.height);return o.width=i,o.height=n,null===(a=o.getContext("2d"))||void 0===a||a.putImageData(h,0,0),o}(r,g):r,o=u?{x:Math.floor(a.x*g),y:Math.floor(a.y*g),width:Math.floor(a.width*g),height:Math.floor(a.height*g)}:a;t.drawImage(e,o.x,o.y,o.width,o.height,0,0,f.width,f.height)},[f,e.a.width,e.a.height,a.x,a.y,a.width,a.height,i,o,n,e.page._exportingOrRendering,u]),t.useEffect(()=>()=>{f&&"CANVAS"===f.nodeName&&l.Util.releaseCanvas(f)},[f]),f||r};const A=S(),D=e(({element:e})=>{const r=Math.min(30,e.a.width/4,e.a.height/4),i=t.useRef(null);t.useEffect(()=>{const t=i.current;if(!t){return}const e=new l.Animation(e=>{t.rotate(((null==e?void 0:e.timeDiff)||0)/2)},t.getLayer());return e.start(),()=>{e.stop()}});const{mediaLoadingStyle:h}=u();return t.createElement(o,{x:e.x,y:e.y,rotation:e.rotation,listening:!1,opacity:e.a.opacity,hideInExport:!e.showInExport},t.createElement(n,{width:e.a.width,height:e.a.height,fill:h.fill}),t.createElement(a,{ref:i,x:e.a.width/2,y:e.a.height/2,fill:h.textFill,outerRadius:Math.abs(r),innerRadius:Math.max(1,r-5),angle:270}))}),L=e(({element:e})=>{const{mediaErrorStyle:r}=u(),a=Math.max(10,Math.min(30,e.a.width/25));return t.createElement(o,{x:e.x,y:e.y,rotation:e.rotation,listening:!1,opacity:e.a.opacity,hideInExport:!e.showInExport},t.createElement(n,{width:e.a.width,height:e.a.height,fill:r.fill}),t.createElement(h,{text:"Can not load the image...",fontSize:a,width:e.a.width,height:e.a.height,align:"center",fill:r.textFill,verticalAlign:"middle",padding:5}))});let W=d;export const setImageLoaderHook=t=>{W=t};export const useImageLoader=(e,r="",a="")=>{const o=t.useRef(),i=()=>{var t;null===(t=o.current)||void 0===t||t.call(o),o.current=void 0};t.useEffect(()=>i,[]),t.useLayoutEffect(()=>{const t=r.slice(0,200),n=`image with id ${a} url: ${t}`;"loading"!==e||o.current||(o.current=m(n)),"loading"!==e&&i(),"failed"===e&&f(n)},[e])};export const ImageElement=e(({element:e,store:a})=>{var h;const d=u(),[m,f]=t.useState(!1),w=t.useRef(null),C=t.useRef(null),X=e.isSelected,[T,_]=(e=>{const[r,a]=t.useReducer(t=>t+1,0),o=t.useRef("loading"),i=t.useRef(e.src),n=t.useRef(e.src);n.current!==e.src&&(n.current=e.src,o.current="loading");const h=t.useMemo(()=>I(e.src)||"svg"===e.type,[e.src,e.type]);return t.useEffect(()=>{if(!h){return}if(!e.src){return}let t=!1;return(async()=>{o.current="loading",a();const r=await p.urlToString(e.src),n=p.fixSize(r);let h;h=e.colorsReplace?p.replaceColors(n,e.colorsReplace||new Map):p.svgToURL(n),t||(i.current=h,o.current="loaded",a())})(),()=>{t=!0}},[e.src,JSON.stringify(e.colorsReplace)]),h?[i.current,o.current]:[e.src,"loaded"]})(e),[k,H]=W(T,"anonymous"),j="svg"!==e.type||"loaded"===_?H:"loading";useImageLoader(j,e.src,e.id);const z=e.page._exportingOrRendering?1:Math.max(1,a.scale),P=a._elementsPixelRatio*z,F=(({image:e,status:r,type:a})=>{const o=t.useRef();return t.useEffect(()=>{o.current=e||o.current},[e]),"failed"!==r||"failed"!==r&&"svg"===a?o.current:void 0})({image:k,status:H,type:e.type}),B=((e,r,a)=>{const o=t.useMemo(()=>{var t,o;const{flipX:i,flipY:n}=e,h="svg"===e.type||e.src.indexOf("data:image/svg+xml")>=0||e.src.indexOf(".svg")>=0,c=navigator.userAgent.toLowerCase().indexOf("firefox")>-1,s=(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||c)&&h||e.maskSrc;if(!i&&!n&&!s){return r}if(!r||!r.width||!r.height){return null}const d=S();let l=1;"svg"===e.type&&(l=Math.max(e.a.width/r.width*a,e.a.height/r.height*a)),x(d,Math.max(r.width*l,1),Math.max(r.height*l,1));let g=i?-d.width:0,u=n?-d.height:0;return null===(t=d.getContext("2d"))||void 0===t||t.scale(i?-1:1,n?-1:1),null===(o=d.getContext("2d"))||void 0===o||o.drawImage(r,g,u,d.width,d.height),d},[e.maskSrc,e.flipX,e.flipY,r,e.a.width,e.a.height,a]);return t.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&l.Util.releaseCanvas(o)},[o]),o})(e,k||F,P),N=((e,r)=>{const a=useSizeFixer(e.maskSrc||""),[o,i]=W(a,"anonymous");return useImageLoader(a?i:"loaded",a||"",e.id),t.useMemo(()=>{if(!o){return r}if(!r||!r.width||!r.height){return r}const t=S();t.width=Math.max(r.width,1),t.height=Math.max(r.height,1);const a=t.getContext("2d");if(!a){return r}a.drawImage(r,0,0),a.globalCompositeOperation="source-in";const i=function(t,e){const r=e.width/e.height;let a,o;return r>=t.width/t.height?(a=t.width,o=t.width/r):(a=t.height*r,o=t.height),{x:(t.width-a)/2,y:(t.height-o)/2,width:a,height:o}}(o,e);return a.drawImage(o,i.x,i.y,i.width,i.height,0,0,r.width,r.height),t},[r,o,e.a.width,e.a.height])})(e,B)||A;let{cropX:U,cropY:V,cropWidth:$,cropHeight:q}=e.a;"loaded"!==H&&(U=V=0,$=q=1);const J=N.width*$,G=N.height*q,K=e.a.width/e.a.height;let Q,Z;const tt=J/G,et=e.stretchEnabled;et?(Q=J,Z=G):K>=tt?(Q=J,Z=J/K):(Q=G*K,Z=G);const rt={x:N.width*U,y:N.height*V,width:Q,height:Z},at=null!==(h=e.cornerRadius)&&void 0!==h?h:0,ot=e.page._exportingOrRendering?1:Math.min(2,a.scale),it=a._elementsPixelRatio*ot;let nt=((e,r,a,o)=>{const i=useSizeFixer(e.clipSrc||""),[n,h]=W(i,"anonymous"),c=e.clipSrc?h:"loaded";useImageLoader(c,e.clipSrc,e.id);const s=t.useMemo(()=>{if(r&&n){return S()}},[r,n]);return t.useLayoutEffect(()=>{var t;if(!n){return}if(!r||!r.width||!r.height){return}if(!n||!n.width||!n.height){return}if(!s){return}const o=S(),i=Math.max(e.a.width/n.width*a,e.a.height/n.height*a);o.width=Math.max(n.width*i,1),o.height=Math.max(n.height*i,1),null===(t=o.getContext("2d"))||void 0===t||t.drawImage(n,0,0,o.width,o.height),s.width=Math.max(r.width,1),s.height=Math.max(r.height,1);const h=s.getContext("2d");h&&(h.save(),h.drawImage(o,0,0,r.width,r.height),l.Util.releaseCanvas(o),h.globalCompositeOperation="source-in",h.drawImage(r,0,0,s.width,s.height),h.restore())},[s,r,n,e.a.width,e.a.height,a,...o]),e.clipSrc&&n?s:r})(e,useCornerRadiusAndCrop(e,N,rt,it,at,m||e._cropModeEnabled||"svg"===e.type,!0),it,[rt,at,it]);const ht=Math.max(e.a.width/Q,e.a.height/Z);t.useEffect(()=>{var t;if(!e._cropModeEnabled){return}const r=null===(t=w.current)||void 0===t?void 0:t.getStage();function a(t){e._cropModeEnabled&&t.target!==C.current&&e.toggleCropMode(!1)}function o(t){e._cropModeEnabled&&t.target.parentNode!==(null==r?void 0:r.content)&&e.toggleCropMode(!1)}return document.body.addEventListener("click",o),null==r||r.on("click",a),null==r||r.on("tap",a),()=>{document.body.removeEventListener("click",o),document.body.removeEventListener("touchstart",o),null==r||r.off("click",a),null==r||r.off("click",a)}},[e._cropModeEnabled]),t.useLayoutEffect(()=>{if(!m&&!e._cropModeEnabled){return y(w.current,e),r(()=>{y(w.current,e)},{delay:100})}},[nt,e.page._exportingOrRendering,m,$,q,e._cropModeEnabled]),t.useLayoutEffect(()=>{var t;m||e._cropModeEnabled?null===(t=w.current)||void 0===t||t.clearCache():y(w.current,e)},[m,e.a.width,e.a.height,e._cropModeEnabled]),t.useEffect(()=>{y(w.current,e)},[e.shadowEnabled,e.shadowBlur,e.cornerRadius,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]);const ct=t.useRef(null),st=t.useRef(null),dt=t.useRef(null);t.useLayoutEffect(()=>{e._cropModeEnabled&&(st.current.nodes([ct.current]),dt.current.nodes([C.current]))},[e._cropModeEnabled]);var lt=t.useRef(null),gt=t.useRef(0),ut=t.useRef(!1);const mt=t=>{var r;(null===(r=t.evt.touches)||void 0===r?void 0:r.length)>2&&t.target.stopDrag(),Math.round(t.target.x())>0&&(t.target.x(0),t.target.scaleX(1)),Math.round(t.target.y())>0&&(t.target.y(0),t.target.scaleY(1));const a=t.target.width()*t.target.scaleX(),o=t.target.height()*t.target.scaleY(),i=Math.min(1,Q/a),n=Math.min(1,Z/o),h=1-i,c=Math.min(h,Math.max(0,Math.round(-t.target.x())/a)),s=1-n,d=Math.min(s,Math.max(0,Math.round(-t.target.y())/o));t.target.setAttrs({x:-c*N.width,y:-d*N.height,scaleX:1,scaleY:1}),e.set({cropX:c,cropY:d,cropWidth:i,cropHeight:n})},ft=()=>{"svg"!==e.type&&e.contentEditable&&(e.stretchEnabled||setTimeout(()=>{e.toggleCropMode(!0)}))},pt="svg"===e.type&&F,wt="loading"===H&&!pt,[xt]=E(wt,100,!1,!1),yt="failed"===H,Mt=!xt&&!yt,vt=t.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Et=Mt?e.a.opacity:0;M(w,Et);const bt=e.selectable||a.role===s.ADMIN,St=v(),It=b(e,e.borderColor,"stroke");return t.createElement(t.Fragment,null,xt&&t.createElement(D,{element:e}),yt&&t.createElement(L,{element:e}),t.createElement(i,{ref:w,name:"element",id:e.id,image:nt,x:e.a.x,y:e.a.y,width:e.a.width||1,height:e.a.height||1,rotation:e.a.rotation,opacity:Et,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,customCrop:rt,listening:bt,draggable:St?e.draggable&&X:e.draggable,preventDefault:!St||X,hideInExport:!e.showInExport,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDblClick:ft,onDblTap:ft,onTransformStart:()=>{f(!0),vt.current={cropX:e.cropX,cropY:e.cropY,cropWidth:e.cropWidth,cropHeight:e.cropHeight}},onTransform:t=>{var r;const a=t.currentTarget,o=Math.abs(a.scaleX()-1)<1e-7?1:a.scaleX(),i=Math.abs(a.scaleY()-1)<1e-7?1:a.scaleY();a.scaleX(1),a.scaleY(1);const n=null===(r=t.target.getStage())||void 0===r?void 0:r.findOne("Transformer"),h=1-Q/N.width,c=Math.min(h,Math.max(0,e.cropX)),s=1-Z/N.height,d=Math.min(s,Math.max(0,e.cropY)),l=n.getActiveAnchor(),g=!(l.indexOf("middle")>=0||l.indexOf("center")>=0),u=!g&&o<1&&vt.current.cropHeight>Z/N.height;let m=g?e.cropWidth:e.cropWidth*o;u&&(m=e.cropWidth);const f=!g&&i<1&&vt.current.cropWidth>Q/N.width;let p=g?e.cropHeight:e.cropHeight*i;f&&(p=e.cropHeight),et&&(m=e.cropWidth,p=e.cropHeight),e.set({cropX:c,cropY:d,x:a.x(),y:a.y(),width:a.width()*o,height:a.height()*i,rotation:t.target.rotation(),cropWidth:Math.min(m,1-c),cropHeight:Math.min(p,1-d)})},onTransformEnd:t=>{const r=t.currentTarget;e.set({width:r.width(),height:r.height(),x:r.x(),y:r.y(),rotation:t.target.rotation(),cropWidth:Q/N.width,cropHeight:Z/N.height}),f(!1)}}),t.createElement(n,Object.assign({x:e.x,y:e.y,width:Math.max(e.a.width-e.borderSize,0),height:Math.max(e.a.height-e.borderSize,0),opacity:Et,offsetX:-e.borderSize/2,offsetY:-e.borderSize/2},It,{strokeWidth:e.borderSize,listening:!1,visible:!!e.borderSize,rotation:e.rotation,cornerRadius:Math.max(0,at-e.borderSize),hideInExport:!e.showInExport})),e._cropModeEnabled&&t.createElement(g,{selector:".page-abs-container",enabled:!0},t.createElement(n,{x:-window.innerWidth/a.scale,y:-window.innerWidth/a.scale,width:window.innerWidth/a.scale*3,height:window.innerWidth/a.scale*3,fill:d.cropOverlayFill}),t.createElement(i,{listening:!1,image:nt,x:e.x,y:e.y,width:e.a.width,height:e.a.height,rotation:e.rotation,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur}),t.createElement(o,{x:e.x,y:e.y,rotation:e.rotation,scaleX:ht,scaleY:ht},t.createElement(i,{image:N,ref:C,opacity:.4,draggable:!0,x:-e.cropX*N.width,y:-e.cropY*N.height,onDragMove:mt,onTransform:mt,onTouchMove:t=>{t.evt.preventDefault();const e=t.target.getStage().getPointersPositions();var r=e[0],a=e[1];const o=t.target;if(r&&!a&&!o.isDragging()&&ut.current&&(o.startDrag(),ut.current=!1),r&&a){l.hitOnDragEnabled=!0,o.isDragging()&&(ut.current=!0,o.stopDrag());const e=t.target.getAbsoluteTransform().copy();e.invert();var i={x:r.x,y:r.y},n={x:a.x,y:a.y};if(!lt.current){return void(lt.current=R(i,n))}var h=R(i,n),c=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}(i,n);gt.current||(gt.current=c);const f=o.position();var s={x:h.x-f.x,y:h.y-f.y},d=c/gt.current;o.scaleX(d),o.scaleY(d);const p=e.point(h),w=e.point(lt.current);var g=p.x-w.x,u=p.y-w.y,m={x:Math.min(0,h.x-s.x*d+g),y:Math.min(0,h.y-s.y*d+u)};o.position(m),gt.current=c,lt.current=h,mt(t)}},onTouchEnd:t=>{gt.current=0,lt.current=null,l.hitOnDragEnabled=!1}}),t.createElement(c,Object.assign({ref:dt},O,d.outerImageCropTransformerStyle)),t.createElement(n,{width:Q,height:Z,ref:ct,listening:!1,onTransform:t=>{if(e.cropX<Math.abs(t.target.x()/N.width)&&t.target.x()<0&&e.cropX>0){const r=(e.cropWidth+e.cropX)*N.width;t.target.scaleX(1),t.target.width(r)}if(e.cropY<Math.abs(t.target.y()/N.height)&&t.target.y()<0&&e.cropY>0){const r=(e.cropHeight+e.cropY)*N.height;t.target.scaleY(1),t.target.height(r)}t.target.x()<-e.cropX*N.width-1e-9&&(t.target.x(-e.cropX*N.width),t.target.scaleX(1)),t.target.y()<-e.cropY*N.height-1e-9&&(t.target.y(-e.cropY*N.height),t.target.scaleY(1));const r=Math.min(1,Math.max(0,e.cropX+t.target.x()/N.width)),a=Math.min(1,Math.max(0,t.target.y()/N.height+e.cropY)),o=t.target.width()*t.target.scaleX(),i=t.target.height()*t.target.scaleY(),n=Math.min(1-r,o/N.width),h=Math.min(1-a,i/N.height),c=t.target.getAbsolutePosition(t.target.getParent().getParent());t.target.scale({x:1,y:1}),t.target.position({x:0,y:0}),e.set({x:c.x,y:c.y,cropX:r,cropY:a,cropWidth:n,cropHeight:h,width:Math.min(o*ht,N.width*(1-r)*ht),height:Math.min(i*ht,N.height*(1-a)*ht)})}}),t.createElement(c,Object.assign({ref:st},Y,d.innerImageCropTransformerStyle,{visible:e.resizable})))))});
|
|
1
|
+
import t from"react";import{observer as e}from"mobx-react-lite";import{autorun as r}from"mobx";import{Arc as a,Group as o,Image as i,Rect as n,Text as h,Transformer as c}from"react-konva";import{ROLES as s}from"../model/store.js";import d from"use-image";import l from"konva";import{Portal as g}from"react-konva-utils";import{useWorkspaceStyle as u}from"./workspace-style.js";import{incrementLoader as m,triggerLoadError as f}from"../utils/loader.js";import*as p from"../utils/svg.js";import{flags as w}from"../utils/flags.js";import{trySetCanvasSize as x}from"../utils/canvas.js";import{applyFilter as y}from"./apply-filters.js";import{useFadeIn as M}from"./use-fadein.js";import{isTouchDevice as v}from"../utils/screen.js";import{useDelayer as E}from"./use-delayer.js";import{useColor as b}from"./use-color.js";function S(){return document.createElement("canvas")}const I=t=>t.indexOf("data:image/svg+xml")>=0||t.indexOf(".svg")>=0;export const useSizeFixer=e=>{const[r,a]=t.useState(e);return t.useEffect(()=>{(async()=>{const t=await async function(t){if(!I(t)){return t}const e=await p.urlToString(t),r=p.fixSize(e);return p.svgToURL(r)}(e);t!==r&&a(t)})()},[e]),r};function R(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}const C=(t,e)=>e.width<5||e.height<5?t:e,X={keepRatio:!1,rotateEnabled:!1,boundBoxFunc:C},Y={enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],rotateEnabled:!1,borderEnabled:!1,boundBoxFunc:C};const O=(t,e,r)=>Math.max(e,Math.min(r,t));export const useCornerRadiusAndCrop=(e,r,a,o,i=0,n=!1,h=!0)=>{const c=Math.floor(O(e.a.width*o,1,1e4)),s=Math.floor(O(e.a.height*o,1,1e4)),d=Math.min(i*o,c/2,s/2),g=Math.max(e.a.width/a.width,e.a.height/a.height)*o,u=e.page._exportingOrRendering&&w.imageDownScalingEnabled&&g<1&&!n,m=0===a.x&&0===a.y&&a.width===(null==r?void 0:r.width)&&a.height===(null==r?void 0:r.height),f=t.useMemo(()=>{if(r&&r.width&&r.height){return m&&0===d&&!u?void 0:S()}},[r,d,u,m]);return t.useLayoutEffect(()=>{if(!f||!r){return}x(f,c,s);const t=f.getContext("2d");if(!t){return}d&&(t.beginPath(),t.moveTo(d,0),t.lineTo(c-d,0),t.arc(c-d,d,d,3*Math.PI/2,0,!1),t.lineTo(c,s-d),t.arc(c-d,s-d,d,0,Math.PI/2,!1),t.lineTo(d,s),t.arc(d,s-d,d,Math.PI/2,Math.PI,!1),t.lineTo(0,d),t.arc(d,d,d,Math.PI,3*Math.PI/2,!1),t.clip());const e=u?function(t,e){var r,a;const o=S();o.width=t.width,o.height=t.height;const i=Math.max(1,Math.floor(o.width*e)),n=Math.max(1,Math.floor(o.height*e));null===(r=o.getContext("2d"))||void 0===r||r.drawImage(t,0,0,o.width,o.height);const h=function(t,e,r,a,o,i,n){for(var h=new ImageData(e,r),c=new Int32Array(t.data.buffer),s=t.width,d=new Int32Array(h.data.buffer),l=h.width,g=e/i,u=r/n,m=Math.round(1/g),f=Math.round(1/u),p=m*f,w=0;w<h.height;w++){for(var x=0;x<l;x++){for(var y=0+Math.round(x/g)+(0+Math.round(w/u))*s,M=0,v=0,E=0,b=0,S=0;S<f;S++){for(var I=0;I<m;I++){var R=c[y+I+S*s];M+=R<<24>>>24,v+=R<<16>>>24,E+=R<<8>>>24,b+=R>>>24}}M=Math.round(M/p),v=Math.round(v/p),E=Math.round(E/p),b=Math.round(b/p),d[x+w*l]=b<<24|E<<16|v<<8|M}}return h}(o.getContext("2d").getImageData(0,0,o.width,o.height),i,n,0,0,o.width,o.height);return o.width=i,o.height=n,null===(a=o.getContext("2d"))||void 0===a||a.putImageData(h,0,0),o}(r,g):r,o=u?{x:Math.floor(a.x*g),y:Math.floor(a.y*g),width:Math.floor(a.width*g),height:Math.floor(a.height*g)}:a;t.drawImage(e,o.x,o.y,o.width,o.height,0,0,f.width,f.height)},[f,e.a.width,e.a.height,a.x,a.y,a.width,a.height,i,o,n,e.page._exportingOrRendering,u]),t.useEffect(()=>()=>{f&&"CANVAS"===f.nodeName&&l.Util.releaseCanvas(f)},[f]),f||r};const T=S(),D=e(({element:e})=>{const r=Math.min(30,e.a.width/4,e.a.height/4),i=t.useRef(null);t.useEffect(()=>{const t=i.current;if(!t){return}const e=new l.Animation(e=>{t.rotate(((null==e?void 0:e.timeDiff)||0)/2)},t.getLayer());return e.start(),()=>{e.stop()}});const{mediaLoadingStyle:h}=u();return t.createElement(o,{x:e.x,y:e.y,rotation:e.rotation,listening:!1,opacity:e.a.opacity,hideInExport:!e.showInExport},t.createElement(n,{width:e.a.width,height:e.a.height,fill:h.fill}),t.createElement(a,{ref:i,x:e.a.width/2,y:e.a.height/2,fill:h.textFill,outerRadius:Math.abs(r),innerRadius:Math.max(1,r-5),angle:270}))}),A=e(({element:e})=>{const{mediaErrorStyle:r}=u(),a=Math.max(10,Math.min(30,e.a.width/25));return t.createElement(o,{x:e.x,y:e.y,rotation:e.rotation,listening:!1,opacity:e.a.opacity,hideInExport:!e.showInExport},t.createElement(n,{width:e.a.width,height:e.a.height,fill:r.fill}),t.createElement(h,{text:"Can not load the image...",fontSize:a,width:e.a.width,height:e.a.height,align:"center",fill:r.textFill,verticalAlign:"middle",padding:5}))});let L=d;export const setImageLoaderHook=t=>{L=t};export const useImageLoader=(e,r="",a="")=>{const o=t.useRef(),i=()=>{var t;null===(t=o.current)||void 0===t||t.call(o),o.current=void 0};t.useEffect(()=>i,[]),t.useLayoutEffect(()=>{const t=r.slice(0,200),n=`image with id ${a} url: ${t}`;"loading"!==e||o.current||(o.current=m(n)),"loading"!==e&&i(),"failed"===e&&f(n)},[e])};export const ImageElement=e(({element:e,store:a})=>{var h;const d=u(),[m,f]=t.useState(!1),w=t.useRef(null),C=t.useRef(null),O=e.isSelected,[W,_]=(e=>{const[r,a]=t.useReducer(t=>t+1,0),o=t.useRef("loading"),i=t.useRef(e.src),n=t.useRef(e.src);n.current!==e.src&&(n.current=e.src,o.current="loading");const h=t.useMemo(()=>I(e.src)||"svg"===e.type,[e.src,e.type]);return t.useEffect(()=>{if(!h){return}if(!e.src){return}let t=!1;return(async()=>{o.current="loading",a();const r=await p.urlToString(e.src),n=p.fixSize(r);let h;h=e.colorsReplace?p.replaceColors(n,e.colorsReplace||new Map):p.svgToURL(n),t||(i.current=h,o.current="loaded",a())})(),()=>{t=!0}},[e.src,JSON.stringify(e.colorsReplace)]),h?[i.current,o.current]:[e.src,"loaded"]})(e),[k,H]=L(W,"anonymous"),j="svg"!==e.type||"loaded"===_?H:"loading";useImageLoader(j,e.src,e.id);const z=e.page._exportingOrRendering?1:Math.max(1,a.scale),P=a._elementsPixelRatio*z,F=(({image:e,status:r,type:a})=>{const o=t.useRef();return t.useEffect(()=>{o.current=e||o.current},[e]),"failed"!==r||"failed"!==r&&"svg"===a?o.current:void 0})({image:k,status:H,type:e.type}),B=((e,r,a)=>{const o=t.useMemo(()=>{var t,o;const{flipX:i,flipY:n}=e,h="svg"===e.type||e.src.indexOf("data:image/svg+xml")>=0||e.src.indexOf(".svg")>=0,c=navigator.userAgent.toLowerCase().indexOf("firefox")>-1,s=(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||c)&&h||e.maskSrc;if(!i&&!n&&!s){return r}if(!r||!r.width||!r.height){return null}const d=S();let l=1;"svg"===e.type&&(l=Math.max(e.a.width/r.width*a,e.a.height/r.height*a)),x(d,Math.max(r.width*l,1),Math.max(r.height*l,1));let g=i?-d.width:0,u=n?-d.height:0;return null===(t=d.getContext("2d"))||void 0===t||t.scale(i?-1:1,n?-1:1),null===(o=d.getContext("2d"))||void 0===o||o.drawImage(r,g,u,d.width,d.height),d},[e.maskSrc,e.flipX,e.flipY,r,e.a.width,e.a.height,a]);return t.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&l.Util.releaseCanvas(o)},[o]),o})(e,k||F,P),N=((e,r)=>{const a=useSizeFixer(e.maskSrc||""),[o,i]=L(a,"anonymous");return useImageLoader(a?i:"loaded",a||"",e.id),t.useMemo(()=>{if(!o){return r}if(!r||!r.width||!r.height){return r}const t=S();t.width=Math.max(r.width,1),t.height=Math.max(r.height,1);const a=t.getContext("2d");if(!a){return r}a.drawImage(r,0,0),a.globalCompositeOperation="source-in";const i=function(t,e){const r=e.width/e.height;let a,o;return r>=t.width/t.height?(a=t.width,o=t.width/r):(a=t.height*r,o=t.height),{x:(t.width-a)/2,y:(t.height-o)/2,width:a,height:o}}(o,e);return a.drawImage(o,i.x,i.y,i.width,i.height,0,0,r.width,r.height),t},[r,o,e.a.width,e.a.height])})(e,B)||T;let{cropX:U,cropY:V,cropWidth:$,cropHeight:q}=e.a;"loaded"!==H&&(U=V=0,$=q=1);const J=N.width*$,G=N.height*q,K=e.a.width/e.a.height;let Q,Z;const tt=J/G,et=e.stretchEnabled;et?(Q=J,Z=G):K>=tt?(Q=J,Z=J/K):(Q=G*K,Z=G);const rt={x:N.width*U,y:N.height*V,width:Q,height:Z},at=null!==(h=e.cornerRadius)&&void 0!==h?h:0,ot=e.page._exportingOrRendering?1:Math.min(2,a.scale),it=a._elementsPixelRatio*ot;let nt=((e,r,a,o)=>{const i=useSizeFixer(e.clipSrc||""),[n,h]=L(i,"anonymous"),c=e.clipSrc?h:"loaded";useImageLoader(c,e.clipSrc,e.id);const s=t.useMemo(()=>{if(r&&n){return S()}},[r,n]);return t.useLayoutEffect(()=>{var t;if(!n){return}if(!r||!r.width||!r.height){return}if(!n||!n.width||!n.height){return}if(!s){return}const o=S(),i=Math.max(e.a.width/n.width*a,e.a.height/n.height*a);o.width=Math.max(n.width*i,1),o.height=Math.max(n.height*i,1),null===(t=o.getContext("2d"))||void 0===t||t.drawImage(n,0,0,o.width,o.height),s.width=Math.max(r.width,1),s.height=Math.max(r.height,1);const h=s.getContext("2d");h&&(h.save(),h.drawImage(o,0,0,r.width,r.height),l.Util.releaseCanvas(o),h.globalCompositeOperation="source-in",h.drawImage(r,0,0,s.width,s.height),h.restore())},[s,r,n,e.a.width,e.a.height,a,...o]),e.clipSrc&&n?s:r})(e,useCornerRadiusAndCrop(e,N,rt,it,at,m||e._cropModeEnabled||"svg"===e.type,!0),it,[rt,at,it]);const ht=Math.max(e.a.width/Q,e.a.height/Z);t.useEffect(()=>{var t;if(!e._cropModeEnabled){return}const r=null===(t=w.current)||void 0===t?void 0:t.getStage();function a(t){e._cropModeEnabled&&t.target!==C.current&&e.toggleCropMode(!1)}function o(t){e._cropModeEnabled&&t.target.parentNode!==(null==r?void 0:r.content)&&e.toggleCropMode(!1)}return document.body.addEventListener("click",o),null==r||r.on("click",a),null==r||r.on("tap",a),()=>{document.body.removeEventListener("click",o),document.body.removeEventListener("touchstart",o),null==r||r.off("click",a),null==r||r.off("click",a)}},[e._cropModeEnabled]),t.useLayoutEffect(()=>{if(!m&&!e._cropModeEnabled){return y(w.current,e),r(()=>{y(w.current,e)},{delay:100})}},[nt,e.page._exportingOrRendering,m,$,q,e._cropModeEnabled]),t.useLayoutEffect(()=>{var t;m||e._cropModeEnabled?null===(t=w.current)||void 0===t||t.clearCache():y(w.current,e)},[m,e.a.width,e.a.height,e._cropModeEnabled]),t.useEffect(()=>{y(w.current,e)},[e.shadowEnabled,e.shadowBlur,e.cornerRadius,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]);const ct=t.useRef(null),st=t.useRef(null),dt=t.useRef(null);t.useLayoutEffect(()=>{e._cropModeEnabled&&(st.current.nodes([ct.current]),dt.current.nodes([C.current]))},[e._cropModeEnabled]);var lt=t.useRef(null),gt=t.useRef(0),ut=t.useRef(!1);const mt=t=>{var r;(null===(r=t.evt.touches)||void 0===r?void 0:r.length)>2&&t.target.stopDrag(),Math.round(t.target.x())>0&&(t.target.x(0),t.target.scaleX(1)),Math.round(t.target.y())>0&&(t.target.y(0),t.target.scaleY(1));const a=t.target.width()*t.target.scaleX(),o=t.target.height()*t.target.scaleY(),i=Math.min(1,Q/a),n=Math.min(1,Z/o),h=1-i,c=Math.min(h,Math.max(0,Math.round(-t.target.x())/a)),s=1-n,d=Math.min(s,Math.max(0,Math.round(-t.target.y())/o));t.target.setAttrs({x:-c*N.width,y:-d*N.height,scaleX:1,scaleY:1}),e.set({cropX:c,cropY:d,cropWidth:i,cropHeight:n})},ft=()=>{"svg"!==e.type&&e.contentEditable&&(e.stretchEnabled||setTimeout(()=>{e.toggleCropMode(!0)}))},pt="svg"===e.type&&F,wt="loading"===H&&!pt,[xt]=E(wt,100,!1,!1),yt="failed"===H,Mt=!xt&&!yt,vt=t.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Et=Mt?e.a.opacity:0;M(w,Et);const bt=e.selectable||a.role===s.ADMIN,St=v(),It=b(e,e.borderColor,"stroke");return t.createElement(t.Fragment,null,xt&&t.createElement(D,{element:e}),yt&&t.createElement(A,{element:e}),t.createElement(i,{ref:w,name:"element",id:e.id,image:nt,x:e.a.x,y:e.a.y,width:e.a.width||1,height:e.a.height||1,rotation:e.a.rotation,opacity:Et,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,customCrop:rt,listening:bt,draggable:St?e.draggable&&O:e.draggable,preventDefault:!St||O,hideInExport:!e.showInExport,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDblClick:ft,onDblTap:ft,onTransformStart:()=>{f(!0),vt.current={cropX:e.cropX,cropY:e.cropY,cropWidth:e.cropWidth,cropHeight:e.cropHeight}},onTransform:t=>{var r;const a=t.currentTarget,o=Math.abs(a.scaleX()-1)<1e-7?1:a.scaleX(),i=Math.abs(a.scaleY()-1)<1e-7?1:a.scaleY();a.scaleX(1),a.scaleY(1);const n=null===(r=t.target.getStage())||void 0===r?void 0:r.findOne("Transformer"),h=1-Q/N.width,c=Math.min(h,Math.max(0,e.cropX)),s=1-Z/N.height,d=Math.min(s,Math.max(0,e.cropY)),l=n.getActiveAnchor(),g=!(l.indexOf("middle")>=0||l.indexOf("center")>=0),u=!g&&o<1&&vt.current.cropHeight>Z/N.height;let m=g?e.cropWidth:e.cropWidth*o;u&&(m=e.cropWidth);const f=!g&&i<1&&vt.current.cropWidth>Q/N.width;let p=g?e.cropHeight:e.cropHeight*i;f&&(p=e.cropHeight),et&&(m=e.cropWidth,p=e.cropHeight),e.set({cropX:c,cropY:d,x:a.x(),y:a.y(),width:a.width()*o,height:a.height()*i,rotation:t.target.rotation(),cropWidth:Math.min(m,1-c),cropHeight:Math.min(p,1-d)})},onTransformEnd:t=>{const r=t.currentTarget;e.set({width:r.width(),height:r.height(),x:r.x(),y:r.y(),rotation:t.target.rotation(),cropWidth:Q/N.width,cropHeight:Z/N.height}),f(!1)}}),t.createElement(n,Object.assign({x:e.x,y:e.y,width:Math.max(e.a.width-e.borderSize,0),height:Math.max(e.a.height-e.borderSize,0),opacity:Et,offsetX:-e.borderSize/2,offsetY:-e.borderSize/2},It,{strokeWidth:e.borderSize,listening:!1,visible:!!e.borderSize,rotation:e.rotation,cornerRadius:Math.max(0,at-e.borderSize),hideInExport:!e.showInExport})),e._cropModeEnabled&&t.createElement(g,{selector:".page-abs-container",enabled:!0},t.createElement(n,{x:-window.innerWidth/a.scale,y:-window.innerWidth/a.scale,width:window.innerWidth/a.scale*3,height:window.innerWidth/a.scale*3,fill:d.cropOverlayFill}),t.createElement(i,{listening:!1,image:nt,x:e.x,y:e.y,width:e.a.width,height:e.a.height,rotation:e.rotation,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur}),t.createElement(o,{x:e.x,y:e.y,rotation:e.rotation,scaleX:ht,scaleY:ht},t.createElement(i,{image:N,ref:C,opacity:.4,draggable:!0,x:-e.cropX*N.width,y:-e.cropY*N.height,onDragMove:mt,onTransform:mt,onTouchMove:t=>{t.evt.preventDefault();const e=t.target.getStage().getPointersPositions();var r=e[0],a=e[1];const o=t.target;if(r&&!a&&!o.isDragging()&&ut.current&&(o.startDrag(),ut.current=!1),r&&a){l.hitOnDragEnabled=!0,o.isDragging()&&(ut.current=!0,o.stopDrag());const e=t.target.getAbsoluteTransform().copy();e.invert();var i={x:r.x,y:r.y},n={x:a.x,y:a.y};if(!lt.current){return void(lt.current=R(i,n))}var h=R(i,n),c=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}(i,n);gt.current||(gt.current=c);const f=o.position();var s={x:h.x-f.x,y:h.y-f.y},d=c/gt.current;o.scaleX(d),o.scaleY(d);const p=e.point(h),w=e.point(lt.current);var g=p.x-w.x,u=p.y-w.y,m={x:Math.min(0,h.x-s.x*d+g),y:Math.min(0,h.y-s.y*d+u)};o.position(m),gt.current=c,lt.current=h,mt(t)}},onTouchEnd:t=>{gt.current=0,lt.current=null,l.hitOnDragEnabled=!1}}),t.createElement(c,Object.assign({ref:dt},Y,d.outerImageCropTransformerStyle)),t.createElement(n,{width:Q,height:Z,ref:ct,listening:!1,onTransform:t=>{if(e.cropX<Math.abs(t.target.x()/N.width)&&t.target.x()<0&&e.cropX>0){const r=(e.cropWidth+e.cropX)*N.width;t.target.scaleX(1),t.target.width(r)}if(e.cropY<Math.abs(t.target.y()/N.height)&&t.target.y()<0&&e.cropY>0){const r=(e.cropHeight+e.cropY)*N.height;t.target.scaleY(1),t.target.height(r)}t.target.x()<-e.cropX*N.width-1e-9&&(t.target.x(-e.cropX*N.width),t.target.scaleX(1)),t.target.y()<-e.cropY*N.height-1e-9&&(t.target.y(-e.cropY*N.height),t.target.scaleY(1));const r=Math.min(1,Math.max(0,e.cropX+t.target.x()/N.width)),a=Math.min(1,Math.max(0,t.target.y()/N.height+e.cropY)),o=t.target.width()*t.target.scaleX(),i=t.target.height()*t.target.scaleY(),n=Math.min(1-r,o/N.width),h=Math.min(1-a,i/N.height),c=t.target.getAbsolutePosition(t.target.getParent().getParent());t.target.scale({x:1,y:1}),t.target.position({x:0,y:0}),e.set({x:c.x,y:c.y,cropX:r,cropY:a,cropWidth:n,cropHeight:h,width:Math.min(o*ht,N.width*(1-r)*ht),height:Math.min(i*ht,N.height*(1-a)*ht)})}}),t.createElement(c,Object.assign({ref:st},X,d.innerImageCropTransformerStyle,{visible:e.resizable})))))});
|
package/canvas/page.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Vector2d } from 'konva/lib/types';
|
|
|
3
3
|
import { StoreType } from '../model/store.js';
|
|
4
4
|
import { PageType } from '../model/page-model.js';
|
|
5
5
|
import { NodeType } from '../model/node-model.js';
|
|
6
|
+
import type { GroupClickBehavior } from './workspace-canvas.js';
|
|
6
7
|
export declare function registerTransformerAttrs(type: any, attrs: any): void;
|
|
7
8
|
export declare const useContextMenu: ({ store }: {
|
|
8
9
|
store: StoreType;
|
|
@@ -37,6 +38,7 @@ type PageProps = {
|
|
|
37
38
|
pageControlsEnabled?: boolean;
|
|
38
39
|
components: any;
|
|
39
40
|
altCloneEnabled?: boolean;
|
|
41
|
+
groupClickBehavior?: GroupClickBehavior;
|
|
40
42
|
viewportSize: {
|
|
41
43
|
width: number;
|
|
42
44
|
height: number;
|
|
@@ -55,7 +57,7 @@ type PageProps = {
|
|
|
55
57
|
right?: number;
|
|
56
58
|
};
|
|
57
59
|
};
|
|
58
|
-
declare const _default: (({ store, page, width, height, pageControlsEnabled, components, altCloneEnabled, viewportSize, layout, tooltipSafeArea, transformerSafeArea, }: PageProps) => React.JSX.Element) & {
|
|
60
|
+
declare const _default: (({ store, page, width, height, pageControlsEnabled, components, altCloneEnabled, groupClickBehavior, viewportSize, layout, tooltipSafeArea, transformerSafeArea, }: PageProps) => React.JSX.Element) & {
|
|
59
61
|
displayName: string;
|
|
60
62
|
};
|
|
61
63
|
export default _default;
|
package/canvas/page.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__rest||function(e,t){var n={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++){t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]])}}return n};import t from"react";import{observer as n,useLocalObservable as i}from"mobx-react-lite";import{action as o,runInAction as r}from"mobx";import{Group as l,Image as a,Label as s,Layer as c,Line as d,Rect as m,Stage as u,Tag as h,Text as g,Transformer as x,KonvaRenderer as p}from"react-konva";import f from"use-image";import{useWorkspaceStyle as b}from"./workspace-style.js";import{ROLES as v}from"../model/store.js";import y from"konva";import E from"./element.js";import{DrawingLayer as w}from"./drawing-layer.js";import{ensureDragOrder as X,useSnap as Y}from"./use-transformer-snap.js";import{useImageLoader as k}from"./image-element.js";import{getCrop as S}from"../utils/crop.js";import{___ as A,____ as M,isCreditVisible as R}from"../utils/validate-key.js";import{getClientRect as I,getTotalClientRect as O}from"../utils/math.js";import{pxToUnitRounded as P,pxToUnitString as j}from"../utils/unit.js";import{flags as D}from"../utils/flags.js";import{useColor as C}from"./use-color.js";import{isGradient as T}from"../utils/gradient.js";import{Html as B}from"react-konva-utils";import{observerBatching as W}from"mobx-react-lite";const G=e=>p.batchedUpdates(e,null);W(e=>{p.isAlreadyRendering()?queueMicrotask(()=>G(e)):G(e)});const L=y.DD._drag;window.removeEventListener("mousemove",L),y.DD._drag=function(e){r(()=>{L.call(this,e)})},window.addEventListener("mousemove",y.DD._drag);const V={enabledAnchors:["top-left","top-center","top-right","middle-left","bottom-left","bottom-right","bottom-center","middle-right"],rotateEnabled:!0,rotationSnaps:[0,45,90,135,180,225,270,315],ignoreStroke:!0,flipEnabled:!1,keepRatio:!0},F={text:{enabledAnchors:["top-left","top-right","middle-left","bottom-left","bottom-right","middle-right"]},svg:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},gif:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},line:{enabledAnchors:[],borderEnabled:!1,rotateEnabled:!1},image:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},many:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},group:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},table:{keepRatio:!1,enabledAnchors:["top-left","top-right","middle-left","middle-right","bottom-left","bottom-right"]}};export function registerTransformerAttrs(e,t){F[e]=F[e]||t,Object.assign(F[e],t)}const U=e=>t.createElement(m,Object.assign({},e,{preventDefault:!1})),z=n=>{var{url:i}=n,o=e(n,["url"]);const[r,l]=f(i,"anonymous"),s=r?S(r,{width:o.width,height:o.height},"center-middle"):{};return k(l,i,"page background"),t.createElement(a,Object.assign({image:r},o,s))},Z=e=>{const n=C({a:{width:e.width,height:e.height},width:e.width,height:e.height},e.fill);return t.createElement(m,Object.assign({},e,n))},_=n=>{const{background:i,scale:o,borderColor:r,transparencyBackgroundColor:l}=n,a=e(n,["background","scale","borderColor","transparencyBackgroundColor"]),s=t.useMemo(()=>!!y.Util.colorToRGBA(i)||T(i),[i]),c=t.useMemo(()=>{if(T(i)){return!0}const e=y.Util.colorToRGBA(i);return!e||e.a<1},[i]),d=t.useMemo(()=>{if(!c||l){return null}const e=document.createElement("canvas"),t=30;e.width=60,e.height=60;const n=e.getContext("2d");return n&&(n.fillStyle="black",n.fillRect(t,0,t,t),n.fillRect(0,t,t,t)),e},[c,l]);return t.createElement(t.Fragment,null,c&&(l?t.createElement(m,Object.assign({fill:l},a,{hideInExport:!0})):t.createElement(m,Object.assign({fillPatternImage:d},a,{opacity:.1,hideInExport:!0}))),s?t.createElement(Z,Object.assign({fill:i},a)):t.createElement(z,Object.assign({url:i},a)))},H=n(({selection:e})=>{if(!e.visible){return null}const{selectionRectStyle:n}=b();return t.createElement(m,{name:"selection",x:Math.min(e.x1,e.x2),y:Math.min(e.y1,e.y2),width:Math.abs(e.x1-e.x2),height:Math.abs(e.y1-e.y2),fill:n.fill,stroke:n.stroke,strokeWidth:n.strokeWidth})});function J(e){let t=180*e/Math.PI;return t%=360,t>180?t-=360:t<-180&&(t+=360),Math.round(t)}const N=n(({x:e,y:n,width:i,height:o,rotation:r,anchor:l,store:a})=>{const{transformLabelStyle:c}=b();if(void 0===e||void 0===n||void 0===i||void 0===o||void 0===r||void 0===l){return null}const d=I({x:e,y:n,width:i,height:o,rotation:y.Util.radToDeg(r)}),m=(o/2+70)*Math.cos(r-Math.PI/2),u=(o/2+70)*Math.sin(r-Math.PI/2),x=P({unit:a.unit,dpi:a.dpi,px:i/a.scale,precious:"px"===a.unit?0:1})+" x "+P({unit:a.unit,dpi:a.dpi,px:o/a.scale,precious:"px"===a.unit?0:1})+("px"===a.unit?"":" "+a.unit);return t.createElement(t.Fragment,null,t.createElement(s,{x:(d.minX+d.maxX)/2+m,y:(d.minY+d.maxY)/2+u,offsetX:14,offsetY:14,visible:"rotater"===l},t.createElement(h,{cornerRadius:5,fill:c.fill}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:c.textFill,padding:8,text:J(r).toString()+"°"})),t.createElement(s,{x:(d.minX+d.maxX)/2,y:d.maxY+20,visible:"rotater"!==l},t.createElement(h,{cornerRadius:5,fill:c.fill,pointerDirection:"up",pointerHeight:0,pointerWidth:0}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:c.textFill,padding:8,text:x})))}),K=n(({elements:e,store:n})=>{const i=e.filter(e=>e.alwaysOnTop),o=e.filter(e=>!e.alwaysOnTop).concat(i);return t.createElement(t.Fragment,null,o.map(e=>t.createElement(E,{key:e.id,store:n,element:e,onClick:()=>{console.warn("Polotno warning: onClick callback is deprecated. Just stop using it. Polotno will do selection automatically.")}})))});export const useContextMenu=({store:e})=>{const[n,i]=t.useState(!1),[o,r]=t.useState({x:0,y:0}),l=t.useCallback(e=>{i(!0),r(e)},[]);return{open:l,close:t.useCallback(()=>{i(!1)},[]),props:{isOpen:n,offset:o,setIsOpen:i}}};let $=null;export const registerNextDomDrop=e=>{$=e};const Q=atob("UG9sb3RubyBmcmVlIGxpY2Vuc2UgbGltaXRhdGlvbiBleGNlZWRlZCAtIFBsZWFzZSB1cGdyYWRlIHlvdXIgYWNjb3VudC4="),q=atob("I2MwMzkyYg=="),ee=atob("djAuOS4y"),te=e=>t.createElement(t.Fragment,null,t.createElement(s,{fill:q,height:200},t.createElement(h,{fill:q}),t.createElement(g,Object.assign({},e,{fill:"white",text:Q,height:void 0,padding:10,fontSize:20})))),ne=atob("RlJFRSAgVFJJQUwgIExJQ0VOU0U="),ie=(atob("UG93ZXJlZCBieSBQb2xvdG5v"),atob("TElDRU5TRSAgS0VZICBJUyAgTUlTU0lORw==")),oe=atob("UGxlYXNlIGFjdGl2YXRlIHlvdXIgbGljZW5zZS4KTGljZW5zZSByZWxhdGVkIHF1ZXN0aW9uczoKcG9sb3Ruby5jb20vY29udGFjdA=="),re=e=>{const n=1===M(),i=n?ie:ne,o=n?230:195;return t.createElement(l,Object.assign({},e,{listening:!1}),t.createElement(m,{fill:q,width:o,height:24,cornerRadius:2}),t.createElement(g,{text:i,fill:"white",fontSize:13,fontFamily:"monospace",width:o,align:"center",y:5,listening:!1}),n&&t.createElement(g,{text:oe,fill:"rgba(0,0,0,0.6)",fontSize:14,y:30,listening:!1}))};export default n(({store:e,page:n,width:r,height:a,pageControlsEnabled:p,components:f,altCloneEnabled:E,viewportSize:k,layout:S="vertical",tooltipSafeArea:P,transformerSafeArea:C})=>{const T=b(),W=T.transformerStyle,G=V,L=e.bleedVisible?n.bleed:0,z=n.computedWidth+2*L,Z=n.computedHeight+2*L,J=(r-z*e.scale)/2,Q=(a-Z*e.scale)/2,q=t.useRef(null),ne=t.useRef(null),ie=t.useRef(null),oe=null==p||p,le=t.useRef(!1),[ae,se]=t.useState(null),[ce,de]=t.useState({}),[me,ue]=t.useState(0),he=useContextMenu({store:e}),ge=e.selectedElements.find(e=>e._cropModeEnabled),xe=e.selectedElements.find(e=>e.curveEnabled),pe=e.selectedShapes.filter(e=>!e.resizable).length>0,fe=e.selectedShapes.filter(e=>!e.draggable).length>0,be=e.selectedElements.filter(e=>!e.visible).length>0;t.useLayoutEffect(()=>{var t,n,i;if(!q.current){return}const o=q.current.getStage(),r=e.selectedShapes.map(e=>e._cropModeEnabled?null:o.findOne("#"+e.id)).filter(e=>!!e),l=1===e.selectedElements.length,a=l&&(null===(t=e.selectedElements[0])||void 0===t?void 0:t.type)||"many",s=F[a],c=Object.assign(Object.assign({},G),s||{});s&&("svg"!==a&&"image"!==a&&"gif"!==a||e.selectedElements[0].keepRatio||(c.enabledAnchors=G.enabledAnchors),"text"===a&&D.textVerticalResizeEnabled&&(c.enabledAnchors=null===(n=F.text.enabledAnchors)||void 0===n?void 0:n.concat(["bottom-center","top-center"])),"text"===a&&l&&e.selectedElements[0].curveEnabled&&(c.enabledAnchors=F.many.enabledAnchors)),q.current.setAttrs(Object.assign(Object.assign({},c),W)),pe&&q.current.enabledAnchors([]),fe&&q.current.rotateEnabled(!1),r.find(e=>null==e?void 0:e.isDragging())&&r.forEach(e=>{e.isDragging()||null==e||e.startDrag()}),q.current.nodes(r),X(),null===(i=q.current.getLayer())||void 0===i||i.batchDraw()},[e.selectedShapes,ge,pe,be,fe,xe,W]);const ve=()=>{var e,t;const n=q.current;if(!n){return}if(!n.isTransforming()){return void de({})}if(!n.nodes().length||!n.isTransforming()){return}const i=n.__getNodeRect(),o=null==n?void 0:n.getActiveAnchor(),r=n.getStage();de({anchor:o,x:i.x-(null!==(e=null==r?void 0:r.x())&&void 0!==e?e:0),y:i.y-(null!==(t=null==r?void 0:r.y())&&void 0!==t?t:0),rotation:i.rotation,width:i.width,height:i.height})},ye=t.useCallback(()=>{var e;if(null===(e=q.current)||void 0===e?void 0:e.isTransforming()){return}const t=q.current;if(!t||!t.nodes().length){return void ue(0)}const n=t.getClientRect();if(!t.getStage()){return}const i=function(e,t,n,i=0){const o=e.x+e.width/2,r=e.y+e.height/2,l=e.width/2,a=e.height/2,s=i*Math.PI/180,c=e=>{const t=e*Math.PI/180,i=(e%360+360)%360;let c;c=0===i||180===i?a:l;const d=Math.sin(t)*(c+n),m=-Math.cos(t)*(c+n),u=d*Math.cos(s)-m*Math.sin(s),h=d*Math.sin(s)+m*Math.cos(s);return{x:o+u,y:r+h}},d=e=>e.x>=t.left&&e.x<=t.right&&e.y>=t.top&&e.y<=t.bottom;if(d(c(0))){return 0}for(const m of[180,270,90]){if(d(c(m))){return m}}return 0}(n,{top:(null==C?void 0:C.top)||0,bottom:a-((null==C?void 0:C.bottom)||0),left:(null==C?void 0:C.left)||0,right:r-((null==C?void 0:C.right)||0)},W.rotateAnchorOffset,t.rotation());ue(i)},[C,r,a]);t.useEffect(()=>{var e;null===(e=q.current)||void 0===e||e.update(),ve(),ye()},[e.scale,ye]),t.useEffect(()=>{ye()},[e.selectedShapes,ye]);const Ee=i(()=>({visible:!1,x1:0,y1:0,x2:0,y2:0})),we=t.useRef(!1),Xe=o(t=>{var n,i,o,r,l,a,s;if(e.role===v.VIEWER){return}we.current=!1;const c=t.target.findAncestor(".elements-container"),d=t.target.findAncestor("Transformer"),m=t.target.findAncestor(".page-abs-container");if(c||d||m){return}const u=null===(n=t.target.getStage())||void 0===n?void 0:n.getPointerPosition();u&&(u.x-=null!==(o=null===(i=t.target.getStage())||void 0===i?void 0:i.x())&&void 0!==o?o:0,u.y-=null!==(l=null===(r=t.target.getStage())||void 0===r?void 0:r.y())&&void 0!==l?l:0,Ee.visible=!0,Ee.x1=u.x,Ee.y1=u.y,Ee.x2=u.x,Ee.y2=u.y,(null!==(s=null===(a=t.target.getStage())||void 0===a?void 0:a.getPointersPositions().length)&&void 0!==s?s:0)>=2&&(Ee.visible=!1))});(({stageRef:e,containerRef:n,viewportSize:i})=>{t.useEffect(()=>{var t;const i=null===(t=n.current)||void 0===t?void 0:t.closest(".polotno-workspace-inner");function o(){var t;if(!e.current){return}const o=null===(t=n.current)||void 0===t?void 0:t.getBoundingClientRect(),r=null==i?void 0:i.getBoundingClientRect();if(!o||!r){return}const l=Math.max(0,r.left-o.left-100),a=Math.max(0,r.top-o.top-100);e.current.position({x:-l,y:-a}),e.current.container().style.transform=`translate(${l}px, ${a}px)`}return o(),null==i||i.addEventListener("scroll",o),()=>{null==i||i.removeEventListener("scroll",o)}},[i.width,i.height])})({stageRef:ne,containerRef:ie,viewportSize:k}),t.useEffect(()=>{const t=o(e=>{var t,n,i,o,r,l;if(!Ee.visible){return}null===(t=ne.current)||void 0===t||t.setPointersPositions(e);let a=null===(n=ne.current)||void 0===n?void 0:n.getPointerPosition();a?(a.x-=null!==(o=null===(i=ne.current)||void 0===i?void 0:i.x())&&void 0!==o?o:0,a.y-=null!==(l=null===(r=ne.current)||void 0===r?void 0:r.y())&&void 0!==l?l:0):a={x:Ee.x2,y:Ee.y2},Ee.x2=a.x,Ee.y2=a.y}),n=o(()=>{if(!Ee.visible){return}if(!ne.current){return}const t=ne.current.findOne(".selection"),n=t?t.getClientRect({skipStroke:!0}):{width:0,height:0,x:0,y:0};if(n.width&&n.height){const t=[];ne.current.find(".element").forEach(i=>{const o=i.getClientRect(),r=e.getElementById(i.id()),l=null==r?void 0:r.draggable,a=null==r?void 0:r.selectable;y.Util.haveIntersection(n,o)&&l&&a&&t.push(r.top.id)});const i=[...new Set(t)];we.current=!0,e.selectElements(i)}Ee.visible=!1});return window.addEventListener("mousemove",t),window.addEventListener("touchmove",t),window.addEventListener("mouseup",n,{capture:!0}),window.addEventListener("touchend",n,{capture:!0}),()=>{window.removeEventListener("mousemove",t),window.removeEventListener("touchmove",t),window.removeEventListener("mouseup",n),window.removeEventListener("touchend",n)}},[]);const Ye=t.useCallback(t=>{if(!e.selectedElements[0]){return}if(t&&e.selectedElementsIds.includes(t)){return}const i=O(e.selectedShapes),o=t?e.getElementById(t):{x:0,y:0,width:n.computedWidth,height:n.computedHeight,rotation:0},r=I(o),l=[];i.minX>r.maxX&&l.push({distance:i.minX-r.maxX,box1:i,box2:r,points:[{x:i.minX,y:i.minY+i.height/2},{x:r.maxX,y:i.minY+i.height/2},{x:r.maxX,y:r.minY+r.height/2}]}),i.maxX<r.minX&&l.push({distance:r.minX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:i.minY+i.height/2},{x:r.minX,y:i.minY+i.height/2},{x:r.minX,y:r.minY+r.height/2}]}),i.minY>r.maxY&&l.push({box1:i,box2:r,distance:i.minY-r.maxY,points:[{x:i.minX+i.width/2,y:i.minY},{x:i.minX+i.width/2,y:r.maxY},{x:r.minX+r.width/2,y:r.maxY}]}),i.maxY<r.minY&&l.push({box1:i,box2:r,distance:r.minY-i.maxY,points:[{x:i.minX+i.width/2,y:i.maxY},{x:i.minX+i.width/2,y:r.minY},{x:r.minX+r.width/2,y:r.minY}]});const a=i.minX>=r.minX&&i.maxX<=r.maxX&&i.minY>=r.minY&&i.maxY<=r.maxY;if(a&&(l.push({distance:i.minX-r.minX,box1:i,box2:r,points:[{x:i.minX,y:i.minY+i.height/2},{x:r.minX,y:i.minY+i.height/2},{x:r.minX,y:r.minY+r.height/2}]}),l.push({distance:r.maxX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:i.minY+i.height/2},{x:r.maxX,y:i.minY+i.height/2},{x:r.maxX,y:r.minY+r.height/2}]}),l.push({box1:i,box2:r,distance:i.minY-r.minY,points:[{x:i.minX+i.width/2,y:i.minY},{x:i.minX+i.width/2,y:r.minY},{x:r.minX+r.width/2,y:r.minY}]}),l.push({box1:i,box2:r,distance:r.maxY-i.maxY,points:[{x:i.minX+i.width/2,y:i.maxY},{x:i.minX+i.width/2,y:r.maxY},{x:r.minX+r.width/2,y:r.maxY}]})),0===l.length&&!a){const e=i.minX<r.maxX&&i.maxX>r.minX,t=i.minY<r.maxY&&i.maxY>r.minY;if(e&&t){const e=(Math.max(i.minY,r.minY)+Math.min(i.maxY,r.maxY))/2,t=(Math.max(i.minX,r.minX)+Math.min(i.maxX,r.maxX))/2;i.minX<r.minX?l.push({distance:r.minX-i.minX,box1:i,box2:r,points:[{x:i.minX,y:e},{x:r.minX,y:e},{x:r.minX,y:e}]}):l.push({distance:i.minX-r.minX,box1:i,box2:r,points:[{x:i.minX,y:e},{x:r.minX,y:e},{x:r.minX,y:e}]}),i.maxX>r.maxX?l.push({distance:i.maxX-r.maxX,box1:i,box2:r,points:[{x:r.maxX,y:e},{x:i.maxX,y:e},{x:r.maxX,y:e}]}):l.push({distance:r.maxX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:e},{x:r.maxX,y:e},{x:r.maxX,y:e}]}),i.minY<r.minY?l.push({box1:i,box2:r,distance:r.minY-i.minY,points:[{x:t,y:i.minY},{x:t,y:r.minY},{x:t,y:r.minY}]}):l.push({box1:i,box2:r,distance:i.minY-r.minY,points:[{x:t,y:i.minY},{x:t,y:r.minY},{x:t,y:r.minY}]}),i.maxY>r.maxY?l.push({box1:i,box2:r,distance:i.maxY-r.maxY,points:[{x:t,y:r.maxY},{x:t,y:i.maxY},{x:t,y:r.maxY}]}):l.push({box1:i,box2:r,distance:r.maxY-i.maxY,points:[{x:t,y:i.maxY},{x:t,y:r.maxY},{x:t,y:r.maxY}]})}}JSON.stringify(ae)!==JSON.stringify(l)&&se(l)},[e,n]);t.useEffect(()=>{e.selectedElements[0]&&e.distanceGuidesVisible?Ye():ae&&se(null)},[e.distanceGuidesVisible,Ye,e.selectedShapes.map(e=>`${e.x},${e.y},${e.width},${e.height},${e.rotation}`).join("|")]);const ke=t.useRef(!1);t.useEffect(()=>{var e;let t;const n=null===(e=ie.current)||void 0===e?void 0:e.closest(".polotno-workspace-inner"),i=()=>{ke.current=!0,clearTimeout(t),t=setTimeout(()=>{ke.current=!1},300)};return null==n||n.addEventListener("scroll",i),()=>{clearTimeout(t),null==n||n.removeEventListener("scroll",i)}},[]),t.useEffect(()=>{const e=ne.current;if(!e){return}const t=e.container(),n=e=>{var t,n;e.touches.length>=2&&((null===(t=q.current)||void 0===t?void 0:t.isDragging())&&q.current.stopDrag(),null===(n=q.current)||void 0===n||n.nodes().forEach(e=>{e.isDragging()&&e.stopDrag()}))};return t.addEventListener("touchstart",n,{passive:!0}),t.addEventListener("touchmove",n,{passive:!0}),()=>{t.removeEventListener("touchstart",n),t.removeEventListener("touchmove",n)}},[]);const Se=t=>{if(e.role===v.VIEWER){return}if(e.activePage!==n&&n.select(),ke.current){return}if(we.current){return}const i=t.evt.ctrlKey||t.evt.metaKey||t.evt.shiftKey,o=t.target.findAncestor(".elements-container"),r=t.target.findAncestor(".page-abs-container"),l=t.target.findAncestor("Transformer"),a=t.target.findAncestor(".page-container",!0);if(!(i||o||l||r||a||Ee.visible)){return e.selectElements([]),void e.selectPages([])}const s=t.target.findAncestor(".element-container",!0),c=(null==s?void 0:s.findOne(".element"))||t.target.findAncestor(".element",!0),d=e.getElementById(null==c?void 0:c.id()),m=null==d?void 0:d.top,u=null==m?void 0:m.id,h=e.selectedElementsIds.indexOf(u)>=0,g=t.target.findAncestor(".page-container",!0);u&&i&&!h?(e.selectElements(e.selectedElementsIds.concat([u])),e.selectPages([])):u&&i&&h?e.selectElements(e.selectedElementsIds.filter(e=>e!==u)):!u||i||h?u&&!i&&h||(g?(i||e.selectElements([]),e.selectPages([n.id])):e.selectPages([])):(e.selectElements([u]),e.selectPages([]))};Y(q,e);const Ae=e.activePage===n,Me=e._selectedPagesIds.includes(n.id),Re=null==f?void 0:f.PageControls,Ie=null==f?void 0:f.Tooltip,Oe=null==f?void 0:f.ContextMenu,Pe=1/e.scale,je=0/e.scale;return t.createElement("div",{ref:ie,onDragOver:e=>e.preventDefault(),onDrop:t=>{if(t.preventDefault(),e.role===v.VIEWER){return}if(!ne.current){return}ne.current.setPointersPositions(t);const i=ne.current.findOne(".elements-container"),o=null==i?void 0:i.getRelativePointerPosition(),r=ne.current.getPointerPosition(),l=ne.current.getAllIntersections(r).map(e=>e.findAncestor(".element",!0)).filter(Boolean),a=[...new Set(l.reverse())].map(t=>e.getElementById(t.id())).filter(e=>!!e),s=a[0];$&&o&&($(o,s,{elements:a,page:n}),$=null)},style:{position:"relative",width:r+"px",height:a+"px",overflow:"hidden",flexShrink:0},className:"polotno-page-container"+(Ae?" active-page":"")},t.createElement(u,{ref:ne,width:Math.min(r,k.width+200),height:Math.min(k.height+200,a),onClick:Se,onTap:Se,onContextMenu:t=>{if(t.evt.preventDefault(),e.role===v.VIEWER){return}const n=t.target.findAncestor(".element",!0),i=e.getElementById(null==n?void 0:n.id()),o=null==i?void 0:i.top,r=null==o?void 0:o.id;r?e.selectedElementsIds.indexOf(r)>=0||e.selectElements([r]):e.selectElements([]),he.open({x:t.evt.clientX,y:t.evt.clientY})},onMouseDown:Xe,onMouseMove:t=>{if(!e.distanceGuidesVisible&&!t.evt.altKey){return void(ae&&se(null))}const n=t.target.findAncestor(".element",!0),i=null==n?void 0:n.id();Ye(i)},onDragStart:t=>{var n;const i=t.target.getStage();if(i&&i.getPointersPositions().length>=2){return void t.target.stopDrag()}const o=t.target.findAncestor(".element",!0);if(o){const i=e.getElementById(null==o?void 0:o.id()),r=null==i?void 0:i.top,l=null==r?void 0:r.id;!(e.selectedElementsIds.indexOf(l)>=0)&&l&&(e.selectElements([l]),t.target.stopDrag(),t.target.startDrag(t),null===(n=q.current)||void 0===n||n.startDrag(t))}ae&&se(null)},pageId:n.id,style:{position:"absolute",overflow:"hidden",top:0,left:0}},t.createElement(c,null,t.createElement(U,{width:r,height:a,fill:T.workspaceBackgroundColor}),t.createElement(l,{x:J,y:Q,scaleX:e.scale,scaleY:e.scale,name:"page-container"},t.createElement(l,{name:"page-container-2"},t.createElement(l,{name:"page-background-group",x:L,y:L},t.createElement(_,{x:-n.bleed,y:-n.bleed,width:n.computedWidth+2*n.bleed,height:n.computedHeight+2*n.bleed,background:n.background,transparencyBackgroundColor:T.transparencyBackgroundColor,name:"page-background",preventDefault:!1,scale:e.scale})),t.createElement(l,{x:L,y:L,name:"elements-container",listening:!e.isPlaying&&e.role!==v.VIEWER},t.createElement(m,{name:"elements-area",width:n.computedWidth,height:n.computedHeight,listening:!1}),t.createElement(K,{elements:n.children,store:e})),t.createElement(m,{stroke:T.bleedColor,name:"bleed",strokeWidth:n.bleed,x:n.bleed/2,y:n.bleed/2,width:n.computedWidth+n.bleed,height:n.computedHeight+n.bleed,listening:!1,visible:n.bleed>0&&e.bleedVisible,hideInExport:!0}),A()===ee&&t.createElement(te,{name:"hit-detection",x:-Pe/2-je,y:-Pe/2-je,width:z+Pe+2*je,height:Z+Pe+2*je}))),t.createElement(d,{name:"workspace-background",points:[0,0,r,0,r,a,0,a,0,0,J,Q,J,a-Q,r-J,a-Q,r-J,Q,J,Q],listening:!1,closed:!0,fill:T.workspaceBackgroundColor}),t.createElement(l,{x:J,y:Q,scaleX:e.scale,scaleY:e.scale},t.createElement(m,{name:"page-highlight",hideInExport:!0,x:-Pe/2-je,y:-Pe/2-je,width:z+Pe+2*je,height:Z+Pe+2*je,stroke:Me?T.activePageBorderColor:T.pageBorderColor,strokeWidth:2,listening:!1,strokeScaleEnabled:!1})),t.createElement(l,{x:J+L*e.scale,y:Q+L*e.scale,scaleX:e.scale,scaleY:e.scale,name:"page-abs-container"},t.createElement(x,{ref:q,rotateAnchorAngle:me,onDragStart:t=>{var i;const o=t.target.getStage();o&&o.getPointersPositions().length>=2?t.target.stopDrag():((null===(i=t.evt)||void 0===i?void 0:i.altKey)&&E&&e.selectedElements.forEach(e=>{const t=e.clone({},{skipSelect:!0}),i=n.children.indexOf(e);n.setElementZIndex(t.id,i)}),le.current=!0,e.history.startTransaction())},onDragEnd:()=>{le.current&&(e.history.endTransaction(),le.current=!1),ye()},onTransformStart:()=>{e.history.startTransaction(),se(null)},boundBoxFunc:(t,n)=>{var i;const o=Math.abs(n.width)<1||Math.abs(n.height)<1,r=Math.abs(t.width)<1||Math.abs(t.height)<1;if(o&&!r){return t}const l=e.selectedElements;if(1===l.length&&"table"===(null===(i=l[0])||void 0===i?void 0:i.type)){const e=l[0],i=Math.abs(t.width),o=Math.abs(t.height);if(i>0&&o>0){const r=Math.abs(n.width)/i,l=Math.abs(n.height)/o,a=e.width*r,s=e.height*l,c=Object.assign({},n);return a<e.minWidth&&(c.width=t.width,c.x=t.x),s<e.minHeight&&(c.height=t.height,c.y=t.y),c}}return n},onTransform:e=>{const t=q.current.nodes(),n=t[t.length-1];e.target===n&&setTimeout(()=>{ve()},0)},onTransformEnd:t=>{de({}),e.history.endTransaction(),ye()},visible:!e.isPlaying}),ae&&ae.map(({points:n,distance:i,box1:o,box2:r},a)=>t.createElement(l,{name:"distances-container",hideInExport:!0,key:a,listening:!1},t.createElement(m,Object.assign({},o,{stroke:T.distanceGuideStyle.stroke,strokeWidth:1,strokeScaleEnabled:!1})),t.createElement(m,Object.assign({},r,{stroke:T.distanceGuideStyle.stroke,strokeWidth:1,strokeScaleEnabled:!1})),t.createElement(d,{points:[n[0].x,n[0].y,n[1].x,n[1].y],stroke:T.distanceGuideStyle.stroke,strokeWidth:1,strokeScaleEnabled:!1}),t.createElement(d,{points:[n[1].x,n[1].y,n[2].x,n[2].y],stroke:T.distanceGuideStyle.stroke,strokeWidth:1,strokeScaleEnabled:!1}),t.createElement(s,{x:(n[0].x+n[1].x)/2,y:(n[0].y+n[1].y)/2,offsetY:-10,scaleX:1/e.scale,scaleY:1/e.scale},t.createElement(h,{cornerRadius:5,fill:T.distanceGuideStyle.labelFill,pointerDirection:"down"}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:T.distanceGuideStyle.labelTextFill,padding:5,text:j({unit:e.unit,dpi:e.dpi,px:i})})))),n._rendering&&t.createElement(l,null,t.createElement(m,{width:z,height:Z,fill:"rgba(255,255,255,0.9)"}),t.createElement(g,{text:"Rendering...",fontSize:60,width:z,height:Z,align:"center",verticalAlign:"middle"})),Ie&&t.createElement(Ie,{components:f,store:e,page:n,stageRef:ne,tooltipSafeArea:P}),Oe&&t.createElement(B,null,t.createElement(Oe,Object.assign({components:f,store:e},he.props)))),t.createElement(w,{store:e,page:n,width:r,height:a,scale:e.scale,xPadding:J,yPadding:Q,bleed:L}),t.createElement(N,Object.assign({},ce,{store:e})),t.createElement(H,{selection:Ee}),M()>0&&t.createElement(l,{hideInExport:!0},t.createElement(re,{name:"cache-bounds",x:r-(1===M()?250:210),y:a-(1===M()?95:45)}),t.createElement(re,{name:"cache-bounds-t",x:10,y:10})),R()&&t.createElement(g,{text:"Powered by polotno.com",fontSize:14,fill:"rgba(0,0,0,0.6)",x:r-170,y:a-18,onMouseEnter:e=>{e.target.getStage().container().style.cursor="pointer"},onMouseLeave:e=>{e.target.getStage().container().style.cursor=""},onTouchStart:e=>{e.cancelBubble=!0},onMouseDown:e=>{e.cancelBubble=!0},onClick:()=>{window.open("https://polotno.com","_blank","noopener")},onTap:()=>{window.open("https://polotno.com","_blank","noopener")}}),t.createElement(l,{name:"line-guides"}))),oe&&Re&&t.createElement(Re,{store:e,page:n,xPadding:J,yPadding:Q,layout:S}))});
|
|
1
|
+
var e=this&&this.__rest||function(e,t){var n={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++){t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]])}}return n};import t from"react";import{observer as n,useLocalObservable as i}from"mobx-react-lite";import{action as o,runInAction as r}from"mobx";import{Group as l,Image as a,Label as s,Layer as c,Line as d,Rect as m,Stage as u,Tag as g,Text as h,Transformer as p,KonvaRenderer as x}from"react-konva";import f from"use-image";import{useWorkspaceStyle as b}from"./workspace-style.js";import{ROLES as v}from"../model/store.js";import y from"konva";import E from"./element.js";import{DrawingLayer as w}from"./drawing-layer.js";import{ensureDragOrder as X,useSnap as Y}from"./use-transformer-snap.js";import{useImageLoader as k}from"./image-element.js";import{getCrop as S}from"../utils/crop.js";import{___ as A,____ as I,isCreditVisible as M}from"../utils/validate-key.js";import{getClientRect as O,getTotalClientRect as P}from"../utils/math.js";import{pxToUnitRounded as R,pxToUnitString as j}from"../utils/unit.js";import{flags as C}from"../utils/flags.js";import{useColor as D}from"./use-color.js";import{isGradient as B}from"../utils/gradient.js";import{Html as T}from"react-konva-utils";import{observerBatching as W}from"mobx-react-lite";const G=e=>x.batchedUpdates(e,null);W(e=>{x.isAlreadyRendering()?queueMicrotask(()=>G(e)):G(e)});const L=y.DD._drag;window.removeEventListener("mousemove",L),y.DD._drag=function(e){r(()=>{L.call(this,e)})},window.addEventListener("mousemove",y.DD._drag);const V={enabledAnchors:["top-left","top-center","top-right","middle-left","bottom-left","bottom-right","bottom-center","middle-right"],rotateEnabled:!0,rotationSnaps:[0,45,90,135,180,225,270,315],ignoreStroke:!0,flipEnabled:!1,keepRatio:!0},F={text:{enabledAnchors:["top-left","top-right","middle-left","bottom-left","bottom-right","middle-right"]},svg:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},gif:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},line:{enabledAnchors:[],borderEnabled:!1,rotateEnabled:!1},image:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},many:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},group:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},table:{keepRatio:!1,enabledAnchors:["top-left","top-center","top-right","middle-left","middle-right","bottom-left","bottom-center","bottom-right"]}};export function registerTransformerAttrs(e,t){F[e]=F[e]||t,Object.assign(F[e],t)}const U=e=>t.createElement(m,Object.assign({},e,{preventDefault:!1})),z=n=>{var{url:i}=n,o=e(n,["url"]);const[r,l]=f(i,"anonymous"),s=r?S(r,{width:o.width,height:o.height},"center-middle"):{};return k(l,i,"page background"),t.createElement(a,Object.assign({image:r},o,s))},Z=e=>{const n=D({a:{width:e.width,height:e.height},width:e.width,height:e.height},e.fill);return t.createElement(m,Object.assign({},e,n))},_=n=>{const{background:i,scale:o,borderColor:r,transparencyBackgroundColor:l}=n,a=e(n,["background","scale","borderColor","transparencyBackgroundColor"]),s=t.useMemo(()=>!!y.Util.colorToRGBA(i)||B(i),[i]),c=t.useMemo(()=>{if(B(i)){return!0}const e=y.Util.colorToRGBA(i);return!e||e.a<1},[i]),d=t.useMemo(()=>{if(!c||l){return null}const e=document.createElement("canvas"),t=30;e.width=60,e.height=60;const n=e.getContext("2d");return n&&(n.fillStyle="black",n.fillRect(t,0,t,t),n.fillRect(0,t,t,t)),e},[c,l]);return t.createElement(t.Fragment,null,c&&(l?t.createElement(m,Object.assign({fill:l},a,{hideInExport:!0})):t.createElement(m,Object.assign({fillPatternImage:d},a,{opacity:.1,hideInExport:!0}))),s?t.createElement(Z,Object.assign({fill:i},a)):t.createElement(z,Object.assign({url:i},a)))},H=n(({selection:e})=>{if(!e.visible){return null}const{selectionRectStyle:n}=b();return t.createElement(m,{name:"selection",x:Math.min(e.x1,e.x2),y:Math.min(e.y1,e.y2),width:Math.abs(e.x1-e.x2),height:Math.abs(e.y1-e.y2),fill:n.fill,stroke:n.stroke,strokeWidth:n.strokeWidth})});function J(e){let t=180*e/Math.PI;return t%=360,t>180?t-=360:t<-180&&(t+=360),Math.round(t)}const N=n(({x:e,y:n,width:i,height:o,rotation:r,anchor:l,store:a})=>{const{transformLabelStyle:c}=b();if(void 0===e||void 0===n||void 0===i||void 0===o||void 0===r||void 0===l){return null}const d=O({x:e,y:n,width:i,height:o,rotation:y.Util.radToDeg(r)}),m=(o/2+70)*Math.cos(r-Math.PI/2),u=(o/2+70)*Math.sin(r-Math.PI/2),p=R({unit:a.unit,dpi:a.dpi,px:i/a.scale,precious:"px"===a.unit?0:1})+" x "+R({unit:a.unit,dpi:a.dpi,px:o/a.scale,precious:"px"===a.unit?0:1})+("px"===a.unit?"":" "+a.unit);return t.createElement(t.Fragment,null,t.createElement(s,{x:(d.minX+d.maxX)/2+m,y:(d.minY+d.maxY)/2+u,offsetX:14,offsetY:14,visible:"rotater"===l},t.createElement(g,{cornerRadius:5,fill:c.fill}),t.createElement(h,{align:"center",verticalAlign:"middle",fill:c.textFill,padding:8,text:J(r).toString()+"°"})),t.createElement(s,{x:(d.minX+d.maxX)/2,y:d.maxY+20,visible:"rotater"!==l},t.createElement(g,{cornerRadius:5,fill:c.fill,pointerDirection:"up",pointerHeight:0,pointerWidth:0}),t.createElement(h,{align:"center",verticalAlign:"middle",fill:c.textFill,padding:8,text:p})))}),K=n(({elements:e,store:n})=>{const i=e.filter(e=>e.alwaysOnTop),o=e.filter(e=>!e.alwaysOnTop).concat(i);return t.createElement(t.Fragment,null,o.map(e=>t.createElement(E,{key:e.id,store:n,element:e,onClick:()=>{console.warn("Polotno warning: onClick callback is deprecated. Just stop using it. Polotno will do selection automatically.")}})))});export const useContextMenu=({store:e})=>{const[n,i]=t.useState(!1),[o,r]=t.useState({x:0,y:0}),l=t.useCallback(e=>{i(!0),r(e)},[]);return{open:l,close:t.useCallback(()=>{i(!1)},[]),props:{isOpen:n,offset:o,setIsOpen:i}}};let $=null;export const registerNextDomDrop=e=>{$=e};const Q=atob("UG9sb3RubyBmcmVlIGxpY2Vuc2UgbGltaXRhdGlvbiBleGNlZWRlZCAtIFBsZWFzZSB1cGdyYWRlIHlvdXIgYWNjb3VudC4="),q=atob("I2MwMzkyYg=="),ee=atob("djAuOS4y"),te=e=>t.createElement(t.Fragment,null,t.createElement(s,{fill:q,height:200},t.createElement(g,{fill:q}),t.createElement(h,Object.assign({},e,{fill:"white",text:Q,height:void 0,padding:10,fontSize:20})))),ne=atob("RlJFRSAgVFJJQUwgIExJQ0VOU0U="),ie=(atob("UG93ZXJlZCBieSBQb2xvdG5v"),atob("TElDRU5TRSAgS0VZICBJUyAgTUlTU0lORw==")),oe=atob("UGxlYXNlIGFjdGl2YXRlIHlvdXIgbGljZW5zZS4KTGljZW5zZSByZWxhdGVkIHF1ZXN0aW9uczoKcG9sb3Ruby5jb20vY29udGFjdA=="),re=e=>{const n=1===I(),i=n?ie:ne,o=n?230:195;return t.createElement(l,Object.assign({},e,{listening:!1}),t.createElement(m,{fill:q,width:o,height:24,cornerRadius:2}),t.createElement(h,{text:i,fill:"white",fontSize:13,fontFamily:"monospace",width:o,align:"center",y:5,listening:!1}),n&&t.createElement(h,{text:oe,fill:"rgba(0,0,0,0.6)",fontSize:14,y:30,listening:!1}))};export default n(({store:e,page:n,width:r,height:a,pageControlsEnabled:x,components:f,altCloneEnabled:E,groupClickBehavior:k="select-child",viewportSize:S,layout:R="vertical",tooltipSafeArea:D,transformerSafeArea:B})=>{const W=b(),G=W.transformerStyle,L=V,z=e.bleedVisible?n.bleed:0,Z=n.computedWidth+2*z,J=n.computedHeight+2*z,Q=(r-Z*e.scale)/2,q=(a-J*e.scale)/2,ne=t.useRef(null),ie=t.useRef(null),oe=t.useRef(null),le=null==x||x,ae=t.useRef(!1),[se,ce]=t.useState(null),[de,me]=t.useState({}),[ue,ge]=t.useState(0),he=useContextMenu({store:e}),pe=e.selectedElements.find(e=>e._cropModeEnabled),xe=e.selectedElements.find(e=>e.curveEnabled),fe=e.selectedShapes.filter(e=>!e.resizable).length>0,be=e.selectedShapes.filter(e=>!e.draggable).length>0,ve=e.selectedElements.filter(e=>!e.visible).length>0;t.useLayoutEffect(()=>{var t,n,i;if(!ne.current){return}const o=ne.current.getStage(),r=e.selectedShapes.map(e=>e._cropModeEnabled?null:o.findOne("#"+e.id)).filter(e=>!!e),l=1===e.selectedElements.length,a=l&&(null===(t=e.selectedElements[0])||void 0===t?void 0:t.type)||"many",s=F[a],c=Object.assign(Object.assign({},L),s||{});s&&("svg"!==a&&"image"!==a&&"gif"!==a||e.selectedElements[0].keepRatio||(c.enabledAnchors=L.enabledAnchors),"text"===a&&C.textVerticalResizeEnabled&&(c.enabledAnchors=null===(n=F.text.enabledAnchors)||void 0===n?void 0:n.concat(["bottom-center","top-center"])),"text"===a&&l&&e.selectedElements[0].curveEnabled&&(c.enabledAnchors=F.many.enabledAnchors)),ne.current.setAttrs(Object.assign(Object.assign({},c),G)),fe&&ne.current.enabledAnchors([]),be&&ne.current.rotateEnabled(!1),r.find(e=>null==e?void 0:e.isDragging())&&r.forEach(e=>{e.isDragging()||null==e||e.startDrag()}),ne.current.nodes(r),X(),null===(i=ne.current.getLayer())||void 0===i||i.batchDraw()},[e.selectedShapes,pe,fe,ve,be,xe,G]);const ye=()=>{var e,t;const n=ne.current;if(!n){return}if(!n.isTransforming()){return void me({})}if(!n.nodes().length||!n.isTransforming()){return}const i=n.__getNodeRect(),o=null==n?void 0:n.getActiveAnchor(),r=n.getStage();me({anchor:o,x:i.x-(null!==(e=null==r?void 0:r.x())&&void 0!==e?e:0),y:i.y-(null!==(t=null==r?void 0:r.y())&&void 0!==t?t:0),rotation:i.rotation,width:i.width,height:i.height})},Ee=t.useCallback(()=>{var e;if(null===(e=ne.current)||void 0===e?void 0:e.isTransforming()){return}const t=ne.current;if(!t||!t.nodes().length){return void ge(0)}const n=t.getClientRect();if(!t.getStage()){return}const i=function(e,t,n,i=0){const o=e.x+e.width/2,r=e.y+e.height/2,l=e.width/2,a=e.height/2,s=i*Math.PI/180,c=e=>{const t=e*Math.PI/180,i=(e%360+360)%360;let c;c=0===i||180===i?a:l;const d=Math.sin(t)*(c+n),m=-Math.cos(t)*(c+n),u=d*Math.cos(s)-m*Math.sin(s),g=d*Math.sin(s)+m*Math.cos(s);return{x:o+u,y:r+g}},d=e=>e.x>=t.left&&e.x<=t.right&&e.y>=t.top&&e.y<=t.bottom;if(d(c(0))){return 0}for(const m of[180,270,90]){if(d(c(m))){return m}}return 0}(n,{top:(null==B?void 0:B.top)||0,bottom:a-((null==B?void 0:B.bottom)||0),left:(null==B?void 0:B.left)||0,right:r-((null==B?void 0:B.right)||0)},G.rotateAnchorOffset,t.rotation());ge(i)},[B,r,a]);t.useEffect(()=>{var e;null===(e=ne.current)||void 0===e||e.update(),ye(),Ee()},[e.scale,Ee]),t.useEffect(()=>{Ee()},[e.selectedShapes,Ee]);const we=i(()=>({visible:!1,x1:0,y1:0,x2:0,y2:0})),Xe=t.useRef(!1),Ye=o(t=>{var n,i,o,r,l,a,s;if(e.role===v.VIEWER){return}Xe.current=!1;const c=t.target.findAncestor(".elements-container"),d=t.target.findAncestor("Transformer"),m=t.target.findAncestor(".page-abs-container");if(c||d||m){return}const u=null===(n=t.target.getStage())||void 0===n?void 0:n.getPointerPosition();u&&(u.x-=null!==(o=null===(i=t.target.getStage())||void 0===i?void 0:i.x())&&void 0!==o?o:0,u.y-=null!==(l=null===(r=t.target.getStage())||void 0===r?void 0:r.y())&&void 0!==l?l:0,we.visible=!0,we.x1=u.x,we.y1=u.y,we.x2=u.x,we.y2=u.y,(null!==(s=null===(a=t.target.getStage())||void 0===a?void 0:a.getPointersPositions().length)&&void 0!==s?s:0)>=2&&(we.visible=!1))});(({stageRef:e,containerRef:n,viewportSize:i})=>{t.useEffect(()=>{var t;const i=null===(t=n.current)||void 0===t?void 0:t.closest(".polotno-workspace-inner");function o(){var t;if(!e.current){return}const o=null===(t=n.current)||void 0===t?void 0:t.getBoundingClientRect(),r=null==i?void 0:i.getBoundingClientRect();if(!o||!r){return}const l=Math.max(0,r.left-o.left-100),a=Math.max(0,r.top-o.top-100);e.current.position({x:-l,y:-a}),e.current.container().style.transform=`translate(${l}px, ${a}px)`}return o(),null==i||i.addEventListener("scroll",o),()=>{null==i||i.removeEventListener("scroll",o)}},[i.width,i.height])})({stageRef:ie,containerRef:oe,viewportSize:S}),t.useEffect(()=>{const t=o(e=>{var t,n,i,o,r,l;if(!we.visible){return}null===(t=ie.current)||void 0===t||t.setPointersPositions(e);let a=null===(n=ie.current)||void 0===n?void 0:n.getPointerPosition();a?(a.x-=null!==(o=null===(i=ie.current)||void 0===i?void 0:i.x())&&void 0!==o?o:0,a.y-=null!==(l=null===(r=ie.current)||void 0===r?void 0:r.y())&&void 0!==l?l:0):a={x:we.x2,y:we.y2},we.x2=a.x,we.y2=a.y}),n=o(()=>{if(!we.visible){return}if(!ie.current){return}const t=ie.current.findOne(".selection"),n=t?t.getClientRect({skipStroke:!0}):{width:0,height:0,x:0,y:0};if(n.width&&n.height){const t=[];ie.current.find(".element").forEach(i=>{const o=i.getClientRect(),r=e.getElementById(i.id()),l=null==r?void 0:r.draggable,a=null==r?void 0:r.selectable;y.Util.haveIntersection(n,o)&&l&&a&&t.push(r.top.id)});const i=[...new Set(t)];Xe.current=!0,e.selectElements(i)}we.visible=!1});return window.addEventListener("mousemove",t),window.addEventListener("touchmove",t),window.addEventListener("mouseup",n,{capture:!0}),window.addEventListener("touchend",n,{capture:!0}),()=>{window.removeEventListener("mousemove",t),window.removeEventListener("touchmove",t),window.removeEventListener("mouseup",n),window.removeEventListener("touchend",n)}},[]);const ke=t.useCallback(t=>{if(!e.selectedElements[0]){return}if(t&&e.selectedElementsIds.includes(t)){return}const i=P(e.selectedShapes),o=t?e.getElementById(t):{x:0,y:0,width:n.computedWidth,height:n.computedHeight,rotation:0},r=O(o),l=[];i.minX>r.maxX&&l.push({distance:i.minX-r.maxX,box1:i,box2:r,points:[{x:i.minX,y:i.minY+i.height/2},{x:r.maxX,y:i.minY+i.height/2},{x:r.maxX,y:r.minY+r.height/2}]}),i.maxX<r.minX&&l.push({distance:r.minX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:i.minY+i.height/2},{x:r.minX,y:i.minY+i.height/2},{x:r.minX,y:r.minY+r.height/2}]}),i.minY>r.maxY&&l.push({box1:i,box2:r,distance:i.minY-r.maxY,points:[{x:i.minX+i.width/2,y:i.minY},{x:i.minX+i.width/2,y:r.maxY},{x:r.minX+r.width/2,y:r.maxY}]}),i.maxY<r.minY&&l.push({box1:i,box2:r,distance:r.minY-i.maxY,points:[{x:i.minX+i.width/2,y:i.maxY},{x:i.minX+i.width/2,y:r.minY},{x:r.minX+r.width/2,y:r.minY}]});const a=i.minX>=r.minX&&i.maxX<=r.maxX&&i.minY>=r.minY&&i.maxY<=r.maxY;if(a&&(l.push({distance:i.minX-r.minX,box1:i,box2:r,points:[{x:i.minX,y:i.minY+i.height/2},{x:r.minX,y:i.minY+i.height/2},{x:r.minX,y:r.minY+r.height/2}]}),l.push({distance:r.maxX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:i.minY+i.height/2},{x:r.maxX,y:i.minY+i.height/2},{x:r.maxX,y:r.minY+r.height/2}]}),l.push({box1:i,box2:r,distance:i.minY-r.minY,points:[{x:i.minX+i.width/2,y:i.minY},{x:i.minX+i.width/2,y:r.minY},{x:r.minX+r.width/2,y:r.minY}]}),l.push({box1:i,box2:r,distance:r.maxY-i.maxY,points:[{x:i.minX+i.width/2,y:i.maxY},{x:i.minX+i.width/2,y:r.maxY},{x:r.minX+r.width/2,y:r.maxY}]})),0===l.length&&!a){const e=i.minX<r.maxX&&i.maxX>r.minX,t=i.minY<r.maxY&&i.maxY>r.minY;if(e&&t){const e=(Math.max(i.minY,r.minY)+Math.min(i.maxY,r.maxY))/2,t=(Math.max(i.minX,r.minX)+Math.min(i.maxX,r.maxX))/2;i.minX<r.minX?l.push({distance:r.minX-i.minX,box1:i,box2:r,points:[{x:i.minX,y:e},{x:r.minX,y:e},{x:r.minX,y:e}]}):l.push({distance:i.minX-r.minX,box1:i,box2:r,points:[{x:i.minX,y:e},{x:r.minX,y:e},{x:r.minX,y:e}]}),i.maxX>r.maxX?l.push({distance:i.maxX-r.maxX,box1:i,box2:r,points:[{x:r.maxX,y:e},{x:i.maxX,y:e},{x:r.maxX,y:e}]}):l.push({distance:r.maxX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:e},{x:r.maxX,y:e},{x:r.maxX,y:e}]}),i.minY<r.minY?l.push({box1:i,box2:r,distance:r.minY-i.minY,points:[{x:t,y:i.minY},{x:t,y:r.minY},{x:t,y:r.minY}]}):l.push({box1:i,box2:r,distance:i.minY-r.minY,points:[{x:t,y:i.minY},{x:t,y:r.minY},{x:t,y:r.minY}]}),i.maxY>r.maxY?l.push({box1:i,box2:r,distance:i.maxY-r.maxY,points:[{x:t,y:r.maxY},{x:t,y:i.maxY},{x:t,y:r.maxY}]}):l.push({box1:i,box2:r,distance:r.maxY-i.maxY,points:[{x:t,y:i.maxY},{x:t,y:r.maxY},{x:t,y:r.maxY}]})}}JSON.stringify(se)!==JSON.stringify(l)&&ce(l)},[e,n]);t.useEffect(()=>{e.selectedElements[0]&&e.distanceGuidesVisible?ke():se&&ce(null)},[e.distanceGuidesVisible,ke,e.selectedShapes.map(e=>`${e.x},${e.y},${e.width},${e.height},${e.rotation}`).join("|")]);const Se=t.useRef(!1);t.useEffect(()=>{var e;let t;const n=null===(e=oe.current)||void 0===e?void 0:e.closest(".polotno-workspace-inner"),i=()=>{Se.current=!0,clearTimeout(t),t=setTimeout(()=>{Se.current=!1},300)};return null==n||n.addEventListener("scroll",i),()=>{clearTimeout(t),null==n||n.removeEventListener("scroll",i)}},[]),t.useEffect(()=>{const e=ie.current;if(!e){return}const t=e.container(),n=e=>{var t,n;e.touches.length>=2&&((null===(t=ne.current)||void 0===t?void 0:t.isDragging())&&ne.current.stopDrag(),null===(n=ne.current)||void 0===n||n.nodes().forEach(e=>{e.isDragging()&&e.stopDrag()}))};return t.addEventListener("touchstart",n,{passive:!0}),t.addEventListener("touchmove",n,{passive:!0}),()=>{t.removeEventListener("touchstart",n),t.removeEventListener("touchmove",n)}},[]);const Ae=t=>{if(e.role===v.VIEWER){return}if(e.activePage!==n&&n.select(),Se.current){return}if(Xe.current){return}const i=t.evt.shiftKey,o=t.evt.ctrlKey||t.evt.metaKey,r=i||o,l=t.target.findAncestor(".elements-container"),a=t.target.findAncestor(".page-abs-container"),s=t.target.findAncestor("Transformer"),c=t.target.findAncestor(".page-container",!0);if(!(r||l||s||a||c||we.visible)){return e.selectElements([]),void e.selectPages([])}if(o&&!i){const t=ie.current,n=null==t?void 0:t.getPointerPosition();if(!t||!n){return}const i=t.getAllIntersections(n),o=new Set,r=[];for(const a of[...i].reverse()){const t=a.findAncestor(".element",!0);if(!t){continue}const n=e.getElementById(t.id()),i=null==n?void 0:n.top;i&&(o.has(i.id)||(o.add(i.id),r.push(i.id)))}if(0===r.length){return}let l;if(1===e.selectedElementsIds.length){const t=e.selectedElementsIds[0],n=r.indexOf(t);l=-1===n?r[0]:r[(n+1)%r.length]}else{l=r[0]}return e.selectElements([l]),void e.selectPages([])}const d=t.target.findAncestor(".element-container",!0),m=(null==d?void 0:d.findOne(".element"))||t.target.findAncestor(".element",!0),u=e.getElementById(null==m?void 0:m.id()),g=null==u?void 0:u.top;let h;if("select-group"===k){h=null==g?void 0:g.id}else if(g){const t=e.selectedElements.some(e=>{var t;return(null===(t=e.top)||void 0===t?void 0:t.id)===g.id});h=t?null==u?void 0:u.id:null==g?void 0:g.id}else{h=void 0}const p=null==u?void 0:u.id;if(p&&e.selectedElementsIds.indexOf(p)>=0&&!i){return}const x=!!h&&e.selectedElementsIds.indexOf(h)>=0,f=t.target.findAncestor(".page-container",!0);if(h&&i&&!x){const t=e.selectedElementsIds.concat([h]),n=new Set(t),i=t.filter(t=>{const i=e.getElementById(t);if(!i){return!1}for(let e=i.parent;e;e=null==e?void 0:e.parent){if(n.has(e.id)){return!1}}return!0});e.selectElements(i),e.selectPages([])}else{h&&i&&x?e.selectElements(e.selectedElementsIds.filter(e=>e!==h)):!h||i||x?h&&!i&&x||(f?(i||e.selectElements([]),e.selectPages([n.id])):e.selectPages([])):(e.selectElements([h]),e.selectPages([]))}};Y(ne,e);const Ie=e.activePage===n,Me=e._selectedPagesIds.includes(n.id),Oe=null==f?void 0:f.PageControls,Pe=null==f?void 0:f.Tooltip,Re=null==f?void 0:f.ContextMenu,je=1/e.scale,Ce=0/e.scale;return t.createElement("div",{ref:oe,onDragOver:e=>e.preventDefault(),onDrop:t=>{if(t.preventDefault(),e.role===v.VIEWER){return}if(!ie.current){return}ie.current.setPointersPositions(t);const i=ie.current.findOne(".elements-container"),o=null==i?void 0:i.getRelativePointerPosition(),r=ie.current.getPointerPosition(),l=ie.current.getAllIntersections(r).map(e=>e.findAncestor(".element",!0)).filter(Boolean),a=[...new Set(l.reverse())].map(t=>e.getElementById(t.id())).filter(e=>!!e),s=a[0];$&&o&&($(o,s,{elements:a,page:n}),$=null)},style:{position:"relative",width:r+"px",height:a+"px",overflow:"hidden",flexShrink:0},className:"polotno-page-container"+(Ie?" active-page":"")},t.createElement(u,{ref:ie,width:Math.min(r,S.width+200),height:Math.min(S.height+200,a),onClick:Ae,onTap:Ae,onContextMenu:t=>{if(t.evt.preventDefault(),e.role===v.VIEWER){return}const n=t.target.findAncestor(".element",!0),i=e.getElementById(null==n?void 0:n.id()),o=null==i?void 0:i.top,r=null==o?void 0:o.id;r?e.selectedElementsIds.indexOf(r)>=0||e.selectElements([r]):e.selectElements([]),he.open({x:t.evt.clientX,y:t.evt.clientY})},onMouseDown:Ye,onMouseMove:t=>{if(!e.distanceGuidesVisible&&!t.evt.altKey){return void(se&&ce(null))}const n=t.target.findAncestor(".element",!0),i=null==n?void 0:n.id();ke(i)},onDragStart:t=>{var n;const i=t.target.getStage();if(i&&i.getPointersPositions().length>=2){return void t.target.stopDrag()}const o=t.target.findAncestor(".element",!0);if(o){const i=e.getElementById(null==o?void 0:o.id()),r=null==i?void 0:i.top,l=null==r?void 0:r.id;!(i&&e.selectedElementsIds.indexOf(i.id)>=0||l&&e.selectedElementsIds.indexOf(l)>=0)&&l&&(e.selectElements([l]),t.target.stopDrag(),t.target.startDrag(t),null===(n=ne.current)||void 0===n||n.startDrag(t))}se&&ce(null)},pageId:n.id,style:{position:"absolute",overflow:"hidden",top:0,left:0}},t.createElement(c,null,t.createElement(U,{width:r,height:a,fill:W.workspaceBackgroundColor}),t.createElement(l,{x:Q,y:q,scaleX:e.scale,scaleY:e.scale,name:"page-container"},t.createElement(l,{name:"page-container-2"},t.createElement(l,{name:"page-background-group",x:z,y:z},t.createElement(_,{x:-n.bleed,y:-n.bleed,width:n.computedWidth+2*n.bleed,height:n.computedHeight+2*n.bleed,background:n.background,transparencyBackgroundColor:W.transparencyBackgroundColor,name:"page-background",preventDefault:!1,scale:e.scale})),t.createElement(l,{x:z,y:z,name:"elements-container",listening:!e.isPlaying&&e.role!==v.VIEWER},t.createElement(m,{name:"elements-area",width:n.computedWidth,height:n.computedHeight,listening:!1}),t.createElement(K,{elements:n.children,store:e})),t.createElement(m,{stroke:W.bleedColor,name:"bleed",strokeWidth:n.bleed,x:n.bleed/2,y:n.bleed/2,width:n.computedWidth+n.bleed,height:n.computedHeight+n.bleed,listening:!1,visible:n.bleed>0&&e.bleedVisible,hideInExport:!0}),A()===ee&&t.createElement(te,{name:"hit-detection",x:-je/2-Ce,y:-je/2-Ce,width:Z+je+2*Ce,height:J+je+2*Ce}))),t.createElement(d,{name:"workspace-background",points:[0,0,r,0,r,a,0,a,0,0,Q,q,Q,a-q,r-Q,a-q,r-Q,q,Q,q],listening:!1,closed:!0,fill:W.workspaceBackgroundColor}),t.createElement(l,{x:Q,y:q,scaleX:e.scale,scaleY:e.scale},t.createElement(m,{name:"page-highlight",hideInExport:!0,x:-je/2-Ce,y:-je/2-Ce,width:Z+je+2*Ce,height:J+je+2*Ce,stroke:Me?W.activePageBorderColor:W.pageBorderColor,strokeWidth:2,listening:!1,strokeScaleEnabled:!1})),t.createElement(l,{x:Q+z*e.scale,y:q+z*e.scale,scaleX:e.scale,scaleY:e.scale,name:"page-abs-container"},t.createElement(p,{ref:ne,rotateAnchorAngle:ue,onDragStart:t=>{var i;const o=t.target.getStage();o&&o.getPointersPositions().length>=2?t.target.stopDrag():((null===(i=t.evt)||void 0===i?void 0:i.altKey)&&E&&e.selectedElements.forEach(e=>{const t=e.clone({},{skipSelect:!0}),i=n.children.indexOf(e);n.setElementZIndex(t.id,i)}),ae.current=!0,e.history.startTransaction())},onDragEnd:()=>{ae.current&&(e.history.endTransaction(),ae.current=!1),Ee()},onTransformStart:()=>{e.history.startTransaction(),ce(null)},boundBoxFunc:(t,n)=>{var i;const o=Math.abs(n.width)<1||Math.abs(n.height)<1,r=Math.abs(t.width)<1||Math.abs(t.height)<1;if(o&&!r){return t}const l=e.selectedElements;if(1===l.length&&"table"===(null===(i=l[0])||void 0===i?void 0:i.type)){const e=l[0],i=Math.abs(t.width),o=Math.abs(t.height);if(i>0&&o>0){const r=Math.abs(n.width)/i,l=Math.abs(n.height)/o,a=e.width*r,s=e.height*l,c=Object.assign({},n);return a<e.minWidth&&(c.width=t.width,c.x=t.x),s<e.minHeight&&(c.height=t.height,c.y=t.y),c}}return n},onTransform:e=>{const t=ne.current.nodes(),n=t[t.length-1];e.target===n&&setTimeout(()=>{ye()},0)},onTransformEnd:t=>{me({}),e.history.endTransaction(),Ee()},visible:!e.isPlaying}),se&&se.map(({points:n,distance:i,box1:o,box2:r},a)=>t.createElement(l,{name:"distances-container",hideInExport:!0,key:a,listening:!1},t.createElement(m,Object.assign({},o,{stroke:W.distanceGuideStyle.stroke,strokeWidth:1,strokeScaleEnabled:!1})),t.createElement(m,Object.assign({},r,{stroke:W.distanceGuideStyle.stroke,strokeWidth:1,strokeScaleEnabled:!1})),t.createElement(d,{points:[n[0].x,n[0].y,n[1].x,n[1].y],stroke:W.distanceGuideStyle.stroke,strokeWidth:1,strokeScaleEnabled:!1}),t.createElement(d,{points:[n[1].x,n[1].y,n[2].x,n[2].y],stroke:W.distanceGuideStyle.stroke,strokeWidth:1,strokeScaleEnabled:!1}),t.createElement(s,{x:(n[0].x+n[1].x)/2,y:(n[0].y+n[1].y)/2,offsetY:-10,scaleX:1/e.scale,scaleY:1/e.scale},t.createElement(g,{cornerRadius:5,fill:W.distanceGuideStyle.labelFill,pointerDirection:"down"}),t.createElement(h,{align:"center",verticalAlign:"middle",fill:W.distanceGuideStyle.labelTextFill,padding:5,text:j({unit:e.unit,dpi:e.dpi,px:i})})))),n._rendering&&t.createElement(l,null,t.createElement(m,{width:Z,height:J,fill:"rgba(255,255,255,0.9)"}),t.createElement(h,{text:"Rendering...",fontSize:60,width:Z,height:J,align:"center",verticalAlign:"middle"})),Pe&&t.createElement(Pe,{components:f,store:e,page:n,stageRef:ie,tooltipSafeArea:D}),Re&&t.createElement(T,null,t.createElement(Re,Object.assign({components:f,store:e},he.props)))),t.createElement(w,{store:e,page:n,width:r,height:a,scale:e.scale,xPadding:Q,yPadding:q,bleed:z}),t.createElement(N,Object.assign({},de,{store:e})),t.createElement(H,{selection:we}),I()>0&&t.createElement(l,{hideInExport:!0},t.createElement(re,{name:"cache-bounds",x:r-(1===I()?250:210),y:a-(1===I()?95:45)}),t.createElement(re,{name:"cache-bounds-t",x:10,y:10})),M()&&t.createElement(h,{text:"Powered by polotno.com",fontSize:14,fill:"rgba(0,0,0,0.6)",x:r-170,y:a-18,onMouseEnter:e=>{e.target.getStage().container().style.cursor="pointer"},onMouseLeave:e=>{e.target.getStage().container().style.cursor=""},onTouchStart:e=>{e.cancelBubble=!0},onMouseDown:e=>{e.cancelBubble=!0},onClick:()=>{window.open("https://polotno.com","_blank","noopener")},onTap:()=>{window.open("https://polotno.com","_blank","noopener")}}),t.createElement(l,{name:"line-guides"}))),le&&Oe&&t.createElement(Oe,{store:e,page:n,xPadding:Q,yPadding:q,layout:R}))});
|
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{ROLES as m}from"../model/store.js";import{incrementLoader as p}from"../utils/loader.js";import{isFontLoaded as x}from"../utils/fonts.js";import{flags as w}from"../utils/flags.js";import{removeTags as v}from"../utils/text.js";import{getDir as S,getCurvePath as y,resolveLineHeight as E}from"../utils/text-html.js";import{applyFilter as b}from"./apply-filters.js";import{useFadeIn as z}from"./use-fadein.js";import{isTouchDevice as O}from"../utils/screen.js";import{isAlive as k,getParent as A}from"mobx-state-tree";import{getLimitedFontSize as F}from"./text-element/max-font-size.js";import{getOptimalCaretColor as R}from"./text-element/caret-color.js";let M;function j(){return M||(M=document.getElementById("polotno-text-style"),M||(M=document.createElement("style"),M.id="polotno-text-style",document.head.appendChild(M)),M)}s._fixTextRendering=!0;const C={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};export{getDir}from"../utils/text-html.js";const L=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(C),s=e.current;t.useLayoutEffect(()=>{if(!s){return}const t={};t.width=s.width()-2*s.padding()+"px",t.height=s.height()-2*s.padding()+s.fontSize()*s.lineHeight()+"px",t.fontSize=s.fontSize()+"px",t.lineHeight=s.lineHeight()+.01,t.fontFamily=s.fontFamily(),t.textAlign=s.align(),t.color=s.fill(),t.fontWeight=n.fontWeight,t.fontStyle=n.fontStyle,t.letterSpacing=n.letterSpacing+"em",t.opacity=Math.max(n.a.opacity,.2),t.textTransform=n.textTransform,t.caretColor=R(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=j();o.innerHTML="",o.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(a)&&l(t)});const c=t.useRef(null);if(t.useLayoutEffect(()=>{var t;const e=c.current;if(!e){return}null===(t=c.current)||void 0===t||t.focus({preventScroll:!0});const n=i||e.value.length;e.selectionStart=e.selectionEnd=n,r&&(null==e||e.select(),document.execCommand("selectAll",!1,void 0))},[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=c.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]),!s){return null}let d=0;const u=s.textArr.length*s.lineHeight()*s.fontSize();"middle"===n.verticalAlign&&(d=(n.a.height-u)/2),"bottom"===n.verticalAlign&&(d=n.a.height-u);const f=v(n.text);return t.createElement("textarea",{className:"polotno-input",ref:c,dir:S(f),style:Object.assign(Object.assign(Object.assign({},C),a),{paddingTop:d+"px"}),value:f,onChange:t=>{const e=F({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),T=e=>t.createElement(a,null,t.createElement(L,Object.assign({},e)));export const useFontLoader=(e,n,o,r,i)=>{const[a,l]=t.useReducer(t=>t+1,0),s=t.useRef(x(n,o,r)),c=t.useRef(null);return t.useLayoutEffect(()=>{if(s.current=x(n,o,r),s.current){return}let t=!0;return(async()=>{s.current=!1,l();const a=p(`text ${n}`);await e.loadFont(n,o,r,i),t?(c.current=a,s.current=!0,l()):a()})(),()=>{c.current&&(c.current(),c.current=null),t=!1}},[n,o,r]),t.useEffect(()=>{s.current&&setTimeout(()=>{c.current&&(c.current(),c.current=null)})},[s.current]),[s.current]};export const getLineHeight=({fontLoaded:e,fontFamily:n,fontSize:o,lineHeight:r})=>t.useMemo(()=>E({fontFamily:n,fontSize:o,lineHeight:r}),[e,n,o,r]);export function usePrevious(e){const n=t.useRef(e),o=t.useRef(e);return t.useMemo(()=>{o.current=n.current,n.current=e},[e]),o.current}function H(t,e,n=!1){const o=t.fontSize(),r=t.height(),i=v(e.text);let a=e.a.fontSize;t.height(void 0);const l=Math.round(2*e.a.fontSize)-1;for(let s=1;s<l;s++){const o=e.a.height&&t.height()>e.a.height;let r=i.split("\n").join(" ").split(/[\s-]+/).reduce((t,e)=>(e=e.toLowerCase(),/[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFFEF\u4E00-\u9FAF\uAC00-\uD7AF]/.test(e)?t.concat(e.split("")):t.concat(e)),[]),l=t.textArr.map(t=>t.text.toLowerCase()).join(";");const s=r.find(t=>!l.includes(t)||(l=l.replace(t,""),!1));if(!(o||s&&!n)){break}a-=.5,t.fontSize(a)}return t.fontSize(o),t.height(r),a}export{getCurvePath}from"../utils/text-html.js";export const TextElement=e(({element:e,store:a})=>{const{textOverflowIndicatorStyle:s}=g(),x=t.useRef(null),E=t.useRef(null),F=t.useRef(null),R=t.useRef([]),[,M]=t.useReducer(t=>t+1,0),{editorEnabled:j,selectAll:C}=(e=>{const[n,o]=t.useState(!1),r=t.useRef(!1);return t.useEffect(()=>{var t=!0;return setTimeout(()=>{t&&(e._editModeEnabled&&(r.current=!0),o(!0),setTimeout(()=>{r.current=!1},50))},50),()=>{t=!1}},[]),{editorEnabled:n&&e._editModeEnabled,selectAll:r.current}})(e),[L,W]=t.useState(!1),[X,Y]=t.useState(!1),P=t.useRef(e.a.height),B=e.isSelected,D=usePrevious(B),{textVerticalResizeEnabled:$}=w,N=w.autoDeleteEmptyText,I=usePrevious(e.fontFamily),[J,_]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=x.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(J)&&_(n)}),t.useEffect(()=>{if(e.a.width||"tablecell"===e.type){return}const t=x.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{D&&!B&&N&&""===e.text&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[N,e.placeholder,e.removable,e.text,B,D]);const V=()=>{if(e.curveEnabled){const t=x.current;null==t||t.clearCache(),null==t||t.setAttrs({filters:[]});const n=E.current;n&&b(n,e)}else{const t=x.current;t&&b(t,e)}};t.useLayoutEffect(()=>{if(!X){return l(()=>{V()})}}),t.useEffect(()=>{const t=R.current;t.length>0&&(R.current=[],t.forEach(t=>t()))});let q=v(e.text);"uppercase"===e.textTransform&&(q=q.toUpperCase());const[U]=useFontLoader(a,e.fontFamily,e.fontStyle,e.fontWeight,e.text||e.placeholder),Z=()=>{if(e.curveEnabled){const t=E.current;return t.getSelfRect().height||t.fontSize()}const t=x.current.clone({height:void 0}),n=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),n};t.useLayoutEffect(()=>{if(!U){return}if("tablecell"===e.type){const{textOverflow:t}=w;if("resize"===t){const t=Z(),n=k(e)?A(e,2):null;(null==n?void 0:n.setCellContentHeight)&&n.setCellContentHeight(e.id,t)}else if("change-font-size"===t){const t=x.current;if(t){const n=H(t,e,w.textSplitAllowed);n!==e.fontSize&&a.history.ignore(()=>{e.set({fontSize:n})})}}return}const{textOverflow:t,textSplitAllowed:n}=w,o=(t,n,o,r)=>{const i=p(`text ${e.id}`),l=()=>{a.history.ignore(t,n,o).then(()=>{R.current.push(i),M()})};r?queueMicrotask(l):l()};if(!e.height){const t=Z();return void o(()=>{e.height||e.set({height:t})},void 0,void 0,!0)}if(!a.isPlaying){if("change-font-size"!==t||L){if("resize"===t){const t=Z();$&&e.height<t&&!L&&o(()=>{var n;k(e)&&e.set({height:t}),null===(n=x.current)||void 0===n||n.height(t)},!1,!0),$||e.height===t||L||o(()=>{var n;k(e)&&e.set({height:t}),null===(n=x.current)||void 0===n||n.height(t)},!1,!0)}}else{const t=x.current,r=e.curveEnabled?e.fontSize:H(t,e,n);if(r!==e.fontSize){return void o(()=>{e.set({fontSize:r})},!1,!0)}const i=Z();e.height===i||$||o(()=>{e.set({height:i})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(U&&e.curveEnabled){const n=null===(t=E.current)||void 0===t?void 0:t.getSelfRect().width;if(n){const t=n-e.a.width,o=e.a.rotation*Math.PI/180,r=-t/2*Math.cos(o),i=-t/2*Math.sin(o);e.set({width:n,x:e.a.x+r,y:e.a.y+i})}}},[U,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useLayoutEffect(()=>{const t=x.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),V())},[U]);const G=t.useRef(null),K=t.useRef(0),Q=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(K.current=function(t){var e;const n=t.target,o=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var n=t.getStage().getPointerPosition();return e.point(n)}(n),r=n.textArr,i=Math.floor(o.y/(n.fontSize()*n.lineHeight())),a=r.slice(0,i).reduce((t,e)=>t+e.text.length,i),l=null!==(e=r[i])&&void 0!==e?e:r[0];let s=0;return"right"===n.align()?s=n.width()-l.width:"center"===n.align()&&(s=n.width()/2-l.width/2),a+Math.round((o.x-s)/l.width*l.text.length)}(t),e.toggleEditMode())},tt=!q&&e.placeholder?.6:e.a.opacity;z(x,tt);const et=getLineHeight({fontLoaded:U,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),nt=e.selectable||a.role===m.ADMIN,ot=h(e),rt=h(e,e.stroke,"stroke"),it=t.useMemo(()=>e.backgroundEnabled?e.curveEnabled?function({width:t,height:e,padding:n=0,cornerRadius:o=0}){const r=-n,i=-n,a=t+n,l=e+n,s=c(`M ${r} ${i} L ${a} ${i} L ${a} ${l} L ${r} ${l} Z`);return d(s,o).path}({width:e.a.width,height:e.a.height,cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*et*.5),padding:e.backgroundPadding*(e.a.fontSize*et*.5)}):function({lines:t,lineHeight:e,width:n,align:o="left",padding:r=0,cornerRadius:i=0}){const a=f({lines:t,lineHeight:e,width:n,align:o});return u({rects:a,padding:r,cornerRadius:i})}({lines:JSON.parse(JSON.stringify(J)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*et*.5),lineHeight:et*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*et*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.curveEnabled,e.backgroundCornerRadius,e.a.fontSize,e.a.height,et,e.backgroundPadding,e.a.width,e.align,J]),at=O();let lt=0;e.curveEnabled||("middle"===e.verticalAlign?lt=(e.a.height-J.length*et*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(lt=e.a.height-J.length*et*e.a.fontSize));const st=e.curveEnabled?y(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",ct=U?'"'+e.fontFamily+'"':I===e.fontFamily?"Arial":'"'+I+'"',dt=S(q);return t.createElement(t.Fragment,null,t.createElement(o,{ref:F,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*tt,data:it,fill:e.backgroundColor,offsetY:-lt}),t.createElement(o,{data:st,stroke:s.stroke,strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:E,visible:e.curveEnabled,data:st,text:q||e.placeholder,listening:!1,align:"center",textBaseline:"middle",direction:dt},ot,rt,{strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${I}"`,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration.trim(),letterSpacing:e.letterSpacing*e.a.fontSize,x:e.a.x,y:e.a.y,rotation:e.a.rotation,opacity:e._editModeEnabled?.3:tt,hideInExport:!e.showInExport,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity})),t.createElement(r,Object.assign({ref:x,id:e.selectable?e.id:void 0,name:e.selectable?"element":"",hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled,x:e.a.x,y:e.a.y,rotation:e.a.rotation,width:e.a.width,height:e.a.height,text:q||e.placeholder,direction:dt},ot,rt,{lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:ct,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:at?e.draggable&&B:e.draggable,preventDefault:!at||B,opacity:e.curveEnabled?0:tt,visible:!e._editModeEnabled,ellipsis:"ellipsis"===w.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:et,letterSpacing:e.letterSpacing*e.a.fontSize,listening:!!e.selectable&&nt,onDragStart:()=>{Y(!0)},onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{Y(!1),e.set({x:t.target.x(),y:t.target.y()})},onClick:Q,onTap:Q,onTransformStart:()=>{W(!0),P.current=x.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=F.current)||void 0===n||n.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(o=i.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),n=i.width()*t,o=e.a.fontSize;let r=n;n<o&&(r=o,G.current&&i.position(G.current)),i.width(r),i.scaleX(1),i.scaleY(1);let a=Z();if("ellipsis"===w.textOverflow){a=P.current}else{const t=Math.max(a,P.current);i.height(t),e.set({height:i.height()})}const l=w.textVerticalResizeEnabled?Math.max(a,P.current):Z();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),V()}if("top-center"===a||"bottom-center"===a){let n="resize"===w.textOverflow?Z():et*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}G.current=t.target.position();const l=t.target.scaleX();null===(r=F.current)||void 0===r||r.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.a.fontSize*l,width:t.target.width()*l,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*l,shadowBlur:e.shadowBlur*l,shadowOffsetX:e.shadowOffsetX*l,shadowOffsetY:e.shadowOffsetY*l,strokeWidth:e.strokeWidth*l})},onTransformEnd:t=>{var n;const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:Math.round(e.a.fontSize*o),width:Math.ceil(t.target.width()*o),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*o,shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o}),null===(n=F.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),W(!1)}})),j&&e.contentEditable&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement(T,{textNodeRef:x,element:e,selectAll:C,cursorPosition:K.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
|
|
1
|
+
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})))))});
|
|
@@ -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;
|