polotno 4.2.1 → 4.3.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/blueprint/pages-timeline/page-preview.js +2 -2
- package/blueprint/toolbar/html-toolbar.js +3 -3
- package/canvas/apply-filters.d.ts +11 -0
- package/canvas/apply-filters.js +1 -1
- package/canvas/audio.js +1 -1
- package/canvas/element.js +1 -1
- package/canvas/gif-element.js +1 -1
- package/canvas/hotkeys.d.ts +8 -0
- package/canvas/hotkeys.js +1 -1
- package/canvas/html-element.js +1 -1
- package/canvas/image-element.js +1 -1
- package/canvas/render-tag-element.js +1 -1
- package/canvas/rich-editor.js +2 -2
- package/canvas/table-element.js +1 -1
- package/canvas/text-element/fit-font-size.js +1 -1
- package/canvas/text-element.js +1 -1
- package/canvas/tooltip.js +1 -1
- package/canvas/use-filtered-source.d.ts +2 -0
- package/canvas/use-filtered-source.js +1 -0
- package/canvas/use-mediabunny-video.js +1 -1
- package/canvas/video-element.d.ts +1 -1
- package/canvas/video-element.js +1 -1
- package/canvas/workspace-canvas.d.ts +2 -1
- package/canvas/workspace-canvas.js +1 -1
- package/model/group-model.d.ts +1 -0
- package/model/group-model.js +1 -1
- package/model/page-model.d.ts +1 -0
- package/model/store.d.ts +9 -0
- package/model/store.js +1 -1
- package/model/text-model.d.ts +1 -0
- package/model/text-model.js +1 -1
- package/package.json +3 -3
- package/pages-timeline/page-preview.js +1 -1
- package/polotno.bundle.js +127 -126
- package/side-panel/effects-panel.js +1 -1
- package/side-panel/upload-panel.d.ts +1 -3
- package/side-panel/upload-panel.js +1 -1
- package/toolbar/html-toolbar.js +3 -3
- package/utils/base64.d.ts +2 -0
- package/utils/base64.js +1 -0
- package/utils/clipboard.d.ts +361 -0
- package/utils/clipboard.js +1 -1
- package/utils/errors.d.ts +7 -0
- package/utils/errors.js +1 -0
- package/utils/file.d.ts +6 -0
- package/utils/file.js +1 -1
- package/utils/fonts.js +1 -1
- package/utils/image-dpi.js +1 -1
- package/utils/insert-file.d.ts +23 -0
- package/utils/insert-file.js +1 -0
- package/utils/l10n.d.ts +4 -0
- package/utils/l10n.js +1 -1
- package/utils/loader.d.ts +3 -2
- package/utils/loader.js +1 -1
- package/utils/mobx.d.ts +4 -0
- package/utils/mobx.js +1 -0
- package/utils/text-html.d.ts +1 -0
- package/utils/text-html.js +1 -1
- package/utils/text-types.d.ts +2 -0
- package/utils/text-types.js +1 -1
- package/utils/to-html.js +1 -1
- package/utils/to-svg.js +1 -1
- package/utils/validate-key.js +1 -1
- package/utils/video.js +1 -1
package/canvas/rich-editor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var t=this&&this.__rest||function(t,e){var o={};for(var n in t){Object.prototype.hasOwnProperty.call(t,n)&&e.indexOf(n)<0&&(o[n]=t[n])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(n=Object.getOwnPropertySymbols(t);i<n.length;i++){e.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(t,n[i])&&(o[n[i]]=t[n[i]])}}return o};import{jsx as e}from"react/jsx-runtime";import o from"react";import n from"quill";import*as i from"mobx";import{nodeReaction as r}from"../utils/mobx.js";import{isAlive as l}from"mobx-state-tree";import s from"konva";import{getQuillEditorHtml as a,getDir as d}from"../utils/text-html.js";import{normalizeRichTextHtml as c,isQuillFormatMixed as u,isBoldWeight as f}from"../utils/rich-text-html.js";import{resetStyleContent as p}from"../utils/reset-style.js";import{removeTags as h}from"../utils/text.js";import{isGradient as m,parseColor as g}from"../utils/gradient.js";import{getOptimalCaretColor as b}from"./text-element/caret-color.js";import{registerQuillUnrestrictedFontFormats as v}from"./quill-font-formats.js";import{ALL_QUILL_MIXED_KEYS as y,setActiveTextEditor as x,updateActiveTextFormat as w,clearActiveTextEditor as S}from"../utils/text-format-state.js";import q from"../utils/styled.js";export function applyOpacityToColor(t,e){if(1===e){return t}const o=s.Util.colorToRGBA(t);return o?`rgba(${o.r}, ${o.g}, ${o.b}, ${o.a*e})`:t}export const quillRef=i.observable({enabled:!1,currentFormat:{},lastSelection:null,pendingToolbarInteraction:!1,editor:i.observable.object({instance:null},{},{deep:!1})});const k=y;export function syncQuillFormatState(t,e){const o=e?t.getFormat(e):{},n=function(t,e){const o={};if(!e||e.length<=0){return o}const n=t.getContents(e.index,e.length);for(const i of k){u(n,i)&&(o[i]=!0)}return o}(t,e);i.runInAction(()=>{quillRef.currentFormat=o}),w(o,n,e)}const E="polotno-saved-selection";function T(){const t=window.getSelection();if(!t||0===t.rangeCount||t.isCollapsed){return}if("undefined"==typeof Highlight||!CSS.highlights){return}const e=t.getRangeAt(0).cloneRange();CSS.highlights.set(E,new Highlight(e)),O()}function C(){"undefined"!=typeof CSS&&CSS.highlights&&CSS.highlights.delete(E)}function O(){setTimeout(()=>{"undefined"!=typeof CSS&&CSS.highlights&&CSS.highlights.has(E)&&(document.querySelector(".polotno-portal")||N(document.activeElement)?O():C())},300)}if("undefined"!=typeof document&&"undefined"!=typeof CSS&&CSS.highlights&&!document.querySelector("[data-polotno-highlight]")){const M=document.createElement("style");M.setAttribute("data-polotno-highlight",""),M.textContent=`::highlight(${E}) { background-color: Highlight; }`,document.head.appendChild(M)}export const RichTextContainer=q("div",o.forwardRef)`
|
|
2
2
|
.ql-editor {
|
|
3
3
|
outline: none;
|
|
4
4
|
/* anchor for the absolutely-positioned ::before placeholder below */
|
|
@@ -129,4 +129,4 @@ var e=this&&this.__rest||function(e,t){var o={};for(var n in e){Object.prototype
|
|
|
129
129
|
-webkit-text-fill-color: transparent;
|
|
130
130
|
color: transparent;
|
|
131
131
|
}
|
|
132
|
-
`;let R=["background","font-weight","color","font","italic","size","script","strike","underline","indent","list","direction"];export const setQuillFormats=
|
|
132
|
+
`;let R=["background","font-weight","color","font","italic","size","script","strike","underline","indent","list","direction"];export const setQuillFormats=t=>{R=t};let F=!1;function L(){F||(F=!0,console.warn("[polotno] The Quill 'bold' format is deprecated. Use the numeric 'font-weight' format instead, e.g. quill.format('font-weight', '700') or applyTextFormat({ fontWeight: 700 })."))}function j(t){return t?"700":"400"}export const createQuill=(e,o)=>{v();const i=new n(e,{toolbar:!1,keyboard:!1,placeholder:(null==o?void 0:o.placeholder)||void 0,clipboard:{matchVisual:!1},formats:R});!function(e){const o=e.format.bind(e),n=e.formatText.bind(e),i=e.getFormat.bind(e);e.format=(t,e,n)=>"bold"===t?(L(),o("font-weight",j(e),n)):o(t,e,n),e.formatText=(e,o,i,r,l)=>{if(i&&"object"==typeof i){if("bold"in i){L();const{bold:l}=i,s=t(i,["bold"]);return n(e,o,Object.assign(Object.assign({},s),{"font-weight":j(l)}),r)}return n(e,o,i,r)}return"bold"===i?(L(),n(e,o,"font-weight",j(r),l)):n(e,o,i,r,l)},e.getFormat=(...t)=>{const e=i(...t);return e&&null!=e["font-weight"]&&!("bold"in e)&&(e.bold=f(e["font-weight"])),e}}(i);const r=n.import("delta"),l=(t,e)=>e.compose((new r).retain(e.length(),{"font-weight":"700"}));return i.clipboard.addMatcher("STRONG",l),i.clipboard.addMatcher("B",l),i};export const setQuillContent=(t,e)=>{var o=t.clipboard.convert({html:"<div class='ql-editor' style='outline: none;'>"+e.replace(/\t/g,"")+"<p><br></p></div>",text:""});o.ops.forEach(t=>{"string"==typeof t.insert&&t.insert.includes("")&&(t.insert=t.insert.split("").join("\t"))}),t.setContents(o),t.history.clear()};export const RichEditor=({onBlur:t,onChange:n,element:s,clickCoords:u})=>{var f,p,v;const y=o.useRef(null),w=o.useRef(!1);o.useLayoutEffect(()=>{let e,o=!1,r=null,d=null,f=null,p=null,h=null;const m=()=>{if(!o&&y.current){try{e=createQuill(y.current,{placeholder:s.placeholder}),i.runInAction(()=>{quillRef.editor.instance=e}),quillRef.pendingToolbarInteraction=!1,window.__polotnoQuill=e,x({instance:e,store:s.store,element:s}),e.on("text-change",()=>{const t=e.getSelection();t&&(syncQuillFormatState(e,t),i.runInAction(()=>{quillRef.lastSelection={index:t.index,length:t.length}})),setTimeout(()=>{var t;const o=e.root;if(!o||!o.isConnected){return}if(!l(s)){return}const i=o.innerHTML;w.current=!0,n(c(function(t){const e=(t||"").trim();if("<p><br></p>"===e||"<p></p>"===e){return""}if(e.startsWith("<p>")&&e.endsWith("</p>")){const t=e.slice(3,-4);if(!/(<\/?(p|div|h[1-6]|ul|ol|li|table|thead|tbody|tr|td|blockquote)\b)/i.test(t)){return t}}return t}(i),{fontSize:s.fontSize,fontFamily:s.fontFamily}));const r=e.getContents(),a=s.fill;let d=null,u=!0;for(const e of r.ops){if("string"!=typeof e.insert||"\n"===e.insert){continue}const o=(null===(t=e.attributes)||void 0===t?void 0:t.color)||a;if(null===d){d=o}else if(o!==d){u=!1;break}}u&&d&&s.set({fill:d})},10)});const o=a(s,s.fontFamily);setQuillContent(e,o),w.current=!0;const m=y.current.closest(".polotno-workspace-inner"),g=null==m?void 0:m.scrollLeft,b=null==m?void 0:m.scrollTop;u?setCursorFromCoords(e,u):e.setSelection(0,0,"api"),m&&void 0!==g&&void 0!==b&&(m.scrollLeft=g,m.scrollTop=b),e.on("selection-change",(t,o,n)=>{t&&(syncQuillFormatState(e,t),i.runInAction(()=>{quillRef.lastSelection={index:t.index,length:t.length}}))});const v=e.root;p=e=>{const o=e.relatedTarget;(null==o?void 0:o.classList.contains("ql-clipboard"))||(N(o)||quillRef.pendingToolbarInteraction?T():setTimeout(()=>{quillRef.pendingToolbarInteraction||N(document.activeElement)?T():(C(),t())},0))},h=()=>{C()},v.addEventListener("blur",p),v.addEventListener("focus",h),r=v,d=t=>{var o,n;const i=e.getSelection();if(!i||0===i.length){return}const r=e.getText(i.index,i.length).replace(/\n$/,""),l=window.getSelection();let s="";if(l&&l.rangeCount>0){const t=l.getRangeAt(0);let e=t.cloneContents(),o=t.startContainer;o&&o.nodeType===Node.TEXT_NODE&&(o=o.parentNode);let n=t.endContainer;if(n&&n.nodeType===Node.TEXT_NODE&&(n=n.parentNode),o&&o===n){let t=o;for(;t&&t!==v&&t.nodeType===Node.ELEMENT_NODE;){const o=t.tagName;if("SPAN"!==o&&"EM"!==o&&"STRONG"!==o&&"U"!==o&&"S"!==o&&"A"!==o){break}const n=t.cloneNode(!1);n.appendChild(e),e=n,t=t.parentNode}}const i=document.createElement("div");i.appendChild(e),s=i.innerHTML}if(null===(o=t.clipboardData)||void 0===o||o.setData("text/plain",r),s){const e='<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>\x3c!--StartFragment--\x3e<div style="white-space: pre-wrap; overflow-wrap: break-word;">'+s+"</div>\x3c!--EndFragment--\x3e</body></html>";null===(n=t.clipboardData)||void 0===n||n.setData("text/html",e)}t.preventDefault()},f=t=>{d&&d(t);const o=e.getSelection();o&&o.length>0&&e.deleteText(o.index,o.length)},r.addEventListener("copy",d),r.addEventListener("cut",f)}catch(m){console.error("RichEditor init failed:",m)}}};return y.current?m():queueMicrotask(m),()=>{o=!0,r&&p&&r.removeEventListener("blur",p),r&&h&&r.removeEventListener("focus",h),C(),r&&d&&f&&(r.removeEventListener("copy",d),r.removeEventListener("cut",f)),i.runInAction(()=>{quillRef.editor.instance=null,quillRef.currentFormat={},quillRef.lastSelection=null}),S(e),delete window.__polotnoQuill}},[]),o.useEffect(()=>r(s,()=>`${s.text}\0${s.fontSize}\0${s.fontFamily}`,()=>{const t=quillRef.editor.instance;if(!t){return}if(w.current){return void(w.current=!1)}const e=t.getSelection();setQuillContent(t,a(s,s.fontFamily)),w.current=!0,e&&(t.setSelection(e.index,e.length),syncQuillFormatState(t,t.getSelection()))},{fireImmediately:!0}),[]),o.useEffect(()=>{window.addEventListener("blur",t);const e=e=>{var o;(null===(o=y.current)||void 0===o?void 0:o.contains(e.target))||N(e.target)||quillRef.pendingToolbarInteraction||(C(),t())};return window.addEventListener("mousedown",e),window.addEventListener("touchstart",e),()=>{window.removeEventListener("blur",t),window.removeEventListener("mousedown",e),window.removeEventListener("touchstart",e)}},[]);const q={color:s.fill};s.fill.indexOf("gradient")>=0&&(q["--polotno-gradient"]=s.fill,q.color="transparent");const k=m(s.fill)?null!==(p=null===(f=g(s.fill).stops[0])||void 0===f?void 0:f.color)&&void 0!==p?p:"#000000":b(s),E=s.a.rotation*Math.PI/180,O=s.shadowOffsetX*Math.cos(E)+s.shadowOffsetY*Math.sin(E),R=-s.shadowOffsetX*Math.sin(E)+s.shadowOffsetY*Math.cos(E);return e(RichTextContainer,{ref:y,style:Object.assign(Object.assign({},q),{fontSize:s.fontSize,fontFamily:s.fontFamily,fontWeight:s.fontWeight,fontStyle:s.fontStyle,"--polotno-text-decoration":s.textDecoration||"none",textTransform:s.textTransform,width:s.a.width,lineHeight:s.lineHeight,letterSpacing:s.letterSpacing*s.fontSize+"px",textAlign:s.align,opacity:Math.max(s.a.opacity,.2),textShadow:s.shadowEnabled?`${O}px ${R}px ${s.shadowBlur}px ${applyOpacityToColor(s.shadowColor,null!==(v=s.shadowOpacity)&&void 0!==v?v:1)}`:void 0,caretColor:k}),dir:d(h(s.text))})};function N(t){return!(!t||!t.closest(".sketch-picker")&&!t.closest("[data-polotno-keep-focus]")&&!t.closest(".polotno-portal")&&!t.closest(".polotno-toolbar"))}export function setCursorFromCoords(t,e){if(!t||!e){return}const{x:o,y:i}=e;try{let e=null;if(document.caretRangeFromPoint){e=document.caretRangeFromPoint(o,i)}else if(document.caretPositionFromPoint){const t=document.caretPositionFromPoint(o,i);t&&(e=document.createRange(),e.setStart(t.offsetNode,t.offset))}if(e){const o=n.find(e.startContainer,!0);if(o){const n=o.offset(t.scroll)+e.startOffset;return void t.setSelection(n,0,"api")}}}catch(r){}t.setSelection(0,0,"api")}
|
package/canvas/table-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,Fragment as e,jsxs as o}from"react/jsx-runtime";import i from"react";import{observer as n}from"mobx-react-lite";import{
|
|
1
|
+
import{jsx as t,Fragment as e,jsxs as o}from"react/jsx-runtime";import i from"react";import{observer as n}from"mobx-react-lite";import{observable as r,runInAction as l}from"mobx";import{nodeAutorun as s}from"../utils/mobx.js";import{Group as a,Rect as h,Line as c,Circle as d}from"react-konva";import{Html as g}from"react-konva-utils";import{ROLES as u}from"../model/store.js";import{isTouchDevice as w}from"../utils/screen.js";import{TextElement as p}from"./text-element.js";const f="#0d83dd",x=(t,e)=>{const o=t.target.getStage();o&&(o.container().style.cursor=e)},y=n(({axis:i,hovered:n,pillX:r,pillY:l,pillW:s,pillH:a,hitX:c,hitY:d,hitW:g,hitH:u,tint:w,hoverKind:p,idx:y,onSelect:v,onHoverChange:m})=>o(e,{children:[n&&t(h,{x:w.x,y:w.y,width:w.width,height:w.height,fill:"rgba(13, 131, 221, 0.08)",listening:!1}),t(h,{x:r,y:l,width:s,height:a,cornerRadius:Math.min(s,a)/2,fill:n?f:"#9ca3af",opacity:n?.55:.18,listening:!1}),t(h,{x:c,y:d,width:g,height:u,fill:"transparent",onMouseEnter:t=>{m({kind:p,idx:y}),x(t,"pointer")},onMouseLeave:t=>{m(null),x(t,"")},onClick:v})]})),v=n(({x:i,y:n,hovered:r,hoverKind:l,idx:s,isTouch:g,sizes:u,onInsert:w,onHoverChange:p})=>{const{hit:y,r:v,halo:m,stroke:b}=u,C=r||g;return o(a,{x:i,y:n,onMouseEnter:t=>{p({kind:l,idx:s}),x(t,"pointer")},onMouseLeave:t=>{p(null),x(t,"")},onClick:t=>{t.cancelBubble=!0,w()},children:[t(h,{x:-y/2,y:-y/2,width:y,height:y,fill:"transparent"}),C&&o(e,{children:[t(d,{radius:v+m,fill:"white",listening:!1}),t(d,{radius:v,fill:f,listening:!1}),t(c,{points:[.55*-v,0,.55*v,0],stroke:"white",strokeWidth:b,lineCap:"round",listening:!1}),t(c,{points:[0,.55*-v,0,.55*v],stroke:"white",strokeWidth:b,lineCap:"round",listening:!1})]})]})}),m=n(({element:o,store:i,inv:n,isTouch:r,hover:l,setHover:s})=>{const a=16*n,h=2*n,c=10*n,d={hit:22*n,r:7*n,halo:2*n,stroke:2*n},g=(t,e)=>null!==l&&l.kind===t&&l.idx===e,u=(t,e)=>i=>{i.cancelBubble=!0;const n=o._anchorCellId?o.cells.find(t=>t.id===o._anchorCellId):void 0;i.evt.shiftKey&&n?"col"===t?o.selectColumnRange(n.col,e):o.selectRowRange(n.row,e):"col"===t?o.selectColumn(e):o.selectRow(e)},w=[0],p=[0];for(let t=0;t<o.cols;t++){w.push(w[t]+o.colWidths[t]*o.a.width)}for(let t=0;t<o.rows;t++){p.push(p[t]+o.rowHeights[t]*o.a.height)}const f=[];for(let e=0;e<o.cols;e++){const i=Math.max(0,w[e+1]-w[e]-6);i<=0||f.push(t(y,{axis:"col",hovered:g("colSelect",e),pillX:w[e]+3,pillY:-h-c,pillW:i,pillH:h,hitX:w[e]+1,hitY:-a-c+h,hitW:i+4,hitH:a,tint:{x:w[e],y:0,width:w[e+1]-w[e],height:o.a.height},hoverKind:"colSelect",idx:e,onSelect:u("col",e),onHoverChange:s},`col-pill-${e}`))}for(let e=0;e<=o.cols;e++){f.push(t(v,{x:w[e],y:-c-h/2,hovered:g("colInsert",e),hoverKind:"colInsert",idx:e,isTouch:r,sizes:d,onInsert:()=>i.history.transaction(()=>o.addColumn(e)),onHoverChange:s},`col-insert-${e}`))}for(let e=0;e<o.rows;e++){const i=Math.max(0,p[e+1]-p[e]-6);i<=0||f.push(t(y,{axis:"row",hovered:g("rowSelect",e),pillX:-h-c,pillY:p[e]+3,pillW:h,pillH:i,hitX:-a-c+h,hitY:p[e]+1,hitW:a,hitH:i+4,tint:{x:0,y:p[e],width:o.a.width,height:p[e+1]-p[e]},hoverKind:"rowSelect",idx:e,onSelect:u("row",e),onHoverChange:s},`row-pill-${e}`))}for(let e=0;e<=o.rows;e++){f.push(t(v,{x:-c-h/2,y:p[e],hovered:g("rowInsert",e),hoverKind:"rowInsert",idx:e,isTouch:r,sizes:d,onInsert:()=>i.history.transaction(()=>o.addRow(e)),onHoverChange:s},`row-insert-${e}`))}return t(e,{children:f})});export const TableElement=n(({element:n,store:d})=>{const f=i.useRef(null),x=i.useRef(null),y=n.selectable||d.role===u.ADMIN,v=w(),b=n.isSelected,C=n._focusedCellIds.length>0,k=n.editingCell,S=1/Math.max(.01,d.scale),[E,I]=i.useState(null);i.useEffect(()=>{b||(n.clearCellFocus(),I(null))},[b]);const H=null==k?void 0:k._editModeEnabled;i.useEffect(()=>{n._editingCellId&&k&&!k._editModeEnabled&&n.exitCellEdit()},[H]),i.useEffect(()=>{C&&!n._editingCellId&&setTimeout(()=>{var t;return null===(t=x.current)||void 0===t?void 0:t.focus()},0)},[C,n._editingCellId]);const M=i.useMemo(()=>r.box(!1),[]);i.useEffect(()=>s(n,()=>{M.get()||n._fitRowsToContent&&d.history.ignore(()=>{n._applyFitRowsToContent()})}),[n,d,M]);const R=t=>{const e=t.target.getStage();if(!e){return}const o=e.getPointerPosition();if(!o){return}const i=f.current;if(!i){return}const r=i.getAbsoluteTransform().copy().invert().point(o);for(const l of n.visibleCells){const t=n.getCellRect(l.row,l.col,l.rowSpan,l.colSpan);if(r.x>=t.x&&r.x<=t.x+t.width&&r.y>=t.y&&r.y<=t.y+t.height){return l}}},W=(t,e)=>"dashed"===t?[4*e,2*e]:"dotted"===t?[e,e]:void 0,T=[];for(const e of n.visibleCells){const o=n.getCellRect(e.row,e.col,e.rowSpan,e.colSpan),i=0===e.row,r=e.row+e.rowSpan===n.rows,l=0===e.col,s=e.col+e.colSpan===n.cols;if(0===e.row){const i=e.getEffectiveBorder("top");if("none"!==i.style&&i.width>0){const n=o.y+i.width/2,r=o.x-(l?0:i.width/2),a=o.x+o.width+(s?0:i.width/2);T.push(t(c,{points:[r,n,a,n],stroke:i.color,strokeWidth:i.width,dash:W(i.style,i.width),listening:!1},`bt-${e.id}`))}}if(0===e.col){const n=e.getEffectiveBorder("left");if("none"!==n.style&&n.width>0){const l=o.x+n.width/2,s=o.y-(i?0:n.width/2),a=o.y+o.height+(r?0:n.width/2);T.push(t(c,{points:[l,s,l,a],stroke:n.color,strokeWidth:n.width,dash:W(n.style,n.width),listening:!1},`bl-${e.id}`))}}{const i=e.getEffectiveBorder("bottom");if("none"!==i.style&&i.width>0){const n=r?o.y+o.height-i.width/2:o.y+o.height,a=o.x-(l?0:i.width/2),h=o.x+o.width+(s?0:i.width/2);T.push(t(c,{points:[a,n,h,n],stroke:i.color,strokeWidth:i.width,dash:W(i.style,i.width),listening:!1},`bb-${e.id}`))}}{const n=e.getEffectiveBorder("right");if("none"!==n.style&&n.width>0){const l=s?o.x+o.width-n.width/2:o.x+o.width,a=o.y-(i?0:n.width/2),h=o.y+o.height+(r?0:n.width/2);T.push(t(c,{points:[l,a,l,h],stroke:n.color,strokeWidth:n.width,dash:W(n.style,n.width),listening:!1},`br-${e.id}`))}}}return o(e,{children:[t(h,{id:n.id,name:"element",x:n.a.x,y:n.a.y,rotation:n.a.rotation,width:n.a.width,height:n.a.height,fill:"transparent",opacity:n.a.opacity,hideInExport:!n.showInExport,listening:y,draggable:v?n.draggable&&b:n.draggable,onClick:t=>{if(!b){return}if(n.locked||!n.contentEditable){return}const e=R(t);e&&(t.evt.shiftKey&&C?(t.cancelBubble=!0,n.focusCellRange(e.row,e.col)):n.focusCell(e.id))},onDblClick:t=>{if(!b){return}if(n.locked||!n.contentEditable){return}const e=R(t);e&&n.enterCellEdit(e.id)},onDragMove:t=>{var e;const o=t.target;n.set({x:o.x(),y:o.y()}),null===(e=f.current)||void 0===e||e.position({x:o.x(),y:o.y()})},onDragEnd:t=>{const e=t.target;n.set({x:e.x(),y:e.y()})},onTransformStart:()=>{l(()=>M.set(!0))},onTransformEnd:()=>{n._resetBaseRowHeights(),l(()=>M.set(!1))},onTransform:t=>{var e,o;const i=t.target,r=i.scaleX(),l=i.scaleY();i.scaleX(1),i.scaleY(1);const s=n.width*r,a=n.height*l;i.width(s),i.height(a);const h=i.x(),c=i.y(),d=i.rotation();null===(e=f.current)||void 0===e||e.position({x:h,y:c}),null===(o=f.current)||void 0===o||o.rotation(d),n.set({width:s,x:h,y:c,rotation:d}),n.setHeightRedistribute(a)}}),o(a,{ref:f,x:n.a.x,y:n.a.y,rotation:n.a.rotation,opacity:n.a.opacity,hideInExport:!n.showInExport,scaleX:n.a.width/n.width,scaleY:n.a.height/n.height,children:[n.visibleCells.map(e=>{const o=n.getCellRect(e.row,e.col,e.rowSpan,e.colSpan);return"transparent"===e.cellBackground?null:t(h,{x:o.x,y:o.y,width:o.width,height:o.height,fill:e.cellBackground,listening:!1},`bg-${e.id}`)}),T,n.visibleCells.map(e=>t(p,{element:e,store:d},`text-${e.id}`)),b&&n._focusedCellIds.map(e=>{const o=n.cells.find(t=>t.id===e);if(!o){return null}const i=n.getCellRect(o.row,o.col,o.rowSpan,o.colSpan),r=2*S;return t(h,{x:i.x,y:i.y,width:i.width,height:i.height,fill:"rgba(13, 131, 221, 0.1)",stroke:"#0d83dd",strokeWidth:r,listening:!1},`focus-${e}`)}),C&&!k&&t(g,{children:t("div",{ref:x,tabIndex:-1,style:{position:"absolute",opacity:0,width:"1px",height:"1px",pointerEvents:"none",outline:"none"}})}),b&&!k&&!d.isPlaying&&(()=>{const e=[];let o=0;for(let i=0;i<n.cols-1;i++){o+=n.colWidths[i]*n.a.width;const r=o,l=i;e.push(t(c,{x:r,points:[0,0,0,n.a.height],stroke:"transparent",strokeWidth:1,hitStrokeWidth:16,draggable:!0,onMouseEnter:t=>{var e;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.container();o&&(o.style.cursor="col-resize"),I({kind:"colInsert",idx:l+1})},onMouseLeave:t=>{var e;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.container();o&&(o.style.cursor=""),I(null)},onDragStart:t=>{t.cancelBubble=!0,d.history.startTransaction()},onDragMove:t=>{t.cancelBubble=!0;const e=t.target,o=(e.x()-r)/n.width;e.x(r),n.resizeColumn(l,o)},onDragEnd:t=>{t.cancelBubble=!0,t.target.x(r),d.history.endTransaction()}},`col-resize-${i}`))}return e})(),b&&!k&&!d.isPlaying&&(()=>{const e=[];let o=0;for(let i=0;i<n.rows-1;i++){o+=n.rowHeights[i]*n.a.height;const r=o,s=i;e.push(t(c,{y:r,points:[0,0,n.a.width,0],stroke:"transparent",strokeWidth:1,hitStrokeWidth:16,draggable:!0,onMouseEnter:t=>{var e;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.container();o&&(o.style.cursor="row-resize"),I({kind:"rowInsert",idx:s+1})},onMouseLeave:t=>{var e;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.container();o&&(o.style.cursor=""),I(null)},onDragStart:t=>{t.cancelBubble=!0,l(()=>M.set(!0)),d.history.startTransaction()},onDragMove:t=>{t.cancelBubble=!0;const e=t.target,o=(e.y()-r)/n.height;e.y(r),n.resizeRow(s,o)},onDragEnd:t=>{t.cancelBubble=!0,t.target.y(r),n._resetBaseRowHeights(),l(()=>M.set(!1)),d.history.endTransaction()}},`row-resize-${i}`))}return e})(),b&&!k&&!d.isPlaying&&t(m,{element:n,store:d,inv:S,isTouch:v,hover:E,setHover:I})]})]})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getHtml as t}from"../../utils/text-html.js";import{detectSize as e,isContentWrapping as i}from"../../utils/html2canvas.js";import{normalizeRichTextHtml as o,hasAnyInlineFontSize as n,scaleRichTextFontSizesInHtml as f}from"../../utils/rich-text-html.js";import{flags as l}from"../../utils/flags.js";const r=t=>e(t).height;export function findFitFontSize(e,s,
|
|
1
|
+
import{getHtml as t}from"../../utils/text-html.js";import{detectSize as e,isContentWrapping as i}from"../../utils/html2canvas.js";import{normalizeRichTextHtml as o,hasAnyInlineFontSize as n,scaleRichTextFontSizesInHtml as f}from"../../utils/rich-text-html.js";import{flags as l}from"../../utils/flags.js";const r=t=>e(t).height;export function findFitFontSize(e,s,a=r){const m=o(e.text,{fontSize:e.fontSize,fontFamily:e.fontFamily});if(n(m)){return function(e,n,s=r){let a=1;for(let r=1;r<50;r++){const r=f(e.text,a),m=e.fontSize*a,S=t(Object.assign(Object.assign({},e.toJSON()),{fontSize:m,text:o(r,{fontSize:m,fontFamily:e.fontFamily})}),n),h=s(S);if(!(e.height&&h>e.height||!l.textSplitAllowed&&!e.curveEnabled&&i({html:S}))){break}a-=.02;const c=Math.max(.05,1/e.fontSize);if(a<c){a=c;break}}return a>=1?{fontSize:e.fontSize}:{fontSize:e.fontSize*a,text:f(e.text,a)}}(e,s,a)}let S=e.fontSize;for(let n=1;n<50;n++){const n=t(Object.assign(Object.assign({},e.toJSON()),{fontSize:S,text:o(e.text,{fontSize:S,fontFamily:e.fontFamily})}),s),f=a(n);if(!(e.height&&f>e.height||!l.textSplitAllowed&&!e.curveEnabled&&i({html:n}))){break}if(S-=.5,S<1){S=1;break}}return{fontSize:S}}
|
package/canvas/text-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,Fragment as e,jsxs as r}from"react/jsx-runtime";import n from"react";import{observer as o}from"mobx-react-lite";import{Group as i,Path as a,Text as l,TextPath as s}from"react-konva";import{Html as c}from"react-konva-utils";import{autorun as u}from"mobx";import d from"konva";import{parsePath as f,roundCommands as h}from"svg-round-corners/lib/index.js";import{generateBackgroundShapeFromRects as g,textLinesToRects as m}from"../utils/background-shape.js";import{useColor as p}from"./use-color.js";import{useWorkspaceStyle as x}from"./workspace-style.js";import{ROLES as w}from"../model/store.js";import{incrementLoader as v}from"../utils/loader.js";import{isFontLoaded as y}from"../utils/fonts.js";import{flags as S}from"../utils/flags.js";import{removeTags as b}from"../utils/text.js";import{getDir as E,getCurvePath as z,resolveLineHeight as k}from"../utils/text-html.js";import{applyFilter as O}from"./apply-filters.js";import{useFadeIn as R}from"./use-fadein.js";import{isTouchDevice as A}from"../utils/screen.js";import{isAlive as F,getParent as M}from"mobx-state-tree";import{getLimitedFontSize as j}from"./text-element/max-font-size.js";import{getOptimalCaretColor as L}from"./text-element/caret-color.js";let T;function C(){return T||(T=document.getElementById("polotno-text-style"),T||(T=document.createElement("style"),T.id="polotno-text-style",document.head.appendChild(T)),T)}d._fixTextRendering=!0;const H={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 X=o(({textNodeRef:e,element:r,onBlur:o,selectAll:i,cursorPosition:a})=>{const[l,s]=n.useState(H),c=e.current;n.useLayoutEffect(()=>{if(!c){return}const t={};t.width=c.width()-2*c.padding()+"px",t.height=c.height()-2*c.padding()+c.fontSize()*c.lineHeight()+"px",t.fontSize=c.fontSize()+"px",t.lineHeight=c.lineHeight()+.01,t.fontFamily=c.fontFamily(),t.textAlign=c.align(),t.color=c.fill(),t.fontWeight=r.fontWeight,t.fontStyle=r.fontStyle,t.letterSpacing=r.letterSpacing+"em",t.opacity=Math.max(r.a.opacity,.2),t.textTransform=r.textTransform,t.caretColor=L(r);const e=`\n .polotno-input::placeholder {\n color: ${l.color};\n opacity: 0.6;\n }\n `,n=C();n.innerHTML="",n.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(l)&&s(t)});const u=n.useRef(null);if(n.useLayoutEffect(()=>{var t;const e=u.current;if(!e){return}null===(t=u.current)||void 0===t||t.focus({preventScroll:!0});const r=a||e.value.length;e.selectionStart=e.selectionEnd=r,i&&(null==e||e.select(),document.execCommand("selectAll",!1,void 0))},[]),n.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=u.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]),!c){return null}let d=0;const f=c.textArr.length*c.lineHeight()*c.fontSize();"middle"===r.verticalAlign&&(d=(r.a.height-f)/2),"bottom"===r.verticalAlign&&(d=r.a.height-f);const h=b(r.text);return t("textarea",{className:"polotno-input",ref:u,dir:E(h),style:Object.assign(Object.assign(Object.assign({},H),l),{paddingTop:d+"px"}),value:h,onChange:t=>{const e=j({oldText:r.text,newText:t.target.value,element:r});r.set({text:t.target.value,fontSize:e})},placeholder:r.placeholder,onBlur:o})}),Y=e=>t(c,{children:t(X,Object.assign({},e))});export const useFontLoader=(t,e,r,o,i)=>{const[a,l]=n.useReducer(t=>t+1,0),s=n.useRef(y(e,r,o)),c=n.useRef(null);return n.useLayoutEffect(()=>{if(s.current=y(e,r,o),s.current){return}let n=!0;return(async()=>{s.current=!1,l();const a=v(`text ${e}`);await t.loadFont(e,r,o,i),n?(c.current=a,s.current=!0,l()):a()})(),()=>{c.current&&(c.current(),c.current=null),n=!1}},[e,r,o]),n.useEffect(()=>{s.current&&setTimeout(()=>{c.current&&(c.current(),c.current=null)})},[s.current]),[s.current]};export const useFontFamiliesLoader=(t,e,r,o,i)=>{const[a,l]=n.useReducer(t=>t+1,0),s=e.join("\0"),c=n.useRef(e.every(t=>y(t,r,o))),u=n.useRef(null);return n.useLayoutEffect(()=>{if(c.current=e.every(t=>y(t,r,o)),c.current){return}let n=!0;return(async()=>{c.current=!1,l();const a=v(`text fonts ${s}`);await Promise.all(e.map(e=>t.loadFont(e,r,o,i))),n?(u.current=a,c.current=!0,l()):a()})(),()=>{u.current&&(u.current(),u.current=null),n=!1}},[s,r,o]),n.useEffect(()=>{c.current&&setTimeout(()=>{u.current&&(u.current(),u.current=null)})},[c.current]),[c.current]};export const getLineHeight=({fontLoaded:t,fontFamily:e,fontSize:r,lineHeight:o})=>n.useMemo(()=>k({fontFamily:e,fontSize:r,lineHeight:o}),[t,e,r,o]);export function usePrevious(t){const e=n.useRef(t),r=n.useRef(t);return n.useMemo(()=>{r.current=e.current,e.current=t},[t]),r.current}function P(t,e,r=!1){const n=t.fontSize(),o=t.height(),i=b(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 n=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(!(n||s&&!r)){break}a-=.5,t.fontSize(a)}return t.fontSize(n),t.height(o),a}export{getCurvePath}from"../utils/text-html.js";export const TextElement=o(({element:o,store:c})=>{const{textOverflowIndicatorStyle:d}=x(),y=n.useRef(null),k=n.useRef(null),j=n.useRef(null),L=n.useRef([]),T=n.useRef(!0),[,C]=n.useReducer(t=>t+1,0),{editorEnabled:H,selectAll:X}=(t=>{const[e,r]=n.useState(!1),o=n.useRef(!1);return n.useEffect(()=>{var e=!0;return setTimeout(()=>{e&&(t._editModeEnabled&&(o.current=!0),r(!0),setTimeout(()=>{o.current=!1},50))},50),()=>{e=!1}},[]),{editorEnabled:e&&t._editModeEnabled,selectAll:o.current}})(o),[W,B]=n.useState(!1),[D,$]=n.useState(!1),I=n.useRef(o.a.height),N=n.useRef(0),J=n.useRef(""),_=n.useRef(0),V=o.isSelected,q=usePrevious(V),{textVerticalResizeEnabled:U}=S,Z=S.autoDeleteEmptyText,G=usePrevious(o.fontFamily),[K,Q]=n.useState([]);n.useEffect(()=>{var t,e;const r=null!==(e=null===(t=y.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(r)!==JSON.stringify(K)&&Q(r)}),n.useEffect(()=>{if(o.a.width||"tablecell"===o.type){return}const t=y.current;t.width(600),o.set({width:1.4*t.getTextWidth()})},[]),n.useEffect(()=>{q&&!V&&Z&&""===o.text&&o.removable&&!o.placeholder&&c.deleteElements([o.id])},[Z,o.placeholder,o.removable,o.text,V,q]);const tt=()=>{if(o.curveEnabled){const t=y.current;null==t||t.clearCache(),null==t||t.setAttrs({filters:[]});const e=k.current;e&&O(e,o)}else{const t=y.current;t&&O(t,o)}};n.useLayoutEffect(()=>{if(!D){return u(()=>{tt()})}}),n.useEffect(()=>{const t=L.current;t.length>0&&(L.current=[],t.forEach(t=>t()))}),n.useEffect(()=>()=>{T.current=!1;const t=L.current;t.length>0&&(L.current=[],t.forEach(t=>t()))},[]);let et=b(o.text);"uppercase"===o.textTransform&&(et=et.toUpperCase());const[rt]=useFontLoader(c,o.fontFamily,o.fontStyle,o.fontWeight,o.text||o.placeholder),nt=()=>{if(o.curveEnabled){const t=k.current;return t.getSelfRect().height||t.fontSize()}const t=y.current.clone({height:void 0}),e=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),e};n.useLayoutEffect(()=>{if(!rt){return}if("tablecell"===o.type){const{textOverflow:t}=S;if("resize"===t){const t=nt(),e=F(o)?M(o,2):null;(null==e?void 0:e.setCellContentHeight)&&e.setCellContentHeight(o.id,t)}else if("change-font-size"===t){const t=y.current;if(t){const e=P(t,o,S.textSplitAllowed);e!==o.fontSize&&c.history.ignore(()=>{o.set({fontSize:e})})}}return}const{textOverflow:t,textSplitAllowed:e}=S,r=(t,e,r,n)=>{const i=v(`text ${o.id}`),a=()=>{c.history.ignore(t,e,r).then(()=>{T.current?(L.current.push(i),C()):i()})};n?queueMicrotask(a):a()};if(!o.height){const t=nt();return void r(()=>{o.height||o.set({height:t})},void 0,void 0,!0)}if(!c.isPlaying){if("change-font-size"!==t||W){if("resize"===t){const t=nt();U&&o.height<t&&!W&&r(()=>{var e;F(o)&&o.set({height:t}),null===(e=y.current)||void 0===e||e.height(t)},!1,!0),U||o.height===t||W||r(()=>{var e;F(o)&&o.set({height:t}),null===(e=y.current)||void 0===e||e.height(t)},!1,!0)}}else{const t=y.current,n=o.curveEnabled?o.fontSize:P(t,o,e);if(n!==o.fontSize){return void r(()=>{o.set({fontSize:n})},!1,!0)}const i=nt();o.height===i||U||r(()=>{o.set({height:i})},!1,!0)}}}),n.useLayoutEffect(()=>{var t;if(rt&&o.curveEnabled){const e=null===(t=k.current)||void 0===t?void 0:t.getSelfRect().width;if(e){const t=e-o.a.width,r=o.a.rotation*Math.PI/180,n=-t/2*Math.cos(r),i=-t/2*Math.sin(r);o.set({width:e,x:o.a.x+n,y:o.a.y+i})}}},[rt,o.curveEnabled,o.curvePower,o.text,o.fontSize,o.fontFamily,o.fontWeight,o.fontStyle,o.letterSpacing]),n.useLayoutEffect(()=>{const t=y.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),tt())},[rt]);const ot=n.useRef(null),it=n.useRef(0),at=t=>{t.evt.preventDefault();const e=c.selectedShapes.find(t=>t===o);e&&o.contentEditable&&(it.current=function(t){var e;const r=t.target,n=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var r=t.getStage().getPointerPosition();return e.point(r)}(r),o=r.textArr,i=Math.floor(n.y/(r.fontSize()*r.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"===r.align()?s=r.width()-l.width:"center"===r.align()&&(s=r.width()/2-l.width/2),a+Math.round((n.x-s)/l.width*l.text.length)}(t),o.toggleEditMode())},lt=!et&&o.placeholder?.6:o.a.opacity;R(y,lt);const st=getLineHeight({fontLoaded:rt,fontFamily:o.fontFamily,fontSize:o.a.fontSize,lineHeight:o.lineHeight}),ct=o.selectable||c.role===w.ADMIN,ut=p(o),dt=p(o,o.stroke,"stroke"),ft=n.useMemo(()=>o.backgroundEnabled?o.curveEnabled?function({width:t,height:e,padding:r=0,cornerRadius:n=0}){const o=-r,i=-r,a=t+r,l=e+r,s=f(`M ${o} ${i} L ${a} ${i} L ${a} ${l} L ${o} ${l} Z`);return h(s,n).path}({width:o.a.width,height:o.a.height,cornerRadius:o.backgroundCornerRadius*(o.a.fontSize*st*.5),padding:o.backgroundPadding*(o.a.fontSize*st*.5)}):function({lines:t,lineHeight:e,width:r,align:n="left",padding:o=0,cornerRadius:i=0}){const a=m({lines:t,lineHeight:e,width:r,align:n});return g({rects:a,padding:o,cornerRadius:i})}({lines:JSON.parse(JSON.stringify(K)),cornerRadius:o.backgroundCornerRadius*(o.a.fontSize*st*.5),lineHeight:st*o.a.fontSize,padding:o.backgroundPadding*(o.a.fontSize*st*.5),width:o.a.width,align:o.align}):"",[o.backgroundEnabled,o.curveEnabled,o.backgroundCornerRadius,o.a.fontSize,o.a.height,st,o.backgroundPadding,o.a.width,o.align,K]),ht=A();let gt=0;o.curveEnabled||("middle"===o.verticalAlign?gt=(o.a.height-K.length*st*o.a.fontSize)/2:"bottom"===o.verticalAlign&&(gt=o.a.height-K.length*st*o.a.fontSize));const mt=o.curveEnabled?z(o.a.width,o.a.height,o.curvePower,o.a.fontSize):"",pt=rt?'"'+o.fontFamily+'"':G===o.fontFamily?"Arial":'"'+G+'"',xt=E(et);return r(e,{children:[t(a,{ref:j,x:o.a.x,y:o.a.y,rotation:o.a.rotation,hideInExport:!o.showInExport,listening:!1,visible:o.backgroundEnabled,opacity:o.backgroundOpacity*lt,data:ft,fill:o.backgroundColor,offsetY:-gt}),t(a,{data:mt,stroke:d.stroke,strokeWidth:1,x:o.a.x,y:o.a.y,rotation:o.a.rotation,visible:!1}),t(s,Object.assign({ref:k,visible:o.curveEnabled,data:mt,text:et||o.placeholder,listening:!1,align:"center",textBaseline:"middle",direction:xt},ut,dt,{strokeWidth:o.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:o.a.fontSize,fontFamily:`"${o.fontFamily}", "${G}"`,fontStyle:o.fontStyle+" "+o.fontWeight,textDecoration:o.textDecoration.trim(),letterSpacing:o.letterSpacing*o.a.fontSize,x:o.a.x,y:o.a.y,rotation:o.a.rotation,opacity:o._editModeEnabled?.3:lt,hideInExport:!o.showInExport,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity})),t(l,Object.assign({ref:y,id:o.selectable?o.id:void 0,name:o.selectable?"element":"",hideInExport:!o.showInExport,editModeEnabled:o._editModeEnabled,x:o.a.x,y:o.a.y,rotation:o.a.rotation,width:o.a.width,height:o.a.height,text:et||o.placeholder,direction:xt},ut,dt,{lineJoin:"round",strokeWidth:o.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:o.a.fontSize,fontFamily:pt,fontStyle:o.fontStyle+" "+o.fontWeight,textDecoration:o.textDecoration,align:o.align,verticalAlign:o.verticalAlign,draggable:ht?o.draggable&&V:o.draggable,preventDefault:!ht||V,opacity:o.curveEnabled?0:lt,visible:!o._editModeEnabled,ellipsis:"ellipsis"===S.textOverflow,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,lineHeight:st,letterSpacing:o.letterSpacing*o.a.fontSize,listening:!!o.selectable&&ct,onDragStart:()=>{$(!0)},onDragMove:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{$(!1),o.set({x:t.target.x(),y:t.target.y()})},onClick:at,onTap:at,onTransformStart:()=>{var t,e;B(!0);const r=y.current;I.current=r.height(),N.current=r.rotation(),_.current=r.height();const n=null===(t=r.getStage())||void 0===t?void 0:t.findOne("Transformer");J.current=null!==(e=null==n?void 0:n.getActiveAnchor())&&void 0!==e?e:""},onTransform:t=>{var e,r,n;const i=t.target;null===(e=j.current)||void 0===e||e.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(),e=i.width()*t,r=o.a.fontSize;let n=e;e<r&&(n=r,ot.current&&i.position(ot.current)),i.width(n),i.scaleX(1),i.scaleY(1);let a=nt();if("ellipsis"===S.textOverflow){a=I.current}else{const t=Math.max(a,I.current);i.height(t),o.set({height:i.height()})}const l=S.textVerticalResizeEnabled?Math.max(a,I.current):nt();o.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),i.skewX(0),i.skewY(0),tt()}if("top-center"===a||"bottom-center"===a){const e="resize"===S.textOverflow?nt():st*o.a.fontSize,r=t.target.height()*t.target.scaleY();if(r<e){if(t.target.height(e),ot.current){if("top-center"===J.current){const r=N.current*Math.PI/180,n=_.current-e;t.target.x(ot.current.x-n*Math.sin(r)),t.target.y(ot.current.y+n*Math.cos(r))}else{t.target.position(ot.current)}}}else{t.target.height(r)}t.target.scaleY(1),t.target.scaleX(1),t.target.rotation(N.current),t.target.skewX(0),t.target.skewY(0),_.current=Math.max(e,r)}ot.current=t.target.position();const l=t.target.scaleX();null===(n=j.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),o.set({fontSize:o.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:o.shadowBlur*l,shadowOffsetX:o.shadowOffsetX*l,shadowOffsetY:o.shadowOffsetY*l,strokeWidth:o.strokeWidth*l})},onTransformEnd:t=>{var e;const r=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),o.set({fontSize:Math.round(o.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:o.shadowBlur*r,shadowOffsetX:o.shadowOffsetX*r,shadowOffsetY:o.shadowOffsetY*r,strokeWidth:o.strokeWidth*r}),null===(e=j.current)||void 0===e||e.setAttrs({scaleX:1,scaleY:1}),B(!1)}})),H&&o.contentEditable&&t(i,{x:o.a.x,y:o.a.y,rotation:o.a.rotation,children:t(Y,{textNodeRef:y,element:o,selectAll:X,cursorPosition:it.current,onBlur:()=>{o.toggleEditMode(!1)}})})]})});
|
|
1
|
+
import{jsx as t,Fragment as e,jsxs as r}from"react/jsx-runtime";import n from"react";import{observer as o}from"mobx-react-lite";import{Group as i,Path as a,Text as s,TextPath as l}from"react-konva";import{Html as c}from"react-konva-utils";import{nodeAutorun as u}from"../utils/mobx.js";import d from"konva";import{parsePath as f,roundCommands as h}from"svg-round-corners/lib/index.js";import{generateBackgroundShapeFromRects as g,textLinesToRects as m}from"../utils/background-shape.js";import{useColor as p}from"./use-color.js";import{useWorkspaceStyle as x}from"./workspace-style.js";import{ROLES as w}from"../model/store.js";import{incrementLoader as v}from"../utils/loader.js";import{isFontLoaded as y}from"../utils/fonts.js";import{flags as S}from"../utils/flags.js";import{removeTags as b}from"../utils/text.js";import{getDir as E,getCurvePath as z,resolveLineHeight as k,normalizeStrokeLineJoin as O}from"../utils/text-html.js";import{applyFilter as R}from"./apply-filters.js";import{useFadeIn as A}from"./use-fadein.js";import{isTouchDevice as F}from"../utils/screen.js";import{isAlive as M,getParent as j}from"mobx-state-tree";import{getLimitedFontSize as L}from"./text-element/max-font-size.js";import{getOptimalCaretColor as T}from"./text-element/caret-color.js";let C;function H(){return C||(C=document.getElementById("polotno-text-style"),C||(C=document.createElement("style"),C.id="polotno-text-style",document.head.appendChild(C)),C)}d._fixTextRendering=!0;const X={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 Y=o(({textNodeRef:e,element:r,onBlur:o,selectAll:i,cursorPosition:a})=>{const[s,l]=n.useState(X),c=e.current;n.useLayoutEffect(()=>{if(!c){return}const t={};t.width=c.width()-2*c.padding()+"px",t.height=c.height()-2*c.padding()+c.fontSize()*c.lineHeight()+"px",t.fontSize=c.fontSize()+"px",t.lineHeight=c.lineHeight()+.01,t.fontFamily=c.fontFamily(),t.textAlign=c.align(),t.color=c.fill(),t.fontWeight=r.fontWeight,t.fontStyle=r.fontStyle,t.letterSpacing=r.letterSpacing+"em",t.opacity=Math.max(r.a.opacity,.2),t.textTransform=r.textTransform,t.caretColor=T(r);const e=`\n .polotno-input::placeholder {\n color: ${s.color};\n opacity: 0.6;\n }\n `,n=H();n.innerHTML="",n.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(s)&&l(t)});const u=n.useRef(null);if(n.useLayoutEffect(()=>{var t;const e=u.current;if(!e){return}null===(t=u.current)||void 0===t||t.focus({preventScroll:!0});const r=a||e.value.length;e.selectionStart=e.selectionEnd=r,i&&(null==e||e.select(),document.execCommand("selectAll",!1,void 0))},[]),n.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=u.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]),!c){return null}let d=0;const f=c.textArr.length*c.lineHeight()*c.fontSize();"middle"===r.verticalAlign&&(d=(r.a.height-f)/2),"bottom"===r.verticalAlign&&(d=r.a.height-f);const h=b(r.text);return t("textarea",{className:"polotno-input",ref:u,dir:E(h),style:Object.assign(Object.assign(Object.assign({},X),s),{paddingTop:d+"px"}),value:h,onChange:t=>{const e=L({oldText:r.text,newText:t.target.value,element:r});r.set({text:t.target.value,fontSize:e})},placeholder:r.placeholder,onBlur:o})}),P=e=>t(c,{children:t(Y,Object.assign({},e))});export const useFontLoader=(t,e,r,o,i)=>{const[a,s]=n.useReducer(t=>t+1,0),l=n.useRef(y(e,r,o)),c=n.useRef(null);return n.useLayoutEffect(()=>{if(l.current=y(e,r,o),l.current){return}let n=!0;return(async()=>{l.current=!1,s();const a=v(`text ${e}`);await t.loadFont(e,r,o,i),n?(c.current=a,l.current=!0,s()):a()})(),()=>{c.current&&(c.current(),c.current=null),n=!1}},[e,r,o]),n.useEffect(()=>{l.current&&setTimeout(()=>{c.current&&(c.current(),c.current=null)})},[l.current]),[l.current]};export const useFontFamiliesLoader=(t,e,r,o,i)=>{const[a,s]=n.useReducer(t=>t+1,0),l=e.join("\0"),c=n.useRef(e.every(t=>y(t,r,o))),u=n.useRef(null);return n.useLayoutEffect(()=>{if(c.current=e.every(t=>y(t,r,o)),c.current){return}let n=!0;return(async()=>{c.current=!1,s();const a=v(`text fonts ${l}`);await Promise.all(e.map(e=>t.loadFont(e,r,o,i))),n?(u.current=a,c.current=!0,s()):a()})(),()=>{u.current&&(u.current(),u.current=null),n=!1}},[l,r,o]),n.useEffect(()=>{c.current&&setTimeout(()=>{u.current&&(u.current(),u.current=null)})},[c.current]),[c.current]};export const getLineHeight=({fontLoaded:t,fontFamily:e,fontSize:r,lineHeight:o})=>n.useMemo(()=>k({fontFamily:e,fontSize:r,lineHeight:o}),[t,e,r,o]);export function usePrevious(t){const e=n.useRef(t),r=n.useRef(t);return n.useMemo(()=>{r.current=e.current,e.current=t},[t]),r.current}function W(t,e,r=!1){const n=t.fontSize(),o=t.height(),i=b(e.text);let a=e.a.fontSize;t.height(void 0);const s=Math.round(2*e.a.fontSize)-1;for(let l=1;l<s;l++){const n=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)),[]),s=t.textArr.map(t=>t.text.toLowerCase()).join(";");const l=o.find(t=>!s.includes(t)||(s=s.replace(t,""),!1));if(!(n||l&&!r)){break}a-=.5,t.fontSize(a)}return t.fontSize(n),t.height(o),a}export{getCurvePath}from"../utils/text-html.js";export const TextElement=o(({element:o,store:c})=>{const{textOverflowIndicatorStyle:d}=x(),y=n.useRef(null),k=n.useRef(null),L=n.useRef(null),T=n.useRef([]),C=n.useRef(!0),[,H]=n.useReducer(t=>t+1,0),{editorEnabled:X,selectAll:Y}=(t=>{const[e,r]=n.useState(!1),o=n.useRef(!1);return n.useEffect(()=>{var e=!0;return setTimeout(()=>{e&&(t._editModeEnabled&&(o.current=!0),r(!0),setTimeout(()=>{o.current=!1},50))},50),()=>{e=!1}},[]),{editorEnabled:e&&t._editModeEnabled,selectAll:o.current}})(o),[B,D]=n.useState(!1),[$,I]=n.useState(!1),N=n.useRef(o.a.height),J=n.useRef(0),_=n.useRef(""),V=n.useRef(0),q=o.isSelected,U=usePrevious(q),{textVerticalResizeEnabled:Z}=S,G=S.autoDeleteEmptyText,K=usePrevious(o.fontFamily),[Q,tt]=n.useState([]);n.useEffect(()=>{var t,e;const r=null!==(e=null===(t=y.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(r)!==JSON.stringify(Q)&&tt(r)}),n.useEffect(()=>{if(o.a.width||"tablecell"===o.type){return}const t=y.current;t.width(600),o.set({width:1.4*t.getTextWidth()})},[]),n.useEffect(()=>{U&&!q&&G&&""===o.text&&o.removable&&!o.placeholder&&c.deleteElements([o.id])},[G,o.placeholder,o.removable,o.text,q,U]);const et=()=>{if(o.curveEnabled){const t=y.current;null==t||t.clearCache(),null==t||t.setAttrs({filters:[]});const e=k.current;e&&R(e,o)}else{const t=y.current;t&&R(t,o)}};n.useLayoutEffect(()=>{if(!$){return u(o,()=>{et()})}}),n.useEffect(()=>{const t=T.current;t.length>0&&(T.current=[],t.forEach(t=>t()))}),n.useEffect(()=>()=>{C.current=!1;const t=T.current;t.length>0&&(T.current=[],t.forEach(t=>t()))},[]);let rt=b(o.text);"uppercase"===o.textTransform&&(rt=rt.toUpperCase());const[nt]=useFontLoader(c,o.fontFamily,o.fontStyle,o.fontWeight,o.text||o.placeholder),ot=()=>{if(o.curveEnabled){const t=k.current;return t.getSelfRect().height||t.fontSize()}const t=y.current.clone({height:void 0}),e=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),e};n.useLayoutEffect(()=>{if(!nt){return}if("tablecell"===o.type){const{textOverflow:t}=S;if("resize"===t){const t=ot(),e=M(o)?j(o,2):null;(null==e?void 0:e.setCellContentHeight)&&e.setCellContentHeight(o.id,t)}else if("change-font-size"===t){const t=y.current;if(t){const e=W(t,o,S.textSplitAllowed);e!==o.fontSize&&c.history.ignore(()=>{o.set({fontSize:e})})}}return}const{textOverflow:t,textSplitAllowed:e}=S,r=(t,e,r,n)=>{const i=v(`text ${o.id}`),a=()=>{c.history.ignore(t,e,r).then(()=>{C.current?(T.current.push(i),H()):i()})};n?queueMicrotask(a):a()};if(!o.height){const t=ot();return void r(()=>{o.height||o.set({height:t})},void 0,void 0,!0)}if(!c.isPlaying){if("change-font-size"!==t||B){if("resize"===t){const t=ot();Z&&o.height<t&&!B&&r(()=>{var e;M(o)&&o.set({height:t}),null===(e=y.current)||void 0===e||e.height(t)},!1,!0),Z||o.height===t||B||r(()=>{var e;M(o)&&o.set({height:t}),null===(e=y.current)||void 0===e||e.height(t)},!1,!0)}}else{const t=y.current,n=o.curveEnabled?o.fontSize:W(t,o,e);if(n!==o.fontSize){return void r(()=>{o.set({fontSize:n})},!1,!0)}const i=ot();o.height===i||Z||r(()=>{o.set({height:i})},!1,!0)}}}),n.useLayoutEffect(()=>{var t;if(nt&&o.curveEnabled){const e=null===(t=k.current)||void 0===t?void 0:t.getSelfRect().width;if(e){const t=e-o.a.width,r=o.a.rotation*Math.PI/180,n=-t/2*Math.cos(r),i=-t/2*Math.sin(r);o.set({width:e,x:o.a.x+n,y:o.a.y+i})}}},[nt,o.curveEnabled,o.curvePower,o.text,o.fontSize,o.fontFamily,o.fontWeight,o.fontStyle,o.letterSpacing]),n.useLayoutEffect(()=>{const t=y.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),et())},[nt]);const it=n.useRef(null),at=n.useRef(0),st=t=>{t.evt.preventDefault();const e=c.selectedShapes.find(t=>t===o);e&&o.contentEditable&&(at.current=function(t){var e;const r=t.target,n=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var r=t.getStage().getPointerPosition();return e.point(r)}(r),o=r.textArr,i=Math.floor(n.y/(r.fontSize()*r.lineHeight())),a=o.slice(0,i).reduce((t,e)=>t+e.text.length,i),s=null!==(e=o[i])&&void 0!==e?e:o[0];let l=0;return"right"===r.align()?l=r.width()-s.width:"center"===r.align()&&(l=r.width()/2-s.width/2),a+Math.round((n.x-l)/s.width*s.text.length)}(t),o.toggleEditMode())},lt=!rt&&o.placeholder?.6:o.a.opacity;A(y,lt);const ct=getLineHeight({fontLoaded:nt,fontFamily:o.fontFamily,fontSize:o.a.fontSize,lineHeight:o.lineHeight}),ut=o.selectable||c.role===w.ADMIN,dt=p(o),ft=p(o,o.stroke,"stroke"),ht=n.useMemo(()=>o.backgroundEnabled?o.curveEnabled?function({width:t,height:e,padding:r=0,cornerRadius:n=0}){const o=-r,i=-r,a=t+r,s=e+r,l=f(`M ${o} ${i} L ${a} ${i} L ${a} ${s} L ${o} ${s} Z`);return h(l,n).path}({width:o.a.width,height:o.a.height,cornerRadius:o.backgroundCornerRadius*(o.a.fontSize*ct*.5),padding:o.backgroundPadding*(o.a.fontSize*ct*.5)}):function({lines:t,lineHeight:e,width:r,align:n="left",padding:o=0,cornerRadius:i=0}){const a=m({lines:t,lineHeight:e,width:r,align:n});return g({rects:a,padding:o,cornerRadius:i})}({lines:JSON.parse(JSON.stringify(Q)),cornerRadius:o.backgroundCornerRadius*(o.a.fontSize*ct*.5),lineHeight:ct*o.a.fontSize,padding:o.backgroundPadding*(o.a.fontSize*ct*.5),width:o.a.width,align:o.align}):"",[o.backgroundEnabled,o.curveEnabled,o.backgroundCornerRadius,o.a.fontSize,o.a.height,ct,o.backgroundPadding,o.a.width,o.align,Q]),gt=F();let mt=0;o.curveEnabled||("middle"===o.verticalAlign?mt=(o.a.height-Q.length*ct*o.a.fontSize)/2:"bottom"===o.verticalAlign&&(mt=o.a.height-Q.length*ct*o.a.fontSize));const pt=o.curveEnabled?z(o.a.width,o.a.height,o.curvePower,o.a.fontSize):"",xt=nt?'"'+o.fontFamily+'"':K===o.fontFamily?"Arial":'"'+K+'"',wt=E(rt);return r(e,{children:[t(a,{ref:L,x:o.a.x,y:o.a.y,rotation:o.a.rotation,hideInExport:!o.showInExport,listening:!1,visible:o.backgroundEnabled,opacity:o.backgroundOpacity*lt,data:ht,fill:o.backgroundColor,offsetY:-mt}),t(a,{data:pt,stroke:d.stroke,strokeWidth:1,x:o.a.x,y:o.a.y,rotation:o.a.rotation,visible:!1}),t(l,Object.assign({ref:k,visible:o.curveEnabled,data:pt,text:rt||o.placeholder,listening:!1,align:"center",textBaseline:"middle",direction:wt},dt,ft,{strokeWidth:o.strokeWidth,lineJoin:O(o.strokeLineJoin),fillAfterStrokeEnabled:!0,fontSize:o.a.fontSize,fontFamily:`"${o.fontFamily}", "${K}"`,fontStyle:o.fontStyle+" "+o.fontWeight,textDecoration:o.textDecoration.trim(),letterSpacing:o.letterSpacing*o.a.fontSize,x:o.a.x,y:o.a.y,rotation:o.a.rotation,opacity:o._editModeEnabled?.3:lt,hideInExport:!o.showInExport,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity})),t(s,Object.assign({ref:y,id:o.selectable?o.id:void 0,name:o.selectable?"element":"",hideInExport:!o.showInExport,editModeEnabled:o._editModeEnabled,x:o.a.x,y:o.a.y,rotation:o.a.rotation,width:o.a.width,height:o.a.height,text:rt||o.placeholder,direction:wt},dt,ft,{lineJoin:O(o.strokeLineJoin),strokeWidth:o.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:o.a.fontSize,fontFamily:xt,fontStyle:o.fontStyle+" "+o.fontWeight,textDecoration:o.textDecoration,align:o.align,verticalAlign:o.verticalAlign,draggable:gt?o.draggable&&q:o.draggable,preventDefault:!gt||q,opacity:o.curveEnabled?0:lt,visible:!o._editModeEnabled,ellipsis:"ellipsis"===S.textOverflow,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,lineHeight:ct,letterSpacing:o.letterSpacing*o.a.fontSize,listening:!!o.selectable&&ut,onDragStart:()=>{I(!0)},onDragMove:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{I(!1),o.set({x:t.target.x(),y:t.target.y()})},onClick:st,onTap:st,onTransformStart:()=>{var t,e;D(!0);const r=y.current;N.current=r.height(),J.current=r.rotation(),V.current=r.height();const n=null===(t=r.getStage())||void 0===t?void 0:t.findOne("Transformer");_.current=null!==(e=null==n?void 0:n.getActiveAnchor())&&void 0!==e?e:""},onTransform:t=>{var e,r,n;const i=t.target;null===(e=L.current)||void 0===e||e.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(),e=i.width()*t,r=o.a.fontSize;let n=e;e<r&&(n=r,it.current&&i.position(it.current)),i.width(n),i.scaleX(1),i.scaleY(1);let a=ot();if("ellipsis"===S.textOverflow){a=N.current}else{const t=Math.max(a,N.current);i.height(t),o.set({height:i.height()})}const s=S.textVerticalResizeEnabled?Math.max(a,N.current):ot();o.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:s}),i.skewX(0),i.skewY(0),et()}if("top-center"===a||"bottom-center"===a){const e="resize"===S.textOverflow?ot():ct*o.a.fontSize,r=t.target.height()*t.target.scaleY();if(r<e){if(t.target.height(e),it.current){if("top-center"===_.current){const r=J.current*Math.PI/180,n=V.current-e;t.target.x(it.current.x-n*Math.sin(r)),t.target.y(it.current.y+n*Math.cos(r))}else{t.target.position(it.current)}}}else{t.target.height(r)}t.target.scaleY(1),t.target.scaleX(1),t.target.rotation(J.current),t.target.skewX(0),t.target.skewY(0),V.current=Math.max(e,r)}it.current=t.target.position();const s=t.target.scaleX();null===(n=L.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),o.set({fontSize:o.a.fontSize*s,width:t.target.width()*s,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*s,shadowBlur:o.shadowBlur*s,shadowOffsetX:o.shadowOffsetX*s,shadowOffsetY:o.shadowOffsetY*s,strokeWidth:o.strokeWidth*s})},onTransformEnd:t=>{var e;const r=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),o.set({fontSize:Math.round(o.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:o.shadowBlur*r,shadowOffsetX:o.shadowOffsetX*r,shadowOffsetY:o.shadowOffsetY*r,strokeWidth:o.strokeWidth*r}),null===(e=L.current)||void 0===e||e.setAttrs({scaleX:1,scaleY:1}),D(!1)}})),X&&o.contentEditable&&t(i,{x:o.a.x,y:o.a.y,rotation:o.a.rotation,children:t(P,{textNodeRef:y,element:o,selectAll:Y,cursorPosition:at.current,onBlur:()=>{o.toggleEditMode(!1)}})})]})});
|
package/canvas/tooltip.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e}from"react/jsx-runtime";import n from"react";import{observer as o}from"mobx-react-lite";import{Html as l}from"react-konva-utils";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";import{Navbar as p}from"../primitives/navbar.js";function f(t,e){return t.classList.contains(e)?t:t.parentElement?f(t.parentElement,e):null}const v=()=>null;export const Tooltip=o(({store:o,page:h,components:g,stageRef:b,tooltipSafeArea:y})=>{var E;const x=o.selectedShapes.every(t=>t.page===h),C=n.useRef(null),[k,j]=n.useState(!1),w=o._hasCroppedImages;n.useEffect(()=>{var t,e,n;const o=()=>{j(!0)},l=()=>{j(!1)};null===(t=null==b?void 0:b.current)||void 0===t||t.on("dragstart",o),null===(e=null==b?void 0:b.current)||void 0===e||e.on("dragend",l);const r=null===(n=null==b?void 0:b.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==b?void 0:b.current)||void 0===t||t.off("dragstart",o),null===(e=null==b?void 0:b.current)||void 0===e||e.off("dragend",l),null==r||r.off("transformstart",o),null==r||r.off("transformend",l)}},[]);const[N,I]=n.useState({fit:!0,needCalculate:!1,token:Math.random()});function R(){if(!C.current){return}if(!N.needCalculate){return}const
|
|
1
|
+
import{jsx as t,jsxs as e}from"react/jsx-runtime";import n from"react";import{observer as o}from"mobx-react-lite";import{Html as l}from"react-konva-utils";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";import{Navbar as p}from"../primitives/navbar.js";function f(t,e){return t.classList.contains(e)?t:t.parentElement?f(t.parentElement,e):null}const v=()=>null;export const Tooltip=o(({store:o,page:h,components:g,stageRef:b,tooltipSafeArea:y})=>{var E;const x=o.selectedShapes.every(t=>t.page===h),C=n.useRef(null),[k,j]=n.useState(!1),w=o._hasCroppedImages;n.useEffect(()=>{var t,e,n;const o=()=>{j(!0)},l=()=>{j(!1)};null===(t=null==b?void 0:b.current)||void 0===t||t.on("dragstart",o),null===(e=null==b?void 0:b.current)||void 0===e||e.on("dragend",l);const r=null===(n=null==b?void 0:b.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==b?void 0:b.current)||void 0===t||t.off("dragstart",o),null===(e=null==b?void 0:b.current)||void 0===e||e.off("dragend",l),null==r||r.off("transformstart",o),null==r||r.off("transformend",l)}},[]);const[N,I]=n.useState({fit:!0,needCalculate:!1,token:Math.random()});function R(){var t;if(!C.current){return}if(!N.needCalculate){return}const e=f(C.current,"polotno-workspace-container");if(!e){return}const n=e.getBoundingClientRect(),o=C.current.getBoundingClientRect(),l=o.top-n.top,r=o.bottom-n.top,i=(null==y?void 0:y.top)||0,s=null!==(t=null==y?void 0:y.bottom)&&void 0!==t?t:45,a=null==b?void 0:b.current;let u=-1/0,c=1/0;if(a){const t=a.container().getBoundingClientRect(),e=a.scaleY();u=t.top+a.y()+S.y*e-n.top,c=t.top+a.y()+(S.y+S.height)*e-n.top}const d=l>=20+i&&u-r>=48,m=r-n.height<=-20-s&&l-c>=48;I(d?{fit:!0,needCalculate:!1,token:N.token}:m?{fit:!1,needCalculate:!1,token:N.token}:{fit:N.fit,needCalculate:!1,token:N.token})}if(n.useEffect(()=>{0!==o.selectedElements.length&&I({fit:!0,needCalculate:!0,token:Math.random()})},[o.selectedElements,k,o.scale]),n.useLayoutEffect(()=>{const t=setTimeout(()=>{R()},100);return()=>{clearTimeout(t)}},[N.needCalculate,C.current,N.token]),n.useEffect(()=>{if(!(null==b?void 0:b.current)){return}const t=f(b.current.content,"polotno-workspace-inner");if(!t){return}const e=()=>{o.selectedElements.length&&I({fit:!0,needCalculate:!0,token:Math.random()})};return null==t||t.addEventListener("scroll",e),()=>{null==t||t.removeEventListener("scroll",e)}},[]),0===o.selectedShapes.length){return null}if(k){return null}if(!x){return null}if(o.activePage!==h){return null}if(w){return null}const S=r(o.selectedShapes),T=(null==g?void 0:g.Position)||d,M=(null==g?void 0:g.Duplicate)||u,O=(null==g?void 0:g.Remove)||c,B=(null==g?void 0:g.Group)||m,Y=(null==g?void 0:g.Lock)||v,F=null===(E=o.selectedElements[0])||void 0===E?void 0:E.type,L=Object.assign(Object.assign({},a.aiTextEnabled?{TextAiWrite:s}:{}),g||{}),P=i({components:L,type:F,usedItems:[]});return t(l,{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,n;const o=S.x+S.width/2,l=null===(e=null==b?void 0:b.current)||void 0===e?void 0:e.container(),r=(null==l?void 0:l.getBoundingClientRect())||{left:0,top:0,width:0,height:0,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},i=null==l?void 0:l.closest(".polotno-workspace-container"),s=(null==i?void 0:i.getBoundingClientRect())||{left:0,top:0,width:Number.POSITIVE_INFINITY,height:Number.POSITIVE_INFINITY,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},a=r.left-s.left,u=r.top-s.top,c=C.current?C.current.getBoundingClientRect().height:34,d=((null==y?void 0:y.top)||0)+8,m=u+t.y+S.y*t.scaleY;let p=N.fit;if(p){const t=m-80,e=d+c/2;Math.max(e,t)+c/2>m-48&&(p=!1)}const f=p?S.y*t.scaleY-80:S.y*t.scaleY+S.height*t.scaleY+80;let v=a+t.x+o*t.scaleX,h=v-S.width*t.scaleX/2,g=v+S.width*t.scaleX/2;const E=Math.min(50,S.width/2*t.scaleX),x=g>=E&&h<=s.width-E,k=C.current?C.current.getBoundingClientRect().width:0,j=(null==y?void 0:y.left)||0,w=(null==y?void 0:y.right)||0;if(Number.isFinite(s.width)&&k>0&&x){const t=8+k/2+j,e=s.width-8-k/2-w;e>=t&&(v=Math.max(t,Math.min(v,e)))}g<E&&(v-=k+8),h>s.width-E&&(v+=k+8);let I=u+t.y+f;const R=C.current?C.current.getBoundingClientRect().height:34,T=((null==y?void 0:y.top)||0)+8,M=(null!==(n=null==y?void 0:y.bottom)&&void 0!==n?n:45)+8;return Number.isFinite(s.height)&&(I=Math.max(T+R/2,I),I=Math.min(s.height-M-R/2,I)),Object.assign(Object.assign({},t),{x:v,y:I,scaleX:1,scaleY:1})},divProps:{style:{pointerEvents:"none",position:"absolute",visibility:N.needCalculate?"hidden":"visible",zIndex:9}},children:t("div",{ref:t=>{C.current=t,!C.current&&t&&R()},className:"polotno-selection-tooltip",style:{pointerEvents:"none"},children:e(p,{floating:!0,height:34,className:"pn:gap-0.5 pn:bg-popover pn:px-0.5",style:{transform:"translate(-50%, -50%)",pointerEvents:"auto"},children:[P.map(e=>{const n=L[e];return t(n,{elements:o.selectedElements,element:o.selectedElements[0],store:o},e)}),t(B,{store:o}),t(Y,{store:o}),t(M,{store:o}),t(O,{store:o}),t(T,{store:o})]})})})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"react";import t from"konva";import{isAlive as o}from"mobx-state-tree";import{applyFiltersToCanvas as r,hasActiveFilters as i,getFiltersDepsKey as n}from"./apply-filters.js";import{trySetCanvasSize as s}from"../utils/canvas.js";export const useFilteredSource=(m,a)=>{const c=n(m),f=o(m)&&i(m),d=e=>{if(!a||!o(m)){return}const t=a instanceof HTMLVideoElement?a.videoWidth:a.width,i=a instanceof HTMLVideoElement?a.videoHeight:a.height;if(!t||!i){return}s(e,t,i);const n=e.getContext("2d");n&&(n.drawImage(a,0,0),r(e,m))},u=e.useMemo(()=>{if(!f||!a){return}const e=document.createElement("canvas");return d(e),e},[a,f,c]);return e.useEffect(()=>()=>{u&&t.Util.releaseCanvas(u)},[u]),[u||a||void 0,()=>{u&&d(u)}]};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{
|
|
1
|
+
import e from"react";import{nodeAutorun as r}from"../utils/mobx.js";import{Input as t,UrlSource as n,BufferSource as u,CanvasSink as a,ALL_FORMATS as i}from"mediabunny";import{incrementLoader as c,triggerLoadError as s}from"../utils/loader.js";import{polotnoError as o}from"../utils/errors.js";import{getElementTimeRange as l,getVideoRestMs as d}from"../utils/timeline.js";const f=.05;export const useMediabunnyVideo=(m,p,g)=>{const[h,v]=e.useState({input:null,videoSink:null,duration:0,isReady:!1,error:null});e.useRef(h).current=h;const w=e.useRef(0),b=e.useRef(null),y=e.useRef(null),T=e.useRef(null),R=e.useRef(null),k=e.useRef(null),E=e.useRef(null),S=e.useRef(!1),$=e.useRef(null),x=e.useRef([]),O=e.useRef(null),I=e.useRef(!1),[,j]=e.useReducer(e=>e+1,0);return e.useEffect(()=>{if(!g){return}let e=!0;const r=++w.current;let l=null;return(async()=>{try{if(!e||r!==w.current){return}l=c(`mediabunny init ${m.id}`);const s=await async function(e){if(function(e){return e.startsWith("data:")}(e)){const r=function(e){const r=e.indexOf(",");if(-1===r){throw new Error("Invalid data URL format")}const t=e.slice(r+1),n=atob(t),u=new Uint8Array(n.length);for(let a=0;a<n.length;a++){u[a]=n.charCodeAt(a)}return u.buffer}(e);return new u(r)}if(function(e){return e.startsWith("file://")}(e)){try{const r=await fetch(e),t=await r.arrayBuffer();return new u(t)}catch(r){throw new Error(`Failed to load file URL: ${e}. File URLs may not be supported in this environment. Error: ${r}`)}}return new n(e)}(m.src);if(!e||r!==w.current){return void(l&&(l(),l=null))}const d=new t({source:s,formats:i}),f=await d.computeDuration(),p=await d.getPrimaryVideoTrack();if(!p){throw o("VIDEO_FAILED","No video track found",{reason:"no-video-track"})}if(null===p.codec){throw o("VIDEO_FAILED","Unsupported video codec",{reason:"unsupported-codec"})}if(!await p.canDecode()){throw o("VIDEO_FAILED","Unable to decode the video track",{reason:"cannot-decode"})}const g=await p.canBeTransparent(),h=new a(p,{poolSize:5,fit:"contain",alpha:g});if(!e||r!==w.current){return d.dispose(),void(l&&(l(),l=null))}l&&(l(),l=null),v(e=>Object.assign(Object.assign({},e),{input:d,videoSink:h,duration:f,isReady:!0,error:null}))}catch(d){if(console.error("Failed to initialize mediabunny:",d),l&&(l(),l=null),e&&r===w.current){const e=`Failed to initialize mediabunny for video ${m.id}: ${d}`;s(o("VIDEO_FAILED",e,Object.assign({reason:"load"},null==d?void 0:d.details),d)),v(e=>Object.assign(Object.assign({},e),{error:String(d),isReady:!1}))}}})(),()=>{e=!1,l&&(l(),l=null)}},[m.src,g]),e.useEffect(()=>()=>{y.current&&(y.current.return(),y.current=null),b.current&&(b.current(),b.current=null),T.current=null,R.current=null,k.current=null,S.current=!1,$.current=null,x.current=[],O.current=null,I.current=!1,v({input:null,videoSink:null,duration:0,isReady:!1,error:null})},[g]),e.useEffect(()=>{if(!g||!h.isReady||!h.videoSink){return}const e=++w.current,t="string"==typeof m.src?m.src.slice(0,120):String(m.src),n=(e,r={},n="debug")=>{let u="";try{u=JSON.stringify(Object.assign(Object.assign({},r),{timeCalc:E.current}))}catch(i){u=`[unserializable extras: ${String(i)}]`}const a=`mediabunny event=${e} elementId=${m.id} targetTime=${k.current} duration=${h.duration} lastFrameTimestamp=${R.current} hasIterator=${Boolean(y.current)} prefetchSize=${x.current.length} srcHint=${t} extras=${u}`;"error"===n?console.error(a):"warn"===n?console.warn(a):console.debug(a)},u=e=>{const r=h.duration||0;if(!r||!Number.isFinite(r)){return e}const t=r>f?r-f:r;return Math.max(0,Math.min(e,t))},a=e=>{const r=h.duration||0;return!(!r||!Number.isFinite(r))&&r-e<=.050001000000000004},i=e=>{let r=T.current;r&&r.width===e.canvas.width&&r.height===e.canvas.height||(r||(r=document.createElement("canvas"),T.current=r),r.width=e.canvas.width,r.height=e.canvas.height);const t=r.getContext("2d");t&&(t.clearRect(0,0,r.width,r.height),t.drawImage(e.canvas,0,0)),R.current=e.timestamp},s=e=>{const r=y.current;r&&(I.current||(I.current=!0,O.current=(async()=>{try{for(;x.current.length<4&&e===w.current;){const t=await r.next();if(e!==w.current){return}if(t.done||!t.value){break}x.current.push({timestamp:t.value.timestamp,frame:t.value})}}catch(t){}finally{I.current=!1,O.current=null}})()))},o=e=>{const r=x.current;for(let t=0;t<r.length;t++){if(Math.abs(r[t].timestamp-e)<f){const e=r[t];return x.current=r.slice(t+1),e}}return null},v=()=>{x.current=[]},D=async(e,r,t=0)=>{const c=u(e),l=(e=>{const r=R.current;return null===r||e<r-f||e>r+.5})(c)?"seek":"iterate";try{const t=h.videoSink,u=R.current;if(null!==u&&Math.abs(u-c)<f){return void(k.current=e)}const m=o(c);if(m){return i(m.frame),k.current=e,s(r),void j()}if(O.current){await O.current;const t=o(c);if(t){return i(t.frame),k.current=e,s(r),void j()}}if(v(),"seek"===l){y.current&&(await y.current.return(),y.current=null);const u=t.canvases(c);y.current=u;const o=await u.next();if(r!==w.current){return void(y.current&&(await y.current.return(),y.current=null))}if(o.done||!o.value){if(a(c)||n("iterator_exhausted",{mode:l,requestedTargetTime:e,clampedTargetTime:c},"warn"),r===w.current&&!a(c)){try{y.current&&(await y.current.return(),y.current=null),v();const n=t.canvases(c);y.current=n;const u=await n.next();!u.done&&u.value&&(i(u.value),s(r),k.current=e,j())}catch(d){}}return}i(o.value),s(r)}else{const u=y.current;if(!u){return}let o=!1;for(;r===w.current;){const m=await u.next();if(r!==w.current){break}if(m.done||!m.value){if(a(c)||n("iterator_exhausted",{mode:l,requestedTargetTime:e,clampedTargetTime:c},"warn"),!o&&!a(c)){o=!0;try{y.current&&(await y.current.return(),y.current=null),v();const e=t.canvases(c);y.current=e;const n=await e.next();if(r!==w.current){break}if(n.done||!n.value){break}i(n.value),s(r);break}catch(d){break}}break}const p=m.value;if(i(p),Math.abs(p.timestamp-c)<f){s(r);break}if(p.timestamp>c){s(r);break}}}k.current=e,j()}catch(m){const u=m instanceof Error?{name:m.name,message:m.message,stack:m.stack}:{message:String(m)},a=m instanceof Error?`${m.name}: ${m.message}`:String(m),i=a.includes("Unsupported configuration")||a.includes("isConfigSupported")||a.includes("OperationError");if(n("frame_process_failed",{mode:l,requestedTargetTime:e,clampedTargetTime:c,unsupportedConfigAttempt:t,isUnsupportedConfig:i,error:u},"error"),i&&t<1){try{y.current&&(await y.current.return(),y.current=null),v(),O.current=null,I.current=!1,R.current=null,await D(e,r,t+1)}catch(d){}}}},F=r(m,()=>{const r=h.videoSink,t=h.duration;if(!r||!t){return}const n=m.startTime*t*1e3,a=t*(m.endTime-m.startTime)*1e3,{start:i}=l(m.animations,m.page.duration),s=d(p.currentTime,m.page.startTime,i,a,n,m.speed),o=s/1e3,f=u(o);E.current={pageStartTime:m.page.startTime,storeCurrentTime:p.currentTime,offsetMs:n,durationMs:a,restMs:s,targetTime:o,clampedTargetTime:f,startTime:m.startTime,endTime:m.endTime,videoDuration:t},((e,r)=>{S.current?$.current=e:(S.current=!0,b.current||(b.current=c(`mediabunny video frame ${m.id}`)),(async()=>{let t=e;for(;null!==t&&r===w.current;){await D(t,r),t=$.current,$.current=null}b.current&&(b.current(),b.current=null),S.current=!1})())})(f,e)});return()=>{F(),w.current++,b.current&&(b.current(),b.current=null)}},[g,h.isReady,h.videoSink,h.duration,p,m]),g&&h.isReady?T.current:null};
|
|
@@ -6,7 +6,7 @@ export declare const useCornerRadiusAndCrop: (element: VideoElementType, image:
|
|
|
6
6
|
y: number;
|
|
7
7
|
width: number;
|
|
8
8
|
height: number;
|
|
9
|
-
}, pixelRatio: number, cornerRadius?: number, skipDownscale?: boolean) => readonly [
|
|
9
|
+
}, pixelRatio: number, cornerRadius?: number, skipDownscale?: boolean) => readonly [HTMLVideoElement | HTMLCanvasElement | undefined, () => void];
|
|
10
10
|
type Props = {
|
|
11
11
|
store: StoreType;
|
|
12
12
|
element: VideoElementType;
|
package/canvas/video-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as o}from"mobx-react-lite";import{autorun as n}from"mobx";import{Arc as a,Group as d,Image as h,Rect as s,Text as l,Transformer as c}from"react-konva";import{ROLES as u}from"../model/store.js";import g from"use-image";import f from"konva";import{Portal as m}from"react-konva-utils";import{useWorkspaceStyle as p}from"./workspace-style.js";import{incrementLoader as v,triggerLoadError as w}from"../utils/loader.js";import*as x from"../utils/svg.js";import{flags as M}from"../utils/flags.js";import{applyFilter as y}from"./apply-filters.js";import{useFadeIn as E}from"./use-fadein.js";import{isTouchDevice as b}from"../utils/screen.js";import{useMediabunnyVideo as L}from"./use-mediabunny-video.js";import{getElementTimeRange as T,getVideoRestMs as C}from"../utils/timeline.js";function R(){return document.createElement("canvas")}const S=new window.Image;S.src=x.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" fill="white"/>\n <path d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');const I=new window.Image;I.src=x.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" fill="white"/>\n <path opacity="0.6" d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" fill="white"/>\n <path d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');export const useCornerRadiusAndCrop=(e,t,r,o,n=0,a=!1)=>{var d,h;const s=Math.floor(Math.max(e.width*o,1)),l=Math.floor(Math.max(e.height*o,1)),c=Math.min(n*o,s/2,l/2),u=Math.max(e.width/r.width,e.height/r.height)*o,g=(null===(d=e.page)||void 0===d?void 0:d._exportingOrRendering)&&M.imageDownScalingEnabled&&u<1&&!a,m=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,p=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height,v=0===r.x&&0===r.y&&r.width===m&&r.height===p,w=i.useMemo(()=>{if(t&&m&&p){return v&&0===c&&!g?void 0:R()}},[t,c,g,v,m,p]),x=()=>{if(!w||!t){return}w.width=s,w.height=l;const e=w.getContext("2d");if(!e){return}c&&(e.beginPath(),e.moveTo(c,0),e.lineTo(s-c,0),e.arc(s-c,c,c,3*Math.PI/2,0,!1),e.lineTo(s,l-c),e.arc(s-c,l-c,c,0,Math.PI/2,!1),e.lineTo(c,l),e.arc(c,l-c,c,Math.PI/2,Math.PI,!1),e.lineTo(0,c),e.arc(c,c,c,Math.PI,3*Math.PI/2,!1),e.clip());const i=g?function(e,t){var r,i;const o=R(),n=e instanceof HTMLVideoElement?e.videoWidth:e.width,a=e instanceof HTMLVideoElement?e.videoHeight:e.height;o.width=n,o.height=a,null===(r=o.getContext("2d"))||void 0===r||r.drawImage(e,0,0,o.width,o.height);const d=function(e,t,r,i,o,n,a){for(var d=new ImageData(t,r),h=new Int32Array(e.data.buffer),s=e.width,l=new Int32Array(d.data.buffer),c=d.width,u=t/n,g=r/a,f=Math.round(1/u),m=Math.round(1/g),p=f*m,v=0;v<d.height;v++){for(var w=0;w<c;w++){for(var x=0+Math.round(w/u)+(0+Math.round(v/g))*s,M=0,y=0,E=0,b=0,L=0;L<m;L++){for(var T=0;T<f;T++){var C=h[x+T+L*s];M+=C<<24>>>24,y+=C<<16>>>24,E+=C<<8>>>24,b+=C>>>24}}M=Math.round(M/p),y=Math.round(y/p),E=Math.round(E/p),b=Math.round(b/p),l[w+v*c]=b<<24|E<<16|y<<8|M}}return d}(o.getContext("2d").getImageData(0,0,o.width,o.height),Math.floor(o.width*t),Math.floor(o.height*t),0,0,o.width,o.height);return o.width=Math.floor(o.width*t),o.height=Math.floor(o.height*t),null===(i=o.getContext("2d"))||void 0===i||i.putImageData(d,0,0),o}(t,u):t,o=g?{x:Math.floor(r.x*u),y:Math.floor(r.y*u),width:Math.floor(r.width*u),height:Math.floor(r.height*u)}:r;e.drawImage(i,o.x,o.y,o.width,o.height,0,0,w.width,w.height)};return i.useLayoutEffect(()=>{x()},[w,e.width,e.height,r.x,r.y,r.width,r.height,n,o,a,null===(h=e.page)||void 0===h?void 0:h._exportingOrRendering,g]),i.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&f.Util.releaseCanvas(w)},[w]),[w||t,x]};const k=R(),H=o(({element:r})=>{const o=Math.min(30,r.width/4,r.height/4),n=i.useRef(null);i.useEffect(()=>{const e=n.current;if(!e){return}const t=new f.Animation(t=>{e.rotate(((null==t?void 0:t.timeDiff)||0)/2)},e.getLayer());return t.start(),()=>{t.stop()}});const{mediaLoadingStyle:h}=p();return t(d,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[e(s,{width:r.width,height:r.height,fill:h.fill}),e(a,{ref:n,x:r.width/2,y:r.height/2,fill:h.textFill,outerRadius:Math.abs(o),innerRadius:Math.max(1,o-5),angle:270})]})}),X=o(({element:r})=>{const{mediaErrorStyle:i}=p(),o=Math.max(10,Math.min(30,r.width/25));return t(d,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[e(s,{width:r.width,height:r.height,fill:i.fill}),e(l,{text:"Can not load the video...",fontSize:o,width:r.width,height:r.height,align:"center",fill:i.textFill,verticalAlign:"middle",padding:5})]})});let Y=function(e,t,r){const o=i.useRef("loading"),n=i.useRef(void 0),[a,d]=i.useState(0),h=i.useRef(void 0),s=i.useRef(void 0),l=i.useRef(void 0);return h.current===e&&s.current===t&&l.current===r||(o.current="loading",n.current=void 0,h.current=e,s.current=t,l.current=r),i.useLayoutEffect(function(){if(e){var i=document.createElement("video");return i.addEventListener("canplay",a),i.addEventListener("error",h),t&&(i.crossOrigin=t),r&&(i.referrerPolicy=r),i.src=e,i.load(),function(){i.removeEventListener("canplay",a),i.removeEventListener("error",h)}}function a(){o.current="loaded",n.current=i,n.current.currentTime=0,d(Math.random()),n.current.removeEventListener("canplay",a)}function h(e){var t;const r=4===i.readyState,a=i.buffered&&i.buffered.length>0&&i.buffered.end(i.buffered.length-1)/i.duration*100>=100;if(r&&a){return}const h=e.message||(null===(t=i.error)||void 0===t?void 0:t.message)||"Unknown error",s=new Error("Video failed to load: "+h);console.error(s),o.current="failed",n.current=void 0,d(Math.random())}},[e,t,r]),[n.current,o.current]};export const setVideoLoaderHook=e=>{Y=e};function W(e){return e.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA}export const useLoader=(e,t,r)=>{const o=i.useRef(void 0),n=()=>{var e;null===(e=o.current)||void 0===e||e.call(o),o.current=void 0};i.useEffect(()=>n,[]),i.useLayoutEffect(()=>{const i=t.slice(0,200),a=`video with id ${r} url: ${i}`;"loading"!==e||o.current||(o.current=v(a)),"loading"!==e&&n(),"failed"===e&&w(a)},[e])};export const VideoElement=o(({element:o,store:a})=>{var l,p,w;const[M,O]=i.useState(!1),P=i.useRef(null),_=i.useRef(null),A=o.isSelected,[V,j]=i.useState(!1),[D,z]=Y(o.src,"anonymous"),[B,U]=i.useState(!1),N=a.activePage===o.page,F=(null===(l=o.page)||void 0===l?void 0:l._exportingOrRendering)&&"loaded"===z,Z=L(o,a,F);useLoader(z,o.src,o.id),D&&(D.playsInline=!0);const $=((e,t,r)=>{const o=i.useMemo(()=>{var i,o;const{flipX:n,flipY:a}=e,d="svg"===e.type||e.src.indexOf("data:image/svg+xml")>=0||e.src.indexOf(".svg")>=0,h=navigator.userAgent.toLowerCase().indexOf("firefox")>-1;if(!(n||a||h&&d)){return t}if(!t){return null}const s=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,l=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height;if(!s||!l){return null}const c=R();let u=1;"svg"===e.type&&(u=Math.max(e.width/s*r,e.height/l*r)),c.width=Math.max(s*u,1),c.height=Math.max(l*u,1);let g=n?-c.width:0,f=a?-c.height:0;return null===(i=c.getContext("2d"))||void 0===i||i.scale(n?-1:1,a?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(t,g,f,c.width,c.height),c},[e.flipX,e.flipY,t,e.width,e.height,r]);return i.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&f.Util.releaseCanvas(o)},[o]),o})(o,D,a._elementsPixelRatio),q=F&&Z||$||k;i.useEffect(()=>{D&&a.history.ignore(()=>{o.set({duration:1e3*D.duration})})},[D]),i.useEffect(()=>{var e;if(!D){return}const t=a.animatedElementsIds,r=(!t.length||t.includes(o.id))&&a.isPlaying;if(!N||!r&&!V){return void D.pause()}V&&(D.muted=!1,D.currentTime=o.startTime*D.duration,D.play());const i=new f.Animation(()=>{we.current()},null===(e=P.current)||void 0===e?void 0:e.getLayer());i.start();const n=()=>{j(!1),D.currentTime=o.startTime*D.duration},d=()=>{D.currentTime>=o.endTime*D.duration&&(D.pause(),D.currentTime=o.startTime*D.duration,j(!1))};return D.addEventListener("ended",n),D.addEventListener("timeupdate",d),()=>{D.pause(),i.stop(),D.removeEventListener("ended",n),D.removeEventListener("timeupdate",d)}},[D,V,a.isPlaying,N]),i.useEffect(()=>{D&&(D.volume=o.volume)},[D,o.volume]),i.useEffect(()=>{D&&(D.playbackRate=o.speed,D.preservesPitch=!1)},[D,o.speed]);const G=i.useRef(null);i.useEffect(()=>{const e=n(()=>{var e,t;if(D){if(F&&Z){return ve(),void a.currentTime}const r=a.animatedElementsIds;if(r.length&&!r.includes(o.id)){return}const i=a.activePage===o.page,n=a.currentTime>=o.page.startTime&&a.currentTime<o.page.startTime+o.page.duration,d=o.startTime*D.duration*1e3,h=D.duration*(o.endTime-o.startTime)*1e3,{start:s,end:l}=T(o.animations,o.page.duration),c=(a.currentTime||o.page.startTime)-o.page.startTime,u=n?C(a.currentTime,o.page.startTime,s,h,d,o.speed):0,g=u/1e3,f=n&&c>=s&&c<l;V||(D.muted=!f,f&&a.isPlaying&&i?D.paused?(D.currentTime=g,D.play()):Math.abs(1e3*D.currentTime-u)>500&&(D.currentTime=g):(D.paused||D.pause(),g!==D.currentTime&&(D.currentTime=g),!W(D)&&!a.isPlaying&&!G.current&&(G.current=v(`video ${o.id}`)))),we.current(),null===(t=null===(e=P.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()}});return()=>{e(),G.current&&(G.current(),G.current=null)}},[a,D,F,Z,V]),i.useEffect(()=>{var e,t;if(!D){return}if(F){return null===(e=G.current)||void 0===e||e.call(G),void(G.current=null)}const r=()=>{var e,t,r;!W(D)&&(null===(e=o.page)||void 0===e?void 0:e._exportingOrRendering)||G.current&&(we.current(),null===(r=null===(t=P.current)||void 0===t?void 0:t.getLayer())||void 0===r||r.batchDraw(),G.current(),G.current=null)};let i;return(null===(t=o.page)||void 0===t?void 0:t._exportingOrRendering)&&(i=setInterval(r,20)),D.addEventListener("timeupdate",r),D.addEventListener("canplay",r),()=>{clearInterval(i),D.removeEventListener("timeupdate",r),D.removeEventListener("canplay",r)}},[null===(p=o.page)||void 0===p?void 0:p._exportingOrRendering,D,o.id,v,F]);let{cropX:J,cropY:K,cropWidth:Q,cropHeight:ee}=o;"loaded"!==z&&(J=K=0,Q=ee=1);const te=(re=q)instanceof HTMLVideoElement?re.videoWidth:(null==re?void 0:re.width)||0;var re;const ie=(e=>e instanceof HTMLVideoElement?e.videoHeight:(null==e?void 0:e.height)||0)(q),oe=te*Q,ne=ie*ee,ae=o.width/o.height;let de,he;const se=oe/ne,le="svg"===o.type;le?(de=oe,he=ne):ae>=se?(de=oe,he=oe/ae):(de=ne*ae,he=ne);const ce={x:te*J,y:ie*K,width:de,height:he},ue=null!==(w=o.cornerRadius)&&void 0!==w?w:0,[ge,fe]=useCornerRadiusAndCrop(o,q,ce,a._elementsPixelRatio,ue,!0);let[me,pe]=((e,t,r,o)=>{const n=(e=>{const[t,r]=i.useState(e);return i.useEffect(()=>{(async()=>{const i=await async function(e){if(!(e.indexOf("data:image/svg+xml")>=0||e.indexOf(".svg")>=0)){return e}const t=await x.urlToString(e),r=x.fixSize(t);return x.svgToURL(r)}(e);i!==t&&r(i)})()},[e]),t})(e.clipSrc||""),[a,d]=g(n,"anonymous"),h=e.clipSrc?d:"loaded";useLoader(h,e.clipSrc,e.id);const s=i.useMemo(()=>{if(t&&a){return R()}},[t,a]);function l(){var i;if(!a){return}const o=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,n=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height;if(!t||!o||!n){return}if(!a||!a.width||!a.height){return}if(!s){return}const d=R(),h=Math.max(e.width/a.width*r,e.height/a.height*r);d.width=a.width*h,d.height=a.height*h,null===(i=d.getContext("2d"))||void 0===i||i.drawImage(a,0,0,d.width,d.height),s.width=Math.max(o,1),s.height=Math.max(n,1);const l=s.getContext("2d");l&&(l.save(),l.drawImage(d,0,0,o,n),f.Util.releaseCanvas(d),l.globalCompositeOperation="source-in",l.drawImage(t,0,0,s.width,s.height),l.restore())}return i.useLayoutEffect(()=>{l()},[s,t,a,e.width,e.height,r,...o]),[e.clipSrc&&a?s:t,l]})(o,ge,a._elementsPixelRatio,[ce,ue,a._elementsPixelRatio]);function ve(){var e,t;fe(),pe(),null===(t=null===(e=P.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()}i.useEffect(()=>{ve()});const we=i.useRef(ve);we.current=ve;const xe=Math.max(o.width/de,o.height/he);i.useEffect(()=>{var e;if(!o._cropModeEnabled){return}const t=null===(e=P.current)||void 0===e?void 0:e.getStage();function r(e){o._cropModeEnabled&&e.target!==_.current&&o.toggleCropMode(!1)}function i(e){o._cropModeEnabled&&e.target.parentNode!==(null==t?void 0:t.content)&&o.toggleCropMode(!1)}return document.body.addEventListener("click",i),null==t||t.on("click",r),null==t||t.on("tap",r),()=>{document.body.removeEventListener("click",i),document.body.removeEventListener("touchstart",i),null==t||t.off("click",r),null==t||t.off("click",r)}},[o._cropModeEnabled]),i.useLayoutEffect(()=>{if(!M&&!o._cropModeEnabled){return y(P.current,o),n(()=>{y(P.current,o)},{delay:100})}},[q,M,Q,ee,o._cropModeEnabled]),i.useLayoutEffect(()=>{var e;M||o._cropModeEnabled?null===(e=P.current)||void 0===e||e.clearCache():y(P.current,o)},[M,o.width,o.height,o._cropModeEnabled]),i.useEffect(()=>{y(P.current,o)},[o.shadowEnabled,o.shadowBlur,o.cornerRadius,o.shadowColor,o.shadowOffsetX,o.shadowOffsetY,o.shadowOpacity]);const Me=i.useRef(null),ye=i.useRef(null),Ee=i.useRef(null);i.useLayoutEffect(()=>{o._cropModeEnabled&&(ye.current.nodes([Me.current]),Ee.current.nodes([_.current]))},[o._cropModeEnabled]);const be=e=>{Math.round(e.target.x())>0&&(e.target.x(0),e.target.scaleX(1)),Math.round(e.target.y())>0&&(e.target.y(0),e.target.scaleY(1));const t=e.target.width()*e.target.scaleX(),r=e.target.height()*e.target.scaleY(),i=Math.min(1,de/t),n=Math.min(1,he/r),a=1-i,d=Math.min(a,Math.max(0,Math.round(-e.target.x())/t)),h=1-n,s=Math.min(h,Math.max(0,Math.round(-e.target.y())/r));e.target.setAttrs({x:-d*te,y:-s*ie,scaleX:1,scaleY:1}),o.set({cropX:d,cropY:s,cropWidth:i,cropHeight:n})},Le=()=>{"svg"!==o.type&&o.contentEditable&&setTimeout(()=>{o.toggleCropMode(!0)})},Te="loading"===z,Ce="failed"===z,Re=!Te&&!Ce,Se=i.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Ie=Re?o.a.opacity:0;E(P,Ie);const ke=o.selectable||a.role===u.ADMIN,He=b();return e(r,{children:t(d,{onMouseEnter:()=>U(!0),onMouseLeave:()=>U(!1),children:[Te&&e(H,{element:o}),Ce&&e(X,{element:o}),e(h,{ref:P,name:"element",id:o.id,image:me,x:o.a.x,y:o.a.y,width:o.a.width||1,height:o.a.height||1,rotation:o.a.rotation,opacity:Ie,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,customCrop:ce,listening:ke,draggable:He?o.draggable&&A:o.draggable,preventDefault:!He||A,hideInExport:!o.showInExport,onDragMove:e=>{o.set({x:e.target.x(),y:e.target.y()})},onDragEnd:e=>{o.set({x:e.target.x(),y:e.target.y()})},onDblClick:Le,onDblTap:Le,onTransformStart:()=>{O(!0),Se.current={cropX:o.cropX,cropY:o.cropY,cropWidth:o.cropWidth,cropHeight:o.cropHeight}},onTransform:e=>{var t;const r=e.currentTarget,i=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),n=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const a=null===(t=e.target.getStage())||void 0===t?void 0:t.findOne("Transformer"),d=1-de/te,h=Math.min(d,Math.max(0,o.cropX)),s=1-he/ie,l=Math.min(s,Math.max(0,o.cropY)),c=a.getActiveAnchor(),u=!(c.indexOf("middle")>=0||c.indexOf("center")>=0),g=!u&&i<1&&Se.current.cropHeight>he/ie;let f=u?o.cropWidth:o.cropWidth*i;g&&(f=o.cropWidth);const m=!u&&n<1&&Se.current.cropWidth>de/te;let p=u?o.cropHeight:o.cropHeight*n;m&&(p=o.cropHeight),le&&(f=o.cropWidth,p=o.cropHeight),o.set({cropX:h,cropY:l,x:r.x(),y:r.y(),width:r.width()*i,height:r.height()*n,rotation:e.target.rotation(),cropWidth:Math.min(f,1-h),cropHeight:Math.min(p,1-l)})},onTransformEnd:e=>{const t=e.currentTarget;o.set({width:t.width(),height:t.height(),x:t.x(),y:t.y(),rotation:e.target.rotation(),cropWidth:de/te,cropHeight:he/ie}),O(!1)}}),e(s,{x:o.a.x,y:o.a.y,width:Math.max(o.a.width-o.borderSize,0),height:Math.max(o.a.height-o.borderSize,0),opacity:Ie,offsetX:-o.borderSize/2,offsetY:-o.borderSize/2,stroke:o.borderColor,strokeWidth:o.borderSize,listening:!1,visible:!!o.borderSize,rotation:o.rotation,cornerRadius:Math.max(0,ue-o.borderSize),hideInExport:!o.showInExport}),!a.isPlaying&&e(h,{image:V?B||He?I:void 0:S,x:o.a.x,y:o.a.y,offsetX:-o.a.width/2+15/a.scale,offsetY:-o.a.height/2+15/a.scale,rotation:o.a.rotation,width:30/a.scale,height:30/a.scale,hideInExport:!0,onClick:()=>j(!V),onTap:()=>j(!V)}),o._cropModeEnabled&&t(m,{selector:".page-abs-container",enabled:!0,children:[e(s,{x:-window.innerWidth/a.scale,y:-window.innerWidth/a.scale,width:window.innerWidth/a.scale*3,height:window.innerWidth/a.scale*3,fill:"rgba(0,0,0,0.3)"}),e(h,{listening:!1,image:me,x:o.a.x,y:o.a.y,width:o.a.width,height:o.a.height,rotation:o.a.rotation,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur}),t(d,{x:o.a.x,y:o.a.y,rotation:o.a.rotation,scaleX:xe,scaleY:xe,children:[e(h,{image:q,ref:_,width:te,height:ie,opacity:.4,draggable:!0,x:-o.cropX*te,y:-o.cropY*ie,onDragMove:be,onTransform:be}),e(c,{ref:Ee,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),e(s,{width:de,height:he,ref:Me,listening:!1,onTransform:e=>{e.target.x()<-o.cropX*te-1e-9&&(e.target.x(-o.cropX*te),e.target.scaleX(1)),e.target.y()<-o.cropY*ie-1e-9&&(e.target.y(-o.cropY*ie),e.target.scaleY(1));const t=Math.min(1,Math.max(0,o.cropX+e.target.x()/te)),r=Math.min(1,Math.max(0,e.target.y()/ie+o.cropY)),i=e.target.width()*e.target.scaleX(),n=e.target.height()*e.target.scaleY(),a=Math.min(1-t,i/te),d=Math.min(1-r,n/ie),h=e.target.getAbsolutePosition(e.target.getParent().getParent());e.target.scale({x:1,y:1}),e.target.position({x:0,y:0}),o.set({x:h.x,y:h.y,cropX:t,cropY:r,cropWidth:a,cropHeight:d,width:Math.min(i*xe,te*(1-t)*xe),height:Math.min(n*xe,ie*(1-r)*xe)})}}),e(c,{ref:ye,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2,visible:o.resizable})]})]})]})})});
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as o}from"mobx-react-lite";import{nodeAutorun as n}from"../utils/mobx.js";import{Arc as a,Group as d,Image as h,Rect as s,Text as l,Transformer as c}from"react-konva";import{ROLES as u}from"../model/store.js";import g from"use-image";import m from"konva";import{Portal as f}from"react-konva-utils";import{useWorkspaceStyle as p}from"./workspace-style.js";import{incrementLoader as v,triggerLoadError as w}from"../utils/loader.js";import{polotnoError as x}from"../utils/errors.js";import*as M from"../utils/svg.js";import{flags as y}from"../utils/flags.js";import{useFilteredSource as E}from"./use-filtered-source.js";import{useEvent as b}from"../hooks/use-event.js";import{useFadeIn as L}from"./use-fadein.js";import{isTouchDevice as T}from"../utils/screen.js";import{useMediabunnyVideo as C}from"./use-mediabunny-video.js";import{getElementTimeRange as R,getVideoRestMs as I}from"../utils/timeline.js";function S(){return document.createElement("canvas")}const k=new window.Image;k.src=M.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" fill="white"/>\n <path d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');const H=new window.Image;H.src=M.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" fill="white"/>\n <path opacity="0.6" d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" fill="white"/>\n <path d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');export const useCornerRadiusAndCrop=(e,t,r,o,n=0,a=!1)=>{var d,h;const s=Math.floor(Math.max(e.width*o,1)),l=Math.floor(Math.max(e.height*o,1)),c=Math.min(n*o,s/2,l/2),u=Math.max(e.width/r.width,e.height/r.height)*o,g=(null===(d=e.page)||void 0===d?void 0:d._exportingOrRendering)&&y.imageDownScalingEnabled&&u<1&&!a,f=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,p=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height,v=0===r.x&&0===r.y&&r.width===f&&r.height===p,w=i.useMemo(()=>{if(t&&f&&p){return v&&0===c&&!g?void 0:S()}},[t,c,g,v,f,p]),x=()=>{if(!w||!t){return}w.width=s,w.height=l;const e=w.getContext("2d");if(!e){return}c&&(e.beginPath(),e.moveTo(c,0),e.lineTo(s-c,0),e.arc(s-c,c,c,3*Math.PI/2,0,!1),e.lineTo(s,l-c),e.arc(s-c,l-c,c,0,Math.PI/2,!1),e.lineTo(c,l),e.arc(c,l-c,c,Math.PI/2,Math.PI,!1),e.lineTo(0,c),e.arc(c,c,c,Math.PI,3*Math.PI/2,!1),e.clip());const i=g?function(e,t){var r,i;const o=S(),n=e instanceof HTMLVideoElement?e.videoWidth:e.width,a=e instanceof HTMLVideoElement?e.videoHeight:e.height;o.width=n,o.height=a,null===(r=o.getContext("2d"))||void 0===r||r.drawImage(e,0,0,o.width,o.height);const d=function(e,t,r,i,o,n,a){for(var d=new ImageData(t,r),h=new Int32Array(e.data.buffer),s=e.width,l=new Int32Array(d.data.buffer),c=d.width,u=t/n,g=r/a,m=Math.round(1/u),f=Math.round(1/g),p=m*f,v=0;v<d.height;v++){for(var w=0;w<c;w++){for(var x=0+Math.round(w/u)+(0+Math.round(v/g))*s,M=0,y=0,E=0,b=0,L=0;L<f;L++){for(var T=0;T<m;T++){var C=h[x+T+L*s];M+=C<<24>>>24,y+=C<<16>>>24,E+=C<<8>>>24,b+=C>>>24}}M=Math.round(M/p),y=Math.round(y/p),E=Math.round(E/p),b=Math.round(b/p),l[w+v*c]=b<<24|E<<16|y<<8|M}}return d}(o.getContext("2d").getImageData(0,0,o.width,o.height),Math.floor(o.width*t),Math.floor(o.height*t),0,0,o.width,o.height);return o.width=Math.floor(o.width*t),o.height=Math.floor(o.height*t),null===(i=o.getContext("2d"))||void 0===i||i.putImageData(d,0,0),o}(t,u):t,o=g?{x:Math.floor(r.x*u),y:Math.floor(r.y*u),width:Math.floor(r.width*u),height:Math.floor(r.height*u)}:r;e.drawImage(i,o.x,o.y,o.width,o.height,0,0,w.width,w.height)};return i.useLayoutEffect(()=>{x()},[w,e.width,e.height,r.x,r.y,r.width,r.height,n,o,a,null===(h=e.page)||void 0===h?void 0:h._exportingOrRendering,g]),i.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&m.Util.releaseCanvas(w)},[w]),[w||t,x]};const W=S(),X=o(({element:r})=>{const o=Math.min(30,r.width/4,r.height/4),n=i.useRef(null);i.useEffect(()=>{const e=n.current;if(!e){return}const t=new m.Animation(t=>{e.rotate(((null==t?void 0:t.timeDiff)||0)/2)},e.getLayer());return t.start(),()=>{t.stop()}});const{mediaLoadingStyle:h}=p();return t(d,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[e(s,{width:r.width,height:r.height,fill:h.fill}),e(a,{ref:n,x:r.width/2,y:r.height/2,fill:h.textFill,outerRadius:Math.abs(o),innerRadius:Math.max(1,o-5),angle:270})]})}),Y=o(({element:r})=>{const{mediaErrorStyle:i}=p(),o=Math.max(10,Math.min(30,r.width/25));return t(d,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[e(s,{width:r.width,height:r.height,fill:i.fill}),e(l,{text:"Can not load the video...",fontSize:o,width:r.width,height:r.height,align:"center",fill:i.textFill,verticalAlign:"middle",padding:5})]})});let A=function(e,t,r){const o=i.useRef("loading"),n=i.useRef(void 0),[a,d]=i.useState(0),h=i.useRef(void 0),s=i.useRef(void 0),l=i.useRef(void 0);return h.current===e&&s.current===t&&l.current===r||(o.current="loading",n.current=void 0,h.current=e,s.current=t,l.current=r),i.useLayoutEffect(function(){if(e){var i=document.createElement("video");return i.addEventListener("canplay",a),i.addEventListener("error",h),t&&(i.crossOrigin=t),r&&(i.referrerPolicy=r),i.src=e,i.load(),function(){i.removeEventListener("canplay",a),i.removeEventListener("error",h)}}function a(){o.current="loaded",n.current=i,n.current.currentTime=0,d(Math.random()),n.current.removeEventListener("canplay",a)}function h(e){var t;const r=4===i.readyState,a=i.buffered&&i.buffered.length>0&&i.buffered.end(i.buffered.length-1)/i.duration*100>=100;if(r&&a){return}const h=e.message||(null===(t=i.error)||void 0===t?void 0:t.message)||"Unknown error",s=new Error("Video failed to load: "+h);console.error(s),o.current="failed",n.current=void 0,d(Math.random())}},[e,t,r]),[n.current,o.current]};export const setVideoLoaderHook=e=>{A=e};function O(e){return e.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA}export const useLoader=(e,t,r)=>{const o=i.useRef(void 0),n=()=>{var e;null===(e=o.current)||void 0===e||e.call(o),o.current=void 0};i.useEffect(()=>n,[]),i.useLayoutEffect(()=>{const i=t.slice(0,200),a=`video with id ${r} url: ${i}`;"loading"!==e||o.current||(o.current=v(a)),"loading"!==e&&n(),"failed"===e&&w(x("VIDEO_FAILED",a,{src:i,elementId:r,reason:"load"}))},[e])};export const VideoElement=o(({element:o,store:a})=>{var l,p,w;const[x,y]=i.useState(!1),P=i.useRef(null),_=i.useRef(null),j=o.isSelected,[V,D]=i.useState(!1),[z,B]=A(o.src,"anonymous"),[U,F]=i.useState(!1),N=a.activePage===o.page,Z=(null===(l=o.page)||void 0===l?void 0:l._exportingOrRendering)&&"loaded"===B,$=C(o,a,Z);useLoader(B,o.src,o.id),z&&(z.playsInline=!0);const q=((e,t,r)=>{const o=i.useMemo(()=>{var i,o;const{flipX:n,flipY:a}=e,d="svg"===e.type||e.src.indexOf("data:image/svg+xml")>=0||e.src.indexOf(".svg")>=0,h=navigator.userAgent.toLowerCase().indexOf("firefox")>-1;if(!(n||a||h&&d)){return t}if(!t){return null}const s=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,l=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height;if(!s||!l){return null}const c=S();let u=1;"svg"===e.type&&(u=Math.max(e.width/s*r,e.height/l*r)),c.width=Math.max(s*u,1),c.height=Math.max(l*u,1);let g=n?-c.width:0,m=a?-c.height:0;return null===(i=c.getContext("2d"))||void 0===i||i.scale(n?-1:1,a?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(t,g,m,c.width,c.height),c},[e.flipX,e.flipY,t,e.width,e.height,r]);return i.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&m.Util.releaseCanvas(o)},[o]),o})(o,z,a._elementsPixelRatio),G=Z&&$||q||W,[J=W,K]=E(o,G);i.useEffect(()=>{z&&a.history.ignore(()=>{o.set({duration:1e3*z.duration})})},[z]),i.useEffect(()=>{var e;if(!z){return}const t=a.animatedElementsIds,r=(!t.length||t.includes(o.id))&&a.isPlaying;if(!N||!r&&!V){return void z.pause()}V&&(z.muted=!1,z.currentTime=o.startTime*z.duration,z.play());const i=new m.Animation(()=>{Me()},null===(e=P.current)||void 0===e?void 0:e.getLayer());i.start();const n=()=>{D(!1),z.currentTime=o.startTime*z.duration},d=()=>{z.currentTime>=o.endTime*z.duration&&(z.pause(),z.currentTime=o.startTime*z.duration,D(!1))};return z.addEventListener("ended",n),z.addEventListener("timeupdate",d),()=>{z.pause(),i.stop(),z.removeEventListener("ended",n),z.removeEventListener("timeupdate",d)}},[z,V,a.isPlaying,N]),i.useEffect(()=>{z&&(z.volume=o.volume)},[z,o.volume]),i.useEffect(()=>{z&&(z.playbackRate=o.speed,z.preservesPitch=!1)},[z,o.speed]);const Q=i.useRef(null);i.useEffect(()=>{const e=n(o,()=>{var e,t;if(z){if(Z&&$){return Me(),void a.currentTime}const r=a.animatedElementsIds;if(r.length&&!r.includes(o.id)){return}const i=a.activePage===o.page,n=a.currentTime>=o.page.startTime&&a.currentTime<o.page.startTime+o.page.duration,d=o.startTime*z.duration*1e3,h=z.duration*(o.endTime-o.startTime)*1e3,{start:s,end:l}=R(o.animations,o.page.duration),c=(a.currentTime||o.page.startTime)-o.page.startTime,u=n?I(a.currentTime,o.page.startTime,s,h,d,o.speed):0,g=u/1e3,m=n&&c>=s&&c<l;V||(z.muted=!m,m&&a.isPlaying&&i?z.paused?(z.currentTime=g,z.play()):Math.abs(1e3*z.currentTime-u)>500&&(z.currentTime=g):(z.paused||z.pause(),g!==z.currentTime&&(z.currentTime=g),!O(z)&&!a.isPlaying&&!Q.current&&(Q.current=v(`video ${o.id}`)))),Me(),null===(t=null===(e=P.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()}});return()=>{e(),Q.current&&(Q.current(),Q.current=null)}},[a,z,Z,$,V]),i.useEffect(()=>{var e,t;if(!z){return}if(Z){return null===(e=Q.current)||void 0===e||e.call(Q),void(Q.current=null)}const r=()=>{var e,t,r;!O(z)&&(null===(e=o.page)||void 0===e?void 0:e._exportingOrRendering)||Q.current&&(Me(),null===(r=null===(t=P.current)||void 0===t?void 0:t.getLayer())||void 0===r||r.batchDraw(),Q.current(),Q.current=null)};let i;return(null===(t=o.page)||void 0===t?void 0:t._exportingOrRendering)&&(i=setInterval(r,20)),z.addEventListener("timeupdate",r),z.addEventListener("canplay",r),()=>{clearInterval(i),z.removeEventListener("timeupdate",r),z.removeEventListener("canplay",r)}},[null===(p=o.page)||void 0===p?void 0:p._exportingOrRendering,z,o.id,v,Z]);let{cropX:ee,cropY:te,cropWidth:re,cropHeight:ie}=o;"loaded"!==B&&(ee=te=0,re=ie=1);const oe=(ne=J)instanceof HTMLVideoElement?ne.videoWidth:(null==ne?void 0:ne.width)||0;var ne;const ae=(e=>e instanceof HTMLVideoElement?e.videoHeight:(null==e?void 0:e.height)||0)(J),de=oe*re,he=ae*ie,se=o.width/o.height;let le,ce;const ue=de/he,ge="svg"===o.type;ge?(le=de,ce=he):se>=ue?(le=de,ce=de/se):(le=he*se,ce=he);const me={x:oe*ee,y:ae*te,width:le,height:ce},fe=null!==(w=o.cornerRadius)&&void 0!==w?w:0,[pe,ve]=useCornerRadiusAndCrop(o,J,me,a._elementsPixelRatio,fe,!0);let[we,xe]=((e,t,r,o)=>{const n=(e=>{const[t,r]=i.useState(e);return i.useEffect(()=>{(async()=>{const i=await async function(e){if(!(e.indexOf("data:image/svg+xml")>=0||e.indexOf(".svg")>=0)){return e}const t=await M.urlToString(e),r=M.fixSize(t);return M.svgToURL(r)}(e);i!==t&&r(i)})()},[e]),t})(e.clipSrc||""),[a,d]=g(n,"anonymous"),h=e.clipSrc?d:"loaded";useLoader(h,e.clipSrc,e.id);const s=i.useMemo(()=>{if(t&&a){return S()}},[t,a]);function l(){var i;if(!a){return}const o=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,n=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height;if(!t||!o||!n){return}if(!a||!a.width||!a.height){return}if(!s){return}const d=S(),h=Math.max(e.width/a.width*r,e.height/a.height*r);d.width=a.width*h,d.height=a.height*h,null===(i=d.getContext("2d"))||void 0===i||i.drawImage(a,0,0,d.width,d.height),s.width=Math.max(o,1),s.height=Math.max(n,1);const l=s.getContext("2d");l&&(l.save(),l.drawImage(d,0,0,o,n),m.Util.releaseCanvas(d),l.globalCompositeOperation="source-in",l.drawImage(t,0,0,s.width,s.height),l.restore())}return i.useLayoutEffect(()=>{l()},[s,t,a,e.width,e.height,r,...o]),[e.clipSrc&&a?s:t,l]})(o,pe,a._elementsPixelRatio,[me,fe,a._elementsPixelRatio]);const Me=b(()=>{var e,t;K(),ve(),xe(),null===(t=null===(e=P.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()});i.useEffect(()=>{Me()});const ye=Math.max(o.width/le,o.height/ce);i.useEffect(()=>{var e;if(!o._cropModeEnabled){return}const t=null===(e=P.current)||void 0===e?void 0:e.getStage();function r(e){o._cropModeEnabled&&e.target!==_.current&&o.toggleCropMode(!1)}function i(e){o._cropModeEnabled&&e.target.parentNode!==(null==t?void 0:t.content)&&o.toggleCropMode(!1)}return document.body.addEventListener("click",i),null==t||t.on("click",r),null==t||t.on("tap",r),()=>{document.body.removeEventListener("click",i),document.body.removeEventListener("touchstart",i),null==t||t.off("click",r),null==t||t.off("click",r)}},[o._cropModeEnabled]);const Ee=i.useRef(null),be=i.useRef(null),Le=i.useRef(null);i.useLayoutEffect(()=>{o._cropModeEnabled&&(be.current.nodes([Ee.current]),Le.current.nodes([_.current]))},[o._cropModeEnabled]);const Te=e=>{Math.round(e.target.x())>0&&(e.target.x(0),e.target.scaleX(1)),Math.round(e.target.y())>0&&(e.target.y(0),e.target.scaleY(1));const t=e.target.width()*e.target.scaleX(),r=e.target.height()*e.target.scaleY(),i=Math.min(1,le/t),n=Math.min(1,ce/r),a=1-i,d=Math.min(a,Math.max(0,Math.round(-e.target.x())/t)),h=1-n,s=Math.min(h,Math.max(0,Math.round(-e.target.y())/r));e.target.setAttrs({x:-d*oe,y:-s*ae,scaleX:1,scaleY:1}),o.set({cropX:d,cropY:s,cropWidth:i,cropHeight:n})},Ce=()=>{"svg"!==o.type&&o.contentEditable&&setTimeout(()=>{o.toggleCropMode(!0)})},Re="loading"===B,Ie="failed"===B,Se=!Re&&!Ie,ke=i.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),He=Se?o.a.opacity:0;L(P,He);const We=o.selectable||a.role===u.ADMIN,Xe=T();return e(r,{children:t(d,{onMouseEnter:()=>F(!0),onMouseLeave:()=>F(!1),children:[Re&&e(X,{element:o}),Ie&&e(Y,{element:o}),e(h,{ref:P,name:"element",id:o.id,image:we,x:o.a.x,y:o.a.y,width:o.a.width||1,height:o.a.height||1,rotation:o.a.rotation,opacity:He,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,customCrop:me,listening:We,draggable:Xe?o.draggable&&j:o.draggable,preventDefault:!Xe||j,hideInExport:!o.showInExport,onDragMove:e=>{o.set({x:e.target.x(),y:e.target.y()})},onDragEnd:e=>{o.set({x:e.target.x(),y:e.target.y()})},onDblClick:Ce,onDblTap:Ce,onTransformStart:()=>{y(!0),ke.current={cropX:o.cropX,cropY:o.cropY,cropWidth:o.cropWidth,cropHeight:o.cropHeight}},onTransform:e=>{var t;const r=e.currentTarget,i=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),n=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const a=null===(t=e.target.getStage())||void 0===t?void 0:t.findOne("Transformer"),d=1-le/oe,h=Math.min(d,Math.max(0,o.cropX)),s=1-ce/ae,l=Math.min(s,Math.max(0,o.cropY)),c=a.getActiveAnchor(),u=!(c.indexOf("middle")>=0||c.indexOf("center")>=0),g=!u&&i<1&&ke.current.cropHeight>ce/ae;let m=u?o.cropWidth:o.cropWidth*i;g&&(m=o.cropWidth);const f=!u&&n<1&&ke.current.cropWidth>le/oe;let p=u?o.cropHeight:o.cropHeight*n;f&&(p=o.cropHeight),ge&&(m=o.cropWidth,p=o.cropHeight),o.set({cropX:h,cropY:l,x:r.x(),y:r.y(),width:r.width()*i,height:r.height()*n,rotation:e.target.rotation(),cropWidth:Math.min(m,1-h),cropHeight:Math.min(p,1-l)})},onTransformEnd:e=>{const t=e.currentTarget;o.set({width:t.width(),height:t.height(),x:t.x(),y:t.y(),rotation:e.target.rotation(),cropWidth:le/oe,cropHeight:ce/ae}),y(!1)}}),e(s,{x:o.a.x,y:o.a.y,width:Math.max(o.a.width-o.borderSize,0),height:Math.max(o.a.height-o.borderSize,0),opacity:He,offsetX:-o.borderSize/2,offsetY:-o.borderSize/2,stroke:o.borderColor,strokeWidth:o.borderSize,listening:!1,visible:!!o.borderSize,rotation:o.rotation,cornerRadius:Math.max(0,fe-o.borderSize),hideInExport:!o.showInExport}),!a.isPlaying&&e(h,{image:V?U||Xe?H:void 0:k,x:o.a.x,y:o.a.y,offsetX:-o.a.width/2+15/a.scale,offsetY:-o.a.height/2+15/a.scale,rotation:o.a.rotation,width:30/a.scale,height:30/a.scale,hideInExport:!0,onClick:()=>D(!V),onTap:()=>D(!V)}),o._cropModeEnabled&&t(f,{selector:".page-abs-container",enabled:!0,children:[e(s,{x:-window.innerWidth/a.scale,y:-window.innerWidth/a.scale,width:window.innerWidth/a.scale*3,height:window.innerWidth/a.scale*3,fill:"rgba(0,0,0,0.3)"}),e(h,{listening:!1,image:we,x:o.a.x,y:o.a.y,width:o.a.width,height:o.a.height,rotation:o.a.rotation,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur}),t(d,{x:o.a.x,y:o.a.y,rotation:o.a.rotation,scaleX:ye,scaleY:ye,children:[e(h,{image:J,ref:_,width:oe,height:ae,opacity:.4,draggable:!0,x:-o.cropX*oe,y:-o.cropY*ae,onDragMove:Te,onTransform:Te}),e(c,{ref:Le,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),e(s,{width:le,height:ce,ref:Ee,listening:!1,onTransform:e=>{e.target.x()<-o.cropX*oe-1e-9&&(e.target.x(-o.cropX*oe),e.target.scaleX(1)),e.target.y()<-o.cropY*ae-1e-9&&(e.target.y(-o.cropY*ae),e.target.scaleY(1));const t=Math.min(1,Math.max(0,o.cropX+e.target.x()/oe)),r=Math.min(1,Math.max(0,e.target.y()/ae+o.cropY)),i=e.target.width()*e.target.scaleX(),n=e.target.height()*e.target.scaleY(),a=Math.min(1-t,i/oe),d=Math.min(1-r,n/ae),h=e.target.getAbsolutePosition(e.target.getParent().getParent());e.target.scale({x:1,y:1}),e.target.position({x:0,y:0}),o.set({x:h.x,y:h.y,cropX:t,cropY:r,cropWidth:a,cropHeight:d,width:Math.min(i*ye,oe*(1-t)*ye),height:Math.min(n*ye,ae*(1-r)*ye)})}}),e(c,{ref:be,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2,visible:o.resizable})]})]})]})})});
|
|
@@ -47,6 +47,7 @@ export type WorkspaceProps = {
|
|
|
47
47
|
rulerTickSize?: number;
|
|
48
48
|
components?: any;
|
|
49
49
|
onKeyDown?: (e: KeyboardEvent, store: StoreType) => void;
|
|
50
|
+
onPaste?: (e: ClipboardEvent, store: StoreType) => void;
|
|
50
51
|
paddingX?: number;
|
|
51
52
|
paddingY?: number;
|
|
52
53
|
pageGap?: number;
|
|
@@ -62,7 +63,7 @@ export type WorkspaceProps = {
|
|
|
62
63
|
right?: number;
|
|
63
64
|
};
|
|
64
65
|
};
|
|
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, groupSelectionMode, visiblePagesOffset, renderOnlyActivePage, scrollToPageThreshold, tooltipSafeArea, }: WorkspaceProps) => React.JSX.Element) & {
|
|
66
|
+
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, onPaste, paddingX, paddingY, pageGap, altCloneEnabled, groupSelectionMode, visiblePagesOffset, renderOnlyActivePage, scrollToPageThreshold, tooltipSafeArea, }: WorkspaceProps) => React.JSX.Element) & {
|
|
66
67
|
displayName: string;
|
|
67
68
|
};
|
|
68
69
|
export default WorkspaceCanvas;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import r from"react";import{observer as o}from"mobx-react-lite";import n from"./page.js";import{TopRules as l}from"./rules.js";import{AudioElement as i}from"./audio.js";import{handleHotkey as s}from"./hotkeys.js";import{t as a}from"../utils/l10n.js";import{WorkspaceStyleProvider as c,useResolvedWorkspaceStyle as u}from"./workspace-style.js";const d=(e,t,r)=>Math.max(t,Math.min(r,e)),h=(e,t)=>Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2)),g=({store:r})=>t("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"},children:[e("p",{children:a("workspace.noPages")}),e("button",{onClick:()=>{r.addPage()},children:a("workspace.addPage")})]}),p=({width:t,height:r,xPadding:o,yPadding:n,backgroundColor:l})=>e("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:o+"px",paddingRight:o+"px",paddingTop:n+"px",paddingBottom:n+"px",flexShrink:0},children:e("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}})});export const WorkspaceCanvas=o(({store:o,layout:a="vertical",pageControlsEnabled:f,backgroundColor:m,transparencyBackgroundColor:v,pageBorderColor:x,activePageBorderColor:y,bleedColor:w,snapGuideStroke:T,snapGuideStrokeWidth:b,snapGuideDash:k,selectionRectFill:S,selectionRectStroke:L,selectionRectStrokeWidth:M,transformLabelFill:C,transformLabelTextFill:E,cropOverlayFill:P,transformerStyle:R,innerImageCropTransformerStyle:F,outerImageCropTransformerStyle:W,highlighterStyle:B,mediaLoadingStyle:O,mediaErrorStyle:z,textOverflowIndicatorStyle:j,distanceGuideStroke:N,distanceLabelFill:H,distanceLabelTextFill:G,rulerBackgroundColor:I,rulerTextColor:_,rulerBorderColor:Y,rulerBorderSize:D,rulerTickColor:X,rulerTickSize:A,components:K,onKeyDown:q,paddingX:V,paddingY:J,pageGap:Q,altCloneEnabled:U=!0,groupSelectionMode:Z="drill",visiblePagesOffset:$,renderOnlyActivePage:ee,scrollToPageThreshold:te=.5,tooltipSafeArea:re})=>{var oe;const ne="horizontal"===a,le=null!=V?V:20,ie=null!=J?J:55,[se,ae]=r.useState({width:100,height:100}),ce=r.useRef(se),ue=r.useRef(null),de=r.useRef(null),he=r.useRef(0);let ge=0,pe=0,fe=0,me=0;if(o.bleedVisible){for(const e of o.pages){const t=e.computedBleed;ge=Math.max(ge,t.left),pe=Math.max(pe,t.right),fe=Math.max(fe,t.top),me=Math.max(me,t.bottom)}}const ve=Math.max(...o.pages.map(e=>e.computedWidth)),xe=Math.max(...o.pages.map(e=>e.computedHeight)),ye=(null===(oe=o.activePage)||void 0===oe?void 0:oe.computedHeight)||0,we=ve+ge+pe,Te=(ee?ye:xe)+fe+me,be=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===ue.current){return}if(!Number.isFinite(we)||!Number.isFinite(Te)){return}const t=ue.current.getBoundingClientRect();0!==t.width&&0!==t.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(ue.current));const r=de.current.clientWidth||t.width,n={width:r,height:t.height};(ce.current.width!==n.width||ce.current.height!==n.height)&&(ae(n),ce.current=n);const l=(r-2*le)/we,i=o.pages.length>1?3.1:2,s=(t.height-ie*i)/Te,a=o.pages.length>1?3.1:2,c=(r-le*a)/we,u=(t.height-2*ie)/Te,d=o.pages.length?Math.max(Math.min(ne?c:l,ne?u:s),.01):1;o.scaleToFit!==d&&(o.setScale(d),o._setScaleToFit(d))};r.useLayoutEffect(()=>{be({skipTimeout:!0})},[]),r.useEffect(()=>{be()},[we,Te,J,V]),r.useLayoutEffect(()=>{be({skipTimeout:!0})},[o.openedSidePanel]),r.useEffect(()=>{o.__()},[]),r.useEffect(()=>{const e=ue.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{be({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{be({skipTimeout:!0})},100);return()=>clearInterval(e)}},[we,Te]);const ke=ee?1:o.pages.length;let Se,Le;if(ne){const e=we*o.scale*ke;Se=Math.max(le,(se.width-e)/ke/2),Le=Math.max(ie,(se.height-Te*o.scale)/2)}else{Se=Math.max(le,(se.width-we*o.scale)/2);const e=Te*o.scale*ke;Le=Math.max(ie,(se.height-e)/ke/2)}Number.isNaN(Se)&&(Se=le),Number.isNaN(Le)&&(Le=ie),r.useEffect(()=>{const e=e=>{(q||s)(e,o)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),r.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const t=Math.max(5,o.scaleToFit);let r=Math.min(.1,o.scaleToFit);ne&&we>0&&Number.isFinite(we)&&(r=Math.max(r,300/we)),r=Math.max(r,.01);const n=.03,l=d(e.deltaY<0?o.scale*(1+n):o.scale/(1+n),r,t);return void o.setScale(l)}},t=de.current;return null==t||t.addEventListener("wheel",e),()=>null==t?void 0:t.removeEventListener("wheel",e)},[ne,we,o]),r.useEffect(()=>{const e=de.current;if(!e){return}const t=e=>{2===e.touches.length&&(he.current=h(e.touches[0],e.touches[1]))},r=t=>{if(2===t.touches.length&&he.current>0){t.preventDefault();const r=h(t.touches[0],t.touches[1]),n=r/he.current,l=Math.max(5,o.scaleToFit);let i=Math.min(.1,o.scaleToFit);ne&&we>0&&Number.isFinite(we)&&(i=Math.max(i,300/we)),i=Math.max(i,.01);const s=o.scale,a=d(s*n,i,l),c=a/s,u=e.getBoundingClientRect(),g=(t.touches[0].clientX+t.touches[1].clientX)/2-u.left,p=(t.touches[0].clientY+t.touches[1].clientY)/2-u.top,f=e.scrollLeft+g,m=e.scrollTop+p;We.current=!0,o.setScale(a),e.scrollLeft=f*c-g,e.scrollTop=m*c-p,he.current=r}},n=()=>{he.current=0};return e.addEventListener("touchstart",t,{passive:!0}),e.addEventListener("touchmove",r,{passive:!1}),e.addEventListener("touchend",n,{passive:!0}),()=>{e.removeEventListener("touchstart",t),e.removeEventListener("touchmove",r),e.removeEventListener("touchend",n)}},[ne,we,o]);const Me=void 0!==Q,Ce=o.pages.map(e=>{if(ne){const t=(e.computedWidth+ge+pe)*o.scale;return Me?t+Q:t+2*Se}{const t=(e.computedHeight+fe+me)*o.scale;return Me?t+Q:t+2*Le}}),Ee=[];let Pe=Me?ne?Se:Le:0;for(let e=0;e<Ce.length;e++){Ee.push(Pe),Pe+=Ce[e]}const Re=Ce.reduce((e,t)=>e+t,0),Fe=Me?Re+(ne?2*Se:2*Le):Re,We=r.useRef(!1),[,Be]=r.useReducer(e=>e+1,0);((e,t,o,n,l)=>{const i=r.useRef(0),s=r.useRef(0),a=r.useRef(null),c=r.useRef(null),u=r.useRef(!1),h=r.useRef(n.pages.length);u.current=h.current!==n.pages.length,h.current=n.pages.length,r.useEffect(()=>{const t=e.current,r=()=>{i.current=t.scrollLeft,s.current=t.scrollTop,a.current=t.scrollWidth,c.current=t.scrollHeight};return t.addEventListener("scroll",r),r(),()=>{t.removeEventListener("scroll",r)}},[]),r.useLayoutEffect(()=>{if(!e.current){return}if(u.current){const t=e.current;return a.current=t.scrollWidth,c.current=t.scrollHeight,i.current=t.scrollLeft,void(s.current=t.scrollTop)}const t=e.current,r=a.current,o=c.current;if(null===r||null===o){return a.current=t.scrollWidth,c.current=t.scrollHeight,i.current=t.scrollLeft,void(s.current=t.scrollTop)}l.current=!0;const n=t.offsetWidth,h=t.offsetHeight,g=(i.current+n/2)/r,p=(s.current+h/2)/o,f=Math.max(0,t.scrollWidth-n),m=Math.max(0,t.scrollHeight-h);t.scrollLeft=d(g*t.scrollWidth-n/2,0,f),t.scrollTop=d(p*t.scrollHeight-h/2,0,m),a.current=t.scrollWidth,c.current=t.scrollHeight,i.current=t.scrollLeft,s.current=t.scrollTop},[o,t])})(de,Fe,o.scale,o,We);const{handleScroll:Oe}=((e,t,o,n,l,i,s,a,c,u)=>{const d=r.useRef(!1),h=r.useRef(null),g=r.useRef(!1),p="horizontal"===c;r.useEffect(()=>{const t=e.current,r=()=>{s.current};return t.addEventListener("scroll",r),()=>{t.removeEventListener("scroll",r)}},[]);const f=n.pages.indexOf(n.activePage);return r.useLayoutEffect(()=>{if(a){return}if(!n.activePage){return}if(!e.current){return}if(d.current){return}const r=e.current,i=n.pages.indexOf(n.activePage),s=t[i]||0,c=p?r.scrollLeft:r.scrollTop,h=p?r.scrollWidth-r.clientWidth:r.scrollHeight-r.clientHeight,f=Math.min(s,Math.max(0,h)),m=o[i]||o[0]||0;let v=()=>{};return(Math.abs(f-c)>m*l||g.current)&&(g.current=!0,v=(({element:e,scrollTop:t,scrollLeft:r,duration:o=300,onFinish:n=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,s=l?t:r,a=s-i;let c=0,u=!1;if(0===o){return l?e.scrollTop=s:e.scrollLeft=s,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,a,o);l?e.scrollTop=t:e.scrollLeft=t,c<o?setTimeout(d,20):n()},h=(e,t,r,o)=>(e/=o/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:r},p?{scrollLeft:f}:{scrollTop:f}),{onFinish:()=>{g.current=!1,null==u||u()},duration:n.isPlaying?0:300}))),v},[n.activePage,f,n.isPlaying,a,c,t,o]),{handleScroll:e=>{if(a){return}if(g.current){return}d.current=!0,clearTimeout(h.current),h.current=setTimeout(()=>{d.current=!1},300);const r=(p?e.currentTarget.scrollLeft:e.currentTarget.scrollTop)+(p?i.width:i.height)/3;let o=0;for(let n=t.length-1;n>=0;n--){if(r>=t[n]){o=n;break}}const l=n.pages[o];l&&n.activePage!==l&&l.select()}}})(de,Ee,Ce,o,te,se,We,ee,a,Be),ze=se.width>=we*o.scale+2*Se,je=se.height>=Te*o.scale+2*Le,Ne=m||"rgba(232, 232, 232, 0.9)",He=(null==K?void 0:K.NoPages)||g,Ge=ne?se.width:se.height,Ie=de.current?ne?de.current.scrollLeft:de.current.scrollTop:0,_e=e=>{for(let t=Ee.length-1;t>=0;t--){if(e>=Ee[t]){return t}}return 0},Ye=Math.max(0,_e(Ie)),De=Math.min(o.pages.length-1,_e(Ie+Ge)),Xe=null!=$?$:1,Ae=Math.max(0,Ye-Xe),Ke=Math.min(o.pages.length-1,De+Xe),qe=u({cropOverlayFill:P,workspaceBackgroundColor:m,pageBorderColor:x,activePageBorderColor:y,bleedColor:w,transparencyBackgroundColor:v,transformerStyle:R,innerImageCropTransformerStyle:F,outerImageCropTransformerStyle:W,highlighterStyle:B,snapGuideStroke:T,snapGuideStrokeWidth:b,snapGuideDash:k,selectionRectFill:S,selectionRectStroke:L,selectionRectStrokeWidth:M,transformLabelFill:C,transformLabelTextFill:E,distanceGuideStroke:N,distanceLabelFill:H,distanceLabelTextFill:G,mediaLoadingStyle:O,mediaErrorStyle:z,textOverflowIndicatorStyle:j,rulerBackgroundColor:I,rulerTextColor:_,rulerBorderColor:Y,rulerBorderSize:D,rulerTickColor:X,rulerTickSize:A});return e(c,{value:qe,children:e("div",{ref:ue,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:Ne,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container",children:t("div",{ref:de,onScroll:Oe,style:Object.assign({position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:ne?"row":"column",overflow:"auto",overflowX:ne?"auto":ze?"hidden":"auto",overflowY:ne&&je?"hidden":"auto"},Me&&{paddingTop:ne?0:Le,paddingBottom:ne?0:Le,paddingLeft:ne?Se:0,paddingRight:ne?Se:0,boxSizing:"border-box"}),className:"polotno-workspace-inner",children:[o.pages.map((t,r)=>{const l=t===o.activePage;if(ee&&!l&&!t._exportingOrRendering&&!t._forceMount){return null}const i=l||r>=Ae&&r<=Ke||t._exportingOrRendering||t._forceMount,s=ne?Ce[r]:we*o.scale+2*Se,c=ne?Te*o.scale+2*Le:Ce[r];if(!i){return e("div",{style:{flexShrink:0},children:e(p,{width:s,height:c,backgroundColor:Ne,xPadding:Se,yPadding:Le})},t.id)}const u=e(n,{page:t,xPadding:Se,yPadding:Le,width:s,height:c,store:o,pageControlsEnabled:f,altCloneEnabled:U,groupSelectionMode:Z,components:K,viewportSize:se,layout:a,tooltipSafeArea:re},t.id);return(t._exportingOrRendering||t._forceMount)&&!l&&ee?e("div",{style:{display:"none",flexShrink:0},children:u},t.id):u}),o.rulesVisible&&e(l,{store:o,xPadding:Se,yPadding:Le,width:we*o.scale+2*Se,height:Te*o.scale+2*Le,pageSizes:Ce,layout:a,renderOnlyActivePage:ee}),0===o.pages.length&&e(He,{store:o}),o.audios.map(t=>e(i,{audio:t,store:o},t.id))]})})})});export default WorkspaceCanvas;
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import r from"react";import{observer as o}from"mobx-react-lite";import n from"./page.js";import{TopRules as l}from"./rules.js";import{AudioElement as i}from"./audio.js";import{handleHotkey as s,handleCopyEvent as a,handleCutEvent as c,handlePasteEvent as u}from"./hotkeys.js";import{t as d}from"../utils/l10n.js";import{WorkspaceStyleProvider as h,useResolvedWorkspaceStyle as g}from"./workspace-style.js";const p=(e,t,r)=>Math.max(t,Math.min(r,e)),f=(e,t)=>Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2)),m=({store:r})=>t("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"},children:[e("p",{children:d("workspace.noPages")}),e("button",{onClick:()=>{r.addPage()},children:d("workspace.addPage")})]}),v=({width:t,height:r,xPadding:o,yPadding:n,backgroundColor:l})=>e("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:o+"px",paddingRight:o+"px",paddingTop:n+"px",paddingBottom:n+"px",flexShrink:0},children:e("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}})});export const WorkspaceCanvas=o(({store:o,layout:d="vertical",pageControlsEnabled:w,backgroundColor:x,transparencyBackgroundColor:y,pageBorderColor:L,activePageBorderColor:T,bleedColor:b,snapGuideStroke:k,snapGuideStrokeWidth:S,snapGuideDash:E,selectionRectFill:M,selectionRectStroke:C,selectionRectStrokeWidth:P,transformLabelFill:R,transformLabelTextFill:F,cropOverlayFill:W,transformerStyle:B,innerImageCropTransformerStyle:O,outerImageCropTransformerStyle:z,highlighterStyle:j,mediaLoadingStyle:N,mediaErrorStyle:H,textOverflowIndicatorStyle:G,distanceGuideStroke:I,distanceLabelFill:_,distanceLabelTextFill:Y,rulerBackgroundColor:D,rulerTextColor:X,rulerBorderColor:A,rulerBorderSize:K,rulerTickColor:q,rulerTickSize:V,components:J,onKeyDown:Q,onPaste:U,paddingX:Z,paddingY:$,pageGap:ee,altCloneEnabled:te=!0,groupSelectionMode:re="drill",visiblePagesOffset:oe,renderOnlyActivePage:ne,scrollToPageThreshold:le=.5,tooltipSafeArea:ie})=>{var se;const ae="horizontal"===d,ce=null!=Z?Z:20,ue=null!=$?$:55,[de,he]=r.useState({width:100,height:100}),ge=r.useRef(de),pe=r.useRef(null),fe=r.useRef(null),me=r.useRef(0);let ve=0,we=0,xe=0,ye=0;if(o.bleedVisible){for(const e of o.pages){const t=e.computedBleed;ve=Math.max(ve,t.left),we=Math.max(we,t.right),xe=Math.max(xe,t.top),ye=Math.max(ye,t.bottom)}}const Le=Math.max(...o.pages.map(e=>e.computedWidth)),Te=Math.max(...o.pages.map(e=>e.computedHeight)),be=(null===(se=o.activePage)||void 0===se?void 0:se.computedHeight)||0,ke=Le+ve+we,Se=(ne?be:Te)+xe+ye,Ee=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===pe.current){return}if(!Number.isFinite(ke)||!Number.isFinite(Se)){return}const t=pe.current.getBoundingClientRect();0!==t.width&&0!==t.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(pe.current));const r=fe.current.clientWidth||t.width,n={width:r,height:t.height};(ge.current.width!==n.width||ge.current.height!==n.height)&&(he(n),ge.current=n);const l=(r-2*ce)/ke,i=o.pages.length>1?3.1:2,s=(t.height-ue*i)/Se,a=o.pages.length>1?3.1:2,c=(r-ce*a)/ke,u=(t.height-2*ue)/Se,d=o.pages.length?Math.max(Math.min(ae?c:l,ae?u:s),.01):1;o.scaleToFit!==d&&(o.setScale(d),o._setScaleToFit(d))};r.useLayoutEffect(()=>{Ee({skipTimeout:!0})},[]),r.useEffect(()=>{Ee()},[ke,Se,$,Z]),r.useLayoutEffect(()=>{Ee({skipTimeout:!0})},[o.openedSidePanel]),r.useEffect(()=>{o.__()},[]),r.useEffect(()=>{const e=pe.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{Ee({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{Ee({skipTimeout:!0})},100);return()=>clearInterval(e)}},[ke,Se]);const Me=ne?1:o.pages.length;let Ce,Pe;if(ae){const e=ke*o.scale*Me;Ce=Math.max(ce,(de.width-e)/Me/2),Pe=Math.max(ue,(de.height-Se*o.scale)/2)}else{Ce=Math.max(ce,(de.width-ke*o.scale)/2);const e=Se*o.scale*Me;Pe=Math.max(ue,(de.height-e)/Me/2)}Number.isNaN(Ce)&&(Ce=ce),Number.isNaN(Pe)&&(Pe=ue),r.useEffect(()=>{const e=e=>{(Q||s)(e,o)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),r.useEffect(()=>{const e=e=>a(e,o),t=e=>c(e,o),r=e=>(U||u)(e,o);return window.addEventListener("copy",e),window.addEventListener("cut",t),window.addEventListener("paste",r),()=>{window.removeEventListener("copy",e),window.removeEventListener("cut",t),window.removeEventListener("paste",r)}},[U]),r.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const t=Math.max(5,o.scaleToFit);let r=Math.min(.1,o.scaleToFit);ae&&ke>0&&Number.isFinite(ke)&&(r=Math.max(r,300/ke)),r=Math.max(r,.01);const n=.03,l=p(e.deltaY<0?o.scale*(1+n):o.scale/(1+n),r,t);return void o.setScale(l)}},t=fe.current;return null==t||t.addEventListener("wheel",e),()=>null==t?void 0:t.removeEventListener("wheel",e)},[ae,ke,o]),r.useEffect(()=>{const e=fe.current;if(!e){return}const t=e=>{2===e.touches.length&&(me.current=f(e.touches[0],e.touches[1]))},r=t=>{if(2===t.touches.length&&me.current>0){t.preventDefault();const r=f(t.touches[0],t.touches[1]),n=r/me.current,l=Math.max(5,o.scaleToFit);let i=Math.min(.1,o.scaleToFit);ae&&ke>0&&Number.isFinite(ke)&&(i=Math.max(i,300/ke)),i=Math.max(i,.01);const s=o.scale,a=p(s*n,i,l),c=a/s,u=e.getBoundingClientRect(),d=(t.touches[0].clientX+t.touches[1].clientX)/2-u.left,h=(t.touches[0].clientY+t.touches[1].clientY)/2-u.top,g=e.scrollLeft+d,m=e.scrollTop+h;je.current=!0,o.setScale(a),e.scrollLeft=g*c-d,e.scrollTop=m*c-h,me.current=r}},n=()=>{me.current=0};return e.addEventListener("touchstart",t,{passive:!0}),e.addEventListener("touchmove",r,{passive:!1}),e.addEventListener("touchend",n,{passive:!0}),()=>{e.removeEventListener("touchstart",t),e.removeEventListener("touchmove",r),e.removeEventListener("touchend",n)}},[ae,ke,o]);const Re=void 0!==ee,Fe=o.pages.map(e=>{if(ae){const t=(e.computedWidth+ve+we)*o.scale;return Re?t+ee:t+2*Ce}{const t=(e.computedHeight+xe+ye)*o.scale;return Re?t+ee:t+2*Pe}}),We=[];let Be=Re?ae?Ce:Pe:0;for(let e=0;e<Fe.length;e++){We.push(Be),Be+=Fe[e]}const Oe=Fe.reduce((e,t)=>e+t,0),ze=Re?Oe+(ae?2*Ce:2*Pe):Oe,je=r.useRef(!1),[,Ne]=r.useReducer(e=>e+1,0);((e,t,o,n,l)=>{const i=r.useRef(0),s=r.useRef(0),a=r.useRef(null),c=r.useRef(null),u=r.useRef(!1),d=r.useRef(n.pages.length);u.current=d.current!==n.pages.length,d.current=n.pages.length,r.useEffect(()=>{const t=e.current,r=()=>{i.current=t.scrollLeft,s.current=t.scrollTop,a.current=t.scrollWidth,c.current=t.scrollHeight};return t.addEventListener("scroll",r),r(),()=>{t.removeEventListener("scroll",r)}},[]),r.useLayoutEffect(()=>{if(!e.current){return}if(u.current){const t=e.current;return a.current=t.scrollWidth,c.current=t.scrollHeight,i.current=t.scrollLeft,void(s.current=t.scrollTop)}const t=e.current,r=a.current,o=c.current;if(null===r||null===o){return a.current=t.scrollWidth,c.current=t.scrollHeight,i.current=t.scrollLeft,void(s.current=t.scrollTop)}l.current=!0;const n=t.offsetWidth,d=t.offsetHeight,h=(i.current+n/2)/r,g=(s.current+d/2)/o,f=Math.max(0,t.scrollWidth-n),m=Math.max(0,t.scrollHeight-d);t.scrollLeft=p(h*t.scrollWidth-n/2,0,f),t.scrollTop=p(g*t.scrollHeight-d/2,0,m),a.current=t.scrollWidth,c.current=t.scrollHeight,i.current=t.scrollLeft,s.current=t.scrollTop},[o,t])})(fe,ze,o.scale,o,je);const{handleScroll:He}=((e,t,o,n,l,i,s,a,c,u)=>{const d=r.useRef(!1),h=r.useRef(null),g=r.useRef(!1),p="horizontal"===c;r.useEffect(()=>{const t=e.current,r=()=>{s.current};return t.addEventListener("scroll",r),()=>{t.removeEventListener("scroll",r)}},[]);const f=n.pages.indexOf(n.activePage);return r.useLayoutEffect(()=>{if(a){return}if(!n.activePage){return}if(!e.current){return}if(d.current){return}const r=e.current,i=n.pages.indexOf(n.activePage),s=t[i]||0,c=p?r.scrollLeft:r.scrollTop,h=p?r.scrollWidth-r.clientWidth:r.scrollHeight-r.clientHeight,f=Math.min(s,Math.max(0,h)),m=o[i]||o[0]||0;let v=()=>{};return(Math.abs(f-c)>m*l||g.current)&&(g.current=!0,v=(({element:e,scrollTop:t,scrollLeft:r,duration:o=300,onFinish:n=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,s=l?t:r,a=s-i;let c=0,u=!1;if(0===o){return l?e.scrollTop=s:e.scrollLeft=s,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,a,o);l?e.scrollTop=t:e.scrollLeft=t,c<o?setTimeout(d,20):n()},h=(e,t,r,o)=>(e/=o/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:r},p?{scrollLeft:f}:{scrollTop:f}),{onFinish:()=>{g.current=!1,null==u||u()},duration:n.isPlaying?0:300}))),v},[n.activePage,f,n.isPlaying,a,c,t,o]),{handleScroll:e=>{if(a){return}if(g.current){return}d.current=!0,clearTimeout(h.current),h.current=setTimeout(()=>{d.current=!1},300);const r=(p?e.currentTarget.scrollLeft:e.currentTarget.scrollTop)+(p?i.width:i.height)/3;let o=0;for(let n=t.length-1;n>=0;n--){if(r>=t[n]){o=n;break}}const l=n.pages[o];l&&n.activePage!==l&&l.select()}}})(fe,We,Fe,o,le,de,je,ne,d,Ne),Ge=de.width>=ke*o.scale+2*Ce,Ie=de.height>=Se*o.scale+2*Pe,_e=x||"rgba(232, 232, 232, 0.9)",Ye=(null==J?void 0:J.NoPages)||m,De=ae?de.width:de.height,Xe=fe.current?ae?fe.current.scrollLeft:fe.current.scrollTop:0,Ae=e=>{for(let t=We.length-1;t>=0;t--){if(e>=We[t]){return t}}return 0},Ke=Math.max(0,Ae(Xe)),qe=Math.min(o.pages.length-1,Ae(Xe+De)),Ve=null!=oe?oe:1,Je=Math.max(0,Ke-Ve),Qe=Math.min(o.pages.length-1,qe+Ve),Ue=g({cropOverlayFill:W,workspaceBackgroundColor:x,pageBorderColor:L,activePageBorderColor:T,bleedColor:b,transparencyBackgroundColor:y,transformerStyle:B,innerImageCropTransformerStyle:O,outerImageCropTransformerStyle:z,highlighterStyle:j,snapGuideStroke:k,snapGuideStrokeWidth:S,snapGuideDash:E,selectionRectFill:M,selectionRectStroke:C,selectionRectStrokeWidth:P,transformLabelFill:R,transformLabelTextFill:F,distanceGuideStroke:I,distanceLabelFill:_,distanceLabelTextFill:Y,mediaLoadingStyle:N,mediaErrorStyle:H,textOverflowIndicatorStyle:G,rulerBackgroundColor:D,rulerTextColor:X,rulerBorderColor:A,rulerBorderSize:K,rulerTickColor:q,rulerTickSize:V});return e(h,{value:Ue,children:e("div",{ref:pe,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:_e,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container",children:t("div",{ref:fe,onScroll:He,style:Object.assign({position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:ae?"row":"column",overflow:"auto",overflowX:ae?"auto":Ge?"hidden":"auto",overflowY:ae&&Ie?"hidden":"auto"},Re&&{paddingTop:ae?0:Pe,paddingBottom:ae?0:Pe,paddingLeft:ae?Ce:0,paddingRight:ae?Ce:0,boxSizing:"border-box"}),className:"polotno-workspace-inner",children:[o.pages.map((t,r)=>{const l=t===o.activePage;if(ne&&!l&&!t._exportingOrRendering&&!t._forceMount){return null}const i=l||r>=Je&&r<=Qe||t._exportingOrRendering||t._forceMount,s=ae?Fe[r]:ke*o.scale+2*Ce,a=ae?Se*o.scale+2*Pe:Fe[r];if(!i){return e("div",{style:{flexShrink:0},children:e(v,{width:s,height:a,backgroundColor:_e,xPadding:Ce,yPadding:Pe})},t.id)}const c=e(n,{page:t,xPadding:Ce,yPadding:Pe,width:s,height:a,store:o,pageControlsEnabled:w,altCloneEnabled:te,groupSelectionMode:re,components:J,viewportSize:de,layout:d,tooltipSafeArea:ie},t.id);return(t._exportingOrRendering||t._forceMount)&&!l&&ne?e("div",{style:{display:"none",flexShrink:0},children:c},t.id):c}),o.rulesVisible&&e(l,{store:o,xPadding:Ce,yPadding:Pe,width:ke*o.scale+2*Ce,height:Se*o.scale+2*Pe,pageSizes:Fe,layout:d,renderOnlyActivePage:ne}),0===o.pages.length&&e(Ye,{store:o}),o.audios.map(t=>e(i,{audio:t,store:o},t.id))]})})})});export default WorkspaceCanvas;
|
package/model/group-model.d.ts
CHANGED
|
@@ -295,6 +295,7 @@ export declare const TYPES_MAP: {
|
|
|
295
295
|
verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
296
296
|
strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
297
297
|
stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
298
|
+
strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
298
299
|
lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
|
|
299
300
|
letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
300
301
|
_editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
package/model/group-model.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__rest||function(e,t){var o={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(o[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(i=Object.getOwnPropertySymbols(e);r<i.length;r++){t.indexOf(i[r])<0&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(o[i[r]]=e[i[r]])}}return o};import{detach as t,isAlive as o,types as i}from"mobx-state-tree";import{nanoid as r}from"nanoid";import{Node as n}from"./node-model.js";import{Animation as
|
|
1
|
+
var e=this&&this.__rest||function(e,t){var o={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(o[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(i=Object.getOwnPropertySymbols(e);r<i.length;r++){t.indexOf(i[r])<0&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(o[i[r]]=e[i[r]])}}return o};import{detach as t,isAlive as o,types as i}from"mobx-state-tree";import{nanoid as r}from"nanoid";import{Node as n}from"./node-model.js";import{Animation as s,Shape as l}from"./shape-model.js";import{animate as a}from"../utils/animations.js";import{polotnoError as d}from"../utils/errors.js";import{getPlayheadLocalTime as c}from"../utils/timeline.js";import{getCenter as p,getTotalClientRect as h}from"../utils/math.js";import{TextElement as y}from"./text-model.js";import{ImageElement as m}from"./image-model.js";import{VideoElement as f}from"./video-model.js";import{LineElement as u}from"./line-model.js";import{SVGElement as g}from"./svg-model.js";import{FigureElement as E}from"./figure-model.js";import{GifElement as b}from"./gif-model.js";import{TableElement as v}from"./table-model.js";export const forEveryChild=(e,t)=>{if(e.children){for(const o of e.children){if(!0===t(o)){break}forEveryChild(o,t)}}};export const forEveryNode=(e,t)=>{if(e.children){for(const o of e.children){if(!0===t(o)){break}forEveryNode(o,t)}}if(e.cells){for(const o of e.cells){if(!0===t(o)){break}}}};export function zIndexOps(e){const o=(t,o,i)=>{const r=t.map(t=>e.children.findIndex(e=>e.id===t)).filter(e=>-1!==e).sort((e,t)=>(t-e)*o);for(const n of r){const r=e.children[n+o];!r||t.indexOf(r.id)>=0||i(n)}},i=(e,t)=>{let i=!1;return o(e,t,()=>{i=!0}),i},r=(i,r)=>{o(i,r,o=>{const i=e.children[o];t(i),e.children.splice(o+r,0,i)})},n=(t,o)=>{const i=[],r=[];e.children.forEach(e=>{(t.indexOf(e.id)>=0?i:r).push(e)}),e.children.replace(o?r.concat(i):i.concat(r))};return{canMoveElementsUp:e=>i(e,1),canMoveElementsTop:e=>i(e,1),canMoveElementsDown:e=>i(e,-1),canMoveElementsBottom:e=>i(e,-1),moveElementsUp(e){r(e,1)},moveElementsDown(e){r(e,-1)},moveElementsTop(e){n(e,!0)},moveElementsBottom(e){n(e,!1)},setElementZIndex(o,i){const r=e.children.find(e=>e.id===o);r&&(t(r),e.children.remove(r),e.children.splice(i,0,r))}}}const x=[...new Array(20)].map((e,t)=>i.late(()=>S[t]));export const ElementTypes=i.union({dispatcher:e=>{const t=TYPES_MAP[e.type];if(!t){const t=`Unknown element type: "${e.type}"`;throw d("DESIGN_INVALID",t,{errors:[{path:"type",message:t}],knownTypes:Object.keys(TYPES_MAP)})}return t}},g,y,m,u,f,E,b,v,i.late(()=>GroupElement),...x);const w=Object.freeze({x:0,y:0,offsetX:0,offsetY:0,scaleX:1,scaleY:1,rotation:0,opacity:1});function j(e){return 1===e?w:Object.assign(Object.assign({},w),{opacity:e})}const O={x:0,y:0,width:0,height:0,rotation:0,opacity:1,fontSize:0,cropX:0,cropY:0,cropWidth:1,cropHeight:1},P=(e,t)=>"number"==typeof e&&isFinite(e)?e:t;function C(e,t,o,i){O.x=e.x,O.y=e.y,O.width=e.width,O.height=e.height,O.opacity=i;const r=a({element:O,animation:t,dTime:o})||{},n=P(r.width,e.width),s=P(r.height,e.height);return{x:P(r.x,e.x),y:P(r.y,e.y),width:n>0?n:e.width,height:s>0?s:e.height,rotation:P(r.rotation,0),opacity:P(r.opacity,i)}}export const GroupElement=n.named("Group").props({type:"group",children:i.array(ElementTypes),animations:i.array(s)}).views(e=>({get draggable(){let t=!0;return forEveryChild(e,e=>{e.draggable||(t=!1)}),t},get resizable(){let t=!0;return forEveryChild(e,e=>{e.resizable||(t=!1)}),t},get contentEditable(){let t=!0;return forEveryChild(e,e=>{e.contentEditable||(t=!1)}),t},get styleEditable(){let t=!0;return forEveryChild(e,e=>{e.styleEditable||(t=!1)}),t},get locked(){let t=!0;return forEveryChild(e,e=>{e.locked||(t=!1)}),t},get _restingBbox(){const t=[];if(forEveryChild(e,e=>{var o,i,r;if("group"===e.type){return}const n=e.width,s=e.height;!n||!s||n<=0||s<=0||t.push({x:null!==(o=e.x)&&void 0!==o?o:0,y:null!==(i=e.y)&&void 0!==i?i:0,width:n,height:s,rotation:null!==(r=e.rotation)&&void 0!==r?r:0})}),!t.length){return null}const o=h(t);return o.width<=0||o.height<=0?null:{x:o.x,y:o.y,width:o.width,height:o.height}},get a(){if(!o(e)){return w}const t=c(e);if(null===t){return j(e.opacity)}if(e.store.isEditingPaused&&this.isSelectedDirectly){return j(e.opacity)}const i=e.page,r=e.store.animatedElementsIds;if(r.length&&!r.includes(e.id)){return j(e.opacity)}let n,s,l;for(const o of e.animations){o.enabled&&("enter"===o.type?n=o:"exit"===o.type?s=o:"loop"===o.type&&(l=o))}const a=!!n&&t<n.delay,d=!!n&&t>=n.delay&&t<=n.delay+n.duration,h=!a&&!d&&!!s&&t>=i.duration-s.duration-s.delay&&t<=i.duration-s.delay,y=!!s&&t>=i.duration-s.delay;if(!(a||d||h||y||l)){return j(e.opacity)}const m=this._restingBbox;if(!m){return j(e.opacity)}let f={x:m.x,y:m.y,width:m.width,height:m.height,rotation:0,opacity:e.opacity};a&&(f.opacity=0),d&&(f=C(m,n,t-n.delay,e.opacity)),h&&(f=C(m,s,t-(i.duration-s.duration-s.delay),e.opacity)),y&&(f.opacity=0),l&&(f=C(f,l,t,f.opacity));const u=p(f);return{x:u.x,y:u.y,offsetX:m.x+m.width/2,offsetY:m.y+m.height/2,scaleX:f.width/m.width,scaleY:f.height/m.height,rotation:f.rotation,opacity:f.opacity}},get isSelectedDirectly(){return!!o(e)&&e.store.selectedElements.indexOf(e)>=0&&e.selectable},get active(){return!0}})).actions(t=>Object.assign(Object.assign({set(o){var{draggable:i,contentEditable:r,styleEditable:n,resizable:s}=o,l=e(o,["draggable","contentEditable","styleEditable","resizable"]);void 0!==i&&forEveryChild(t,e=>{e.set({draggable:i})}),void 0!==r&&forEveryChild(t,e=>{e.set({contentEditable:r})}),void 0!==n&&forEveryChild(t,e=>{e.set({styleEditable:n})}),void 0!==s&&forEveryChild(t,e=>{e.set({resizable:s})}),Object.assign(t,l)},addElement(e,{skipSelect:o=!1}={}){const i=TYPES_MAP[e.type];if(!i){return void console.error("Can not find model with type "+e.type)}e.children&&e.children.forEach(e=>{e.id=e.id||r(10)});const n=i.create(Object.assign({id:r(10)},e));return t.children.push(n),n.selectable&&!o&&t.store.selectElements([n.id]),n}},zIndexOps(t)),{setAnimation(e,o){const i=t.animations.find(t=>t.type===e);i?Object.assign(i,o):t.animations.push(Object.assign({type:e},o))}}));const S=[];export const TYPES_MAP={svg:g,text:y,image:m,group:GroupElement,line:u,video:f,figure:E,gif:b,table:v};export function registerShapeModel(e,t){const o=e.type;if(!o){throw new Error('You must pass "type" attribute to custom model.')}let i=l.named(o).props(e);t&&(i=t(i)),TYPES_MAP[o]=i,S.push(i)}
|
package/model/page-model.d.ts
CHANGED
|
@@ -238,6 +238,7 @@ export declare const Page: import("mobx-state-tree").IModelType<{
|
|
|
238
238
|
verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
239
239
|
strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
240
240
|
stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
241
|
+
strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
241
242
|
lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
|
|
242
243
|
letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
243
244
|
_editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|