polotno 4.2.1 → 4.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blueprint/pages-timeline/page-preview.js +2 -2
- package/blueprint/toolbar/html-toolbar.js +3 -3
- 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/use-mediabunny-video.js +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/text-model.js +1 -1
- package/package.json +2 -2
- package/pages-timeline/page-preview.js +1 -1
- package/polotno.bundle.js +123 -122
- 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 +359 -0
- package/utils/clipboard.js +1 -1
- package/utils/file.d.ts +6 -0
- package/utils/file.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/mobx.d.ts +4 -0
- package/utils/mobx.js +1 -0
- package/utils/validate-key.js +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import o from"react";import{observer as i}from"mobx-react-lite";import{
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import o from"react";import{observer as i}from"mobx-react-lite";import{nodeReaction as n}from"../../utils/mobx.js";import{onSnapshot as r}from"mobx-state-tree";import{Button as s,Menu as a,MenuItem as l,Popover as d,Position as c}from"@blueprintjs/core";import{Duplicate as p,Insert as u,More as g,Trash as m}from"@blueprintjs/icons";import h from"../../utils/styled.js";import{flags as x}from"../../utils/flags.js";import{t as f}from"../../utils/l10n.js";import{Spinner as v}from"./spinner.js";import{deepEqual as b}from"../../utils/deep-equal.js";const w=h("div",o.forwardRef)`
|
|
2
2
|
display: flex;
|
|
3
3
|
position: relative;
|
|
4
4
|
border-radius: 15px;
|
|
@@ -20,4 +20,4 @@ import{jsx as e,jsxs as t}from"react/jsx-runtime";import o from"react";import{ob
|
|
|
20
20
|
&:hover {
|
|
21
21
|
display: block;
|
|
22
22
|
}
|
|
23
|
-
`;let y=[],k=!1;const E=async()=>{if(k||0===y.length){return}k=!0;const{page:e,setPreview:t}=y.shift();try{t(await e.store.toDataURL({pageId:e.id,pixelRatio:.1,quickMode:!0}))}catch(o){o instanceof Error&&"string"==typeof o.message&&(o.message.includes("Canvas was unmounted.")||o.message.includes("<Workspace /> component is not mounted"))||console.error(o)}finally{k=!1}E()};export const usePagePreview=({page:e,ref:t})=>{const[i,s]=o.useState(null),a=o.useRef(!1);return o.useEffect(()=>{const o=()=>{y.push({page:e,setPreview:e=>s(e)}),E()};let i=null,l=null,d=Date.now();const c=()=>{i&&clearTimeout(i),a.current&&(l||(l=setTimeout(()=>{Date.now()-d>=6e3&&(o(),d=Date.now(),l=null)},6e3)),i=setTimeout(()=>{o(),d=Date.now(),i=null,l&&(clearTimeout(l),l=null)},300))};let p=null;const u=r(e,e=>{b(p,e)||(c(),p=e)}),g=n(()=>e.children.some(e=>e._editModeEnabled),e=>{e||c()}),m=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting?(a.current=!0,c()):(i&&clearTimeout(i),l&&clearTimeout(l),a.current=!1)})},{threshold:.1});return t.current&&m.observe(t.current),()=>{m.disconnect(),i&&clearTimeout(i),l&&clearTimeout(l),u(),g(),y=y.filter(t=>t.page!==e)}},[t,e]),i};export const PagePreview=i(({page:i,scale:n})=>{const r=i.store.activePage===i||i.store._selectedPagesIds.includes(i.id),h=o.useRef(null),b=i.store.pages.indexOf(i),y=60/i.computedHeight*i.computedWidth,k=x.animationsEnabled?i.duration*n:y,E=i.store.pages.length>1;o.useLayoutEffect(()=>{h.current&&(h.current.style.width=k+"px")},[b,k]);const I=usePagePreview({page:i,ref:h}),{handleStartDrag:R}=((e,t)=>({handleStartDrag:o.useCallback((o,i)=>{o.preventDefault();const n=o=>{if(o.preventDefault(),!t.current){return}const n="start"===i?7:-7,{clientX:r}=o,{left:s,width:a}=t.current.getBoundingClientRect(),l=(r-s-n)/a;"end"===i&&e.set({duration:Math.max(1e3,l*e.duration)})},r=()=>{window.removeEventListener("mousemove",n),window.removeEventListener("mouseup",r)};window.addEventListener("mousemove",n),window.addEventListener("mouseup",r)},[t,e])}))(i,h);return t(w,{style:{width:k+"px",marginRight:x.animationsEnabled?"0px":"10px",height:"60px"},ref:h,className:"polotno-page-container"+(r?" sortable-selected":""),children:[e("div",{style:{width:"100%",height:"100%",borderRadius:"15px",backgroundImage:I?`url("${I}")`:"none",backgroundRepeat:"repeat-x",backgroundSize:"auto 100%",backgroundColor:"white",display:"flex",justifyContent:"center",alignItems:"center"},onClick:e=>{const{store:t}=i,o=t._selectedPagesIds.length?t._selectedPagesIds:t.activePage?[t.activePage.id]:[],n=o.includes(i.id),r=e.shiftKey;if(r&&n){const e=o.filter(e=>e!==i.id);t.selectPages(e)}else if(r&&!n){const e=o.concat([i.id]);t.selectPages(e)}else{t.selectPages([i.id])}},children:!I&&e(v,{})}),e("div",{style:{position:"absolute",top:"0",left:"0px",bottom:"0px",right:"0px",borderRadius:"15px",border:r?"2px solid rgb(0, 161, 255, 0.9)":"2px solid lightgrey",zIndex:1,pointerEvents:"none"}}),x.animationsEnabled&&t("div",{style:{position:"absolute",zIndex:1,bottom:"5px",left:"5px",backgroundColor:"rgba(0, 0, 0, 0.5)",color:"white",padding:"2px 7px",textAlign:"center",borderRadius:"4rem"},children:[(i.duration/1e3).toFixed(1),"s"]}),x.animationsEnabled&&e("div",{style:{position:"absolute",zIndex:1,top:"50%",right:"0px",width:"8px",height:"50%",transform:"translateY(-50%) translateX(-3px)",borderRadius:"5px",border:"1px solid rgb(255, 255, 255, 0.6)",backgroundColor:"rgb(0, 0, 0, 0.6)",cursor:"ew-resize"},onMouseDown:e=>R(e,"end")}),r&&e(P,{className:"polotno-page-menu",onClick:e=>{e.stopPropagation()},children:e(d,{content:t(a,{style:{width:"140px"},children:[e(l,{icon:e(p,{}),text:f("pagesTimeline.duplicatePage"),onClick:()=>{const e=i.store,t=(e.selectedPages||[]).filter(Boolean),o=t.length?t:e.activePage?[e.activePage]:[];if(!o.length){return}const n=new Set(o.map(e=>e.id)),r=e.pages.filter(e=>n.has(e.id)),s=r[r.length-1],a=r.map(e=>e.clone()),l=e.pages.indexOf(s);a.forEach((e,t)=>{e.setZIndex(l+1+t)}),e.selectPages(a.map(e=>e.id))}}),e(l,{icon:e(u,{}),text:f("pagesTimeline.addPage"),onClick:()=>{var e,t,o;const n=i.store.addPage({bleed:(null===(e=i.store.activePage)||void 0===e?void 0:e.bleed)||0,width:(null===(t=i.store.activePage)||void 0===t?void 0:t.width)||"auto",height:(null===(o=i.store.activePage)||void 0===o?void 0:o.height)||"auto"}),r=i.store.pages.indexOf(i);n.setZIndex(r+1)}}),E&&e(l,{icon:e(m,{}),text:f("pagesTimeline.removePage"),onClick:()=>{const e=i.store,t=(e.selectedPages||[]).filter(Boolean),o=t.length?t.map(e=>e.id):e.activePage?[e.activePage.id]:[];o.length&&e.deletePages(o)}})]}),position:c.TOP,children:e(s,{icon:e(g,{}),style:{minHeight:"20px",borderRadius:"10px"}})})})]})});
|
|
23
|
+
`;let y=[],k=!1;const E=async()=>{if(k||0===y.length){return}k=!0;const{page:e,setPreview:t}=y.shift();try{t(await e.store.toDataURL({pageId:e.id,pixelRatio:.1,quickMode:!0}))}catch(o){o instanceof Error&&"string"==typeof o.message&&(o.message.includes("Canvas was unmounted.")||o.message.includes("<Workspace /> component is not mounted"))||console.error(o)}finally{k=!1}E()};export const usePagePreview=({page:e,ref:t})=>{const[i,s]=o.useState(null),a=o.useRef(!1);return o.useEffect(()=>{const o=()=>{y.push({page:e,setPreview:e=>s(e)}),E()};let i=null,l=null,d=Date.now();const c=()=>{i&&clearTimeout(i),a.current&&(l||(l=setTimeout(()=>{Date.now()-d>=6e3&&(o(),d=Date.now(),l=null)},6e3)),i=setTimeout(()=>{o(),d=Date.now(),i=null,l&&(clearTimeout(l),l=null)},300))};let p=null;const u=r(e,e=>{b(p,e)||(c(),p=e)}),g=n(e,()=>e.children.some(e=>e._editModeEnabled),e=>{e||c()}),m=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting?(a.current=!0,c()):(i&&clearTimeout(i),l&&clearTimeout(l),a.current=!1)})},{threshold:.1});return t.current&&m.observe(t.current),()=>{m.disconnect(),i&&clearTimeout(i),l&&clearTimeout(l),u(),g(),y=y.filter(t=>t.page!==e)}},[t,e]),i};export const PagePreview=i(({page:i,scale:n})=>{const r=i.store.activePage===i||i.store._selectedPagesIds.includes(i.id),h=o.useRef(null),b=i.store.pages.indexOf(i),y=60/i.computedHeight*i.computedWidth,k=x.animationsEnabled?i.duration*n:y,E=i.store.pages.length>1;o.useLayoutEffect(()=>{h.current&&(h.current.style.width=k+"px")},[b,k]);const I=usePagePreview({page:i,ref:h}),{handleStartDrag:R}=((e,t)=>({handleStartDrag:o.useCallback((o,i)=>{o.preventDefault();const n=o=>{if(o.preventDefault(),!t.current){return}const n="start"===i?7:-7,{clientX:r}=o,{left:s,width:a}=t.current.getBoundingClientRect(),l=(r-s-n)/a;"end"===i&&e.set({duration:Math.max(1e3,l*e.duration)})},r=()=>{window.removeEventListener("mousemove",n),window.removeEventListener("mouseup",r)};window.addEventListener("mousemove",n),window.addEventListener("mouseup",r)},[t,e])}))(i,h);return t(w,{style:{width:k+"px",marginRight:x.animationsEnabled?"0px":"10px",height:"60px"},ref:h,className:"polotno-page-container"+(r?" sortable-selected":""),children:[e("div",{style:{width:"100%",height:"100%",borderRadius:"15px",backgroundImage:I?`url("${I}")`:"none",backgroundRepeat:"repeat-x",backgroundSize:"auto 100%",backgroundColor:"white",display:"flex",justifyContent:"center",alignItems:"center"},onClick:e=>{const{store:t}=i,o=t._selectedPagesIds.length?t._selectedPagesIds:t.activePage?[t.activePage.id]:[],n=o.includes(i.id),r=e.shiftKey;if(r&&n){const e=o.filter(e=>e!==i.id);t.selectPages(e)}else if(r&&!n){const e=o.concat([i.id]);t.selectPages(e)}else{t.selectPages([i.id])}},children:!I&&e(v,{})}),e("div",{style:{position:"absolute",top:"0",left:"0px",bottom:"0px",right:"0px",borderRadius:"15px",border:r?"2px solid rgb(0, 161, 255, 0.9)":"2px solid lightgrey",zIndex:1,pointerEvents:"none"}}),x.animationsEnabled&&t("div",{style:{position:"absolute",zIndex:1,bottom:"5px",left:"5px",backgroundColor:"rgba(0, 0, 0, 0.5)",color:"white",padding:"2px 7px",textAlign:"center",borderRadius:"4rem"},children:[(i.duration/1e3).toFixed(1),"s"]}),x.animationsEnabled&&e("div",{style:{position:"absolute",zIndex:1,top:"50%",right:"0px",width:"8px",height:"50%",transform:"translateY(-50%) translateX(-3px)",borderRadius:"5px",border:"1px solid rgb(255, 255, 255, 0.6)",backgroundColor:"rgb(0, 0, 0, 0.6)",cursor:"ew-resize"},onMouseDown:e=>R(e,"end")}),r&&e(P,{className:"polotno-page-menu",onClick:e=>{e.stopPropagation()},children:e(d,{content:t(a,{style:{width:"140px"},children:[e(l,{icon:e(p,{}),text:f("pagesTimeline.duplicatePage"),onClick:()=>{const e=i.store,t=(e.selectedPages||[]).filter(Boolean),o=t.length?t:e.activePage?[e.activePage]:[];if(!o.length){return}const n=new Set(o.map(e=>e.id)),r=e.pages.filter(e=>n.has(e.id)),s=r[r.length-1],a=r.map(e=>e.clone()),l=e.pages.indexOf(s);a.forEach((e,t)=>{e.setZIndex(l+1+t)}),e.selectPages(a.map(e=>e.id))}}),e(l,{icon:e(u,{}),text:f("pagesTimeline.addPage"),onClick:()=>{var e,t,o;const n=i.store.addPage({bleed:(null===(e=i.store.activePage)||void 0===e?void 0:e.bleed)||0,width:(null===(t=i.store.activePage)||void 0===t?void 0:t.width)||"auto",height:(null===(o=i.store.activePage)||void 0===o?void 0:o.height)||"auto"}),r=i.store.pages.indexOf(i);n.setZIndex(r+1)}}),E&&e(l,{icon:e(m,{}),text:f("pagesTimeline.removePage"),onClick:()=>{const e=i.store,t=(e.selectedPages||[]).filter(Boolean),o=t.length?t.map(e=>e.id):e.activePage?[e.activePage.id]:[];o.length&&e.deletePages(o)}})]}),position:c.TOP,children:e(s,{icon:e(g,{}),style:{minHeight:"20px",borderRadius:"10px"}})})})]})});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e}from"react/jsx-runtime";import o from"react";import{observer as n}from"mobx-react-lite";import{Button as i,ButtonGroup as l,Tooltip as r,Position as s}from"@blueprintjs/core";import{Bold as a,Italic as c,Underline as m,Strikethrough as p,AlignLeft as u,AlignCenter as d,AlignRight as f,AlignJustify as x}from"@blueprintjs/icons";import{ElementContainer as h,extendToolbar as
|
|
1
|
+
import{jsx as t,jsxs as e}from"react/jsx-runtime";import o from"react";import{observer as n}from"mobx-react-lite";import{Button as i,ButtonGroup as l,Tooltip as r,Position as s}from"@blueprintjs/core";import{Bold as a,Italic as c,Underline as m,Strikethrough as p,AlignLeft as u,AlignCenter as d,AlignRight as f,AlignJustify as x}from"@blueprintjs/icons";import{ElementContainer as h,extendToolbar as g}from"./element-container.js";import v from"../../utils/styled.js";import b from"./color-picker.js";import T from"./filters-picker.js";import{MdFormatTextdirectionRToL as y,MdFormatTextdirectionLToR as F,MdcFormatVerticalAlignTop as S,MdcFormatVerticalAlignCenter as j,MdcFormatVerticalAlignBottom as w,MdcFormatListBulleted as D,MdcFormatListNumbered as z}from"../../icons/meronex.js";import{AnimationsPicker as A}from"./animations-picker.js";import{flags as C}from"../../utils/flags.js";import{TextAiWrite as k}from"./text-ai-write.js";import{t as O}from"../../utils/l10n.js";import{quillRef as M,createQuill as B,setQuillContent as E}from"../../canvas/html-element.js";import{FontMenu as N,fetcher as I,TextSpacing as L,TextFontSize as W,TextTransform as R}from"./text-toolbar.js";import V from"swr";import{getFontsList as _,globalFonts as G,isGoogleFontChanged as H}from"../../utils/fonts.js";import{getGoogleFontsListAPI as P}from"../../utils/api.js";import{normalizeRichTextHtml as Q,listEffectiveFontFamilies as $}from"../../utils/rich-text-html.js";import{patchTextFormat as q}from"../../utils/text-format.js";import{useTextFormat as J,getActiveTextEditor as K,resolveSelectionScope as U,applyToLiveEditor as X}from"../../utils/text-format-state.js";const Y=v("div")`
|
|
2
2
|
position: relative;
|
|
3
3
|
display: inline-block;
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ import{jsx as t,jsxs as e}from"react/jsx-runtime";import o from"react";import{ob
|
|
|
8
8
|
&.polotno-mixed:focus-within input {
|
|
9
9
|
color: inherit !important;
|
|
10
10
|
}
|
|
11
|
-
`,Z=
|
|
11
|
+
`,Z=v("span")`
|
|
12
12
|
position: absolute;
|
|
13
13
|
left: 11px;
|
|
14
14
|
top: 0;
|
|
@@ -22,4 +22,4 @@ import{jsx as t,jsxs as e}from"react/jsx-runtime";import o from"react";import{ob
|
|
|
22
22
|
${Y}:focus-within & {
|
|
23
23
|
display: none;
|
|
24
24
|
}
|
|
25
|
-
`,tt=t=>{const e=K();return!!e&&e.store===t&&!!e.instance},et=["left","center","right","justify"],ot=["top","middle","bottom"],nt={top:t("span",{className:"bp6-icon",children:t(S,{})}),middle:t("span",{className:"bp6-icon",children:t(j,{})}),bottom:t("span",{className:"bp6-icon",children:t(w,{})})},it=n(({store:e,isActive:o,toggle:n,icon:l,ariaLabel:a,tooltipContent:c})=>{const{format:m,applyTextFormat:p}=J(e),u=c||a;return t(r,{content:u,position:s.BOTTOM,children:t(i,{minimal:!0,icon:l,active:o(m),"aria-label":u,onMouseDown:t=>{t.preventDefault()},onClick:()=>n(m,p)})})});function lt(t,e){const o=t.textDecoration.value||"",n="underline"===e?"line-through":"underline";return[!o.split(/\s+/).includes(e)&&e,o.split(/\s+/).includes(n)&&n].filter(Boolean).join(" ")}export const TextBold=n(({store:e})=>t(it,{store:e,isActive:t=>Number(t.fontWeight.value)>=600,toggle:(t,e)=>e({fontWeight:Number(t.fontWeight.value)>=600?400:700}),icon:t(a,{}),tooltipContent:O("toolbar.bold")}));export const FontStyleGroup=n(({element:o,store:n,elements:a,components:h})=>{const
|
|
25
|
+
`,tt=t=>{const e=K();return!!e&&e.store===t&&!!e.instance},et=["left","center","right","justify"],ot=["top","middle","bottom"],nt={top:t("span",{className:"bp6-icon",children:t(S,{})}),middle:t("span",{className:"bp6-icon",children:t(j,{})}),bottom:t("span",{className:"bp6-icon",children:t(w,{})})},it=n(({store:e,isActive:o,toggle:n,icon:l,ariaLabel:a,tooltipContent:c})=>{const{format:m,applyTextFormat:p}=J(e),u=c||a;return t(r,{content:u,position:s.BOTTOM,children:t(i,{minimal:!0,icon:l,active:o(m),"aria-label":u,onMouseDown:t=>{t.preventDefault()},onClick:()=>n(m,p)})})});function lt(t,e){const o=t.textDecoration.value||"",n="underline"===e?"line-through":"underline";return[!o.split(/\s+/).includes(e)&&e,o.split(/\s+/).includes(n)&&n].filter(Boolean).join(" ")}export const TextBold=n(({store:e})=>t(it,{store:e,isActive:t=>Number(t.fontWeight.value)>=600,toggle:(t,e)=>e({fontWeight:Number(t.fontWeight.value)>=600?400:700}),icon:t(a,{}),tooltipContent:O("toolbar.bold")}));export const FontStyleGroup=n(({element:o,store:n,elements:a,components:h})=>{const g=(null==h?void 0:h.TextBold)||TextBold,v=M.currentFormat;return e(l,{children:[t(g,{element:o,store:n}),t(it,{store:n,isActive:t=>"italic"===t.fontStyle.value,toggle:(t,e)=>e({fontStyle:"italic"===t.fontStyle.value?"normal":"italic"}),icon:t(c,{}),tooltipContent:O("toolbar.italic")}),t(it,{store:n,isActive:t=>{var e;return!!(null===(e=t.textDecoration.value)||void 0===e?void 0:e.split(/\s+/).includes("underline"))},toggle:(t,e)=>e({textDecoration:lt(t,"underline")}),icon:t(m,{}),tooltipContent:O("toolbar.underline")}),t(it,{store:n,isActive:t=>{var e;return!!(null===(e=t.textDecoration.value)||void 0===e?void 0:e.split(/\s+/).includes("line-through"))},toggle:(t,e)=>e({textDecoration:lt(t,"line-through")}),icon:t(p,{}),tooltipContent:O("toolbar.strikethrough")}),t(r,{content:O("toolbar.textAlign"),position:s.BOTTOM,children:t(i,{minimal:!0,icon:"left"===o.align?t(u,{}):"center"===o.align?t(d,{}):"right"===o.align?t(f,{}):t(x,{}),onClick:()=>{const t=(et.indexOf(o.align)+1+et.length)%et.length,e=et[t];n.history.transaction(()=>{a.forEach(t=>{t.set({align:e})})})},"aria-label":O("toolbar.textAlign")})}),C.textVerticalResizeEnabled&&t(r,{content:O("toolbar.verticalAlign"),position:s.BOTTOM,children:t(i,{minimal:!0,icon:nt[o.verticalAlign],onClick:()=>{const t=(ot.indexOf(o.verticalAlign)+1+ot.length)%ot.length,e=ot[t];n.history.transaction(()=>{o.set({verticalAlign:e})})},"aria-label":O("toolbar.verticalAlign")})}),t(r,{content:O("toolbar.listFormat"),position:s.BOTTOM,children:t(i,{minimal:!0,icon:"bullet"===v.list?t("span",{className:"bp6-icon",children:t(z,{style:{width:"20px",height:"20px"}})}):t("span",{className:"bp6-icon",children:t(D,{style:{width:"20px",height:"20px"}})}),onMouseDown:t=>{t.preventDefault()},onClick:()=>{var t;let e=window.__polotnoQuill,n=!e;e=e||(({html:t})=>{const e=document.createElement("div");document.body.appendChild(e),e.style.display="none",e.style.whiteSpace="pre-wrap";const o=B(e);return E(o,t),o})({html:o.text}),n&&e.setSelection(0,e.getLength(),"api");const i=e.getSelection(!0)||(null===(t=K())||void 0===t?void 0:t.lastSelection)||{index:0,length:e.getLength()},l=e.getFormat(i);l.list?"bullet"===l.list?e.format("list","ordered"):e.format("list",!1):e.format("list","bullet"),n&&(o.set({text:Q(e.root.innerHTML,{fontSize:o.fontSize,fontFamily:o.fontFamily})}),(t=>{t.root.parentElement.remove()})(e))},"aria-label":O("toolbar.listFormat")})})]})});export const FontColorInput=n(({element:e,store:o})=>{var n;const{format:i,applyTextFormat:l}=J(o);return t("div",{"data-polotno-keep-focus":!0,onMouseDown:at,children:t(b,{value:null!==(n=i.fill.value)&&void 0!==n?n:e.fill,gradientEnabled:!0,onClose:()=>{const t=K();(null==t?void 0:t.instance)&&t.lastSelection&&t.instance.setSelection(t.lastSelection)},onChange:t=>l({fill:t}),store:o})})});export const DirectionInput=n(({element:e})=>{const o=e,n="rtl"===o.dir?y:F,l=O("toolbar.textDirection");return t(r,{content:l,position:s.BOTTOM,children:t(i,{icon:t(n,{className:"bp6-icon",style:{fontSize:"20px"}}),minimal:!0,onClick:()=>{e.set({dir:"rtl"===o.dir?"ltr":"rtl"})},"aria-label":l})})});let rt=null;const st=()=>{M.pendingToolbarInteraction=!0,rt&&clearTimeout(rt),rt=setTimeout(()=>{M.pendingToolbarInteraction=!1,rt=null},100)},at=t=>{t.preventDefault(),st()},ct=_(),mt={TextFontFamily:n(({elements:e,store:n})=>{var i;const{format:l,applyTextFormat:r}=J(n),s=tt(n),a=l.fontFamily.mixed,c=a?Array.from(new Set(e.flatMap(t=>$(t.text,t.fontFamily)))).sort((t,e)=>t.localeCompare(e,void 0,{sensitivity:"base"})):void 0,{data:m,mutate:p}=V(P(),I,{isPaused:()=>H(),fallbackData:[]});o.useEffect(()=>{p()},[H()]);const u=n.fonts.concat(G).map(t=>t.fontFamily).concat((null==m?void 0:m.length)&&!H()?m:ct),d=[];n.find(t=>("text"===t.type&&d.push(t.fontFamily),!1));const f=[...new Set(d.concat("_divider").concat(u))],x=null!==(i=l.fontFamily.value)&&void 0!==i?i:e[0].fontFamily;let h=x;h.length>15&&(h=h.slice(0,15)+"...");const g=t(N,{fonts:f,activeFont:x,activeFontLabel:h,store:n,mixed:a,mixedFonts:c,onFontSelect:t=>r({fontFamily:t})});return s?t("div",{"data-polotno-keep-focus":!0,onMouseDown:at,children:g}):g}),TextFontSize:n(({elements:o,store:n})=>{const{format:i}=J(n),l=tt(n),r=i.fontSize.mixed,s=i.fontSize.value,a=o.map(t=>new Proxy(t,{get:(t,e)=>"fontSize"===e?null!=s?s:t.fontSize:"set"===e?e=>((t,e)=>{if(!e.fontSize){return void t.set(e)}const o=K();if(o&&o.store===n&&o.instance){const{scope:t}=U(o.instance,o.lastSelection);if("full"!==t){return void X(o.instance,{fontSize:e.fontSize},o.lastSelection)}}const{attrsToSet:i}=q(t,{fontSize:e.fontSize});t.set(Object.assign(Object.assign({},e),i))})(t,e):Reflect.get(t,e)})),c=e(Y,{className:r?"polotno-mixed":"",children:[t(W,{elements:a,store:n}),r&&t(Z,{"aria-hidden":!0,children:"—"})]});return l?t("div",{"data-polotno-keep-focus":!0,onMouseDown:st,children:c}):c}),TextFontVariant:FontStyleGroup,TextTransform:R,TextFilters:T,TextFill:FontColorInput,TextSpacing:L,TextDirection:DirectionInput,TextAnimations:A,TextAiWrite:k};export const HtmlToolbar=n(({store:e,components:o})=>{const n=e.selectedElements,i=e.selectedElements[0],l=["TextFill","TextFontFamily","TextFontSize","TextFontVariant","TextSpacing","TextTransform","TextFilters",C.animationsEnabled&&"TextAnimations","TextAiWrite"],r=g({type:"text",usedItems:l,components:o});return t(h,{items:r,itemRender:l=>{if("TextBold"===l){return null}const r=o[l]||mt[l];return t(r,{element:i,elements:n,store:e,components:o},l)}})});
|
package/canvas/audio.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{observer as t}from"mobx-react-lite";import{
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import{nodeAutorun as r}from"../utils/mobx.js";export const AudioElement=t(({audio:t,store:n})=>{const[i,s]=function(t){const[r,n]=e.useState(null),[i,s]=e.useState("loading");return e.useEffect(()=>{const e=new Audio(t),r=()=>{s("loaded"),n(e)},i=()=>{s("failed"),n(null)};return e.addEventListener("canplay",r),e.addEventListener("error",i),()=>{e.removeEventListener("canplay",r),e.removeEventListener("error",i)}},[t]),[r,i]}(t.src);return e.useEffect(()=>{i&&n.history.ignore(()=>{t.set({duration:1e3*i.duration})})},[i,t,n.history]),e.useEffect(()=>{if(!i){return}const e=()=>{i.currentTime=t.startTime*t.duration/1e3},s=()=>{const e=t.endTime*t.duration/1e3;i.currentTime>=e&&(i.pause(),i.currentTime=t.startTime*t.duration/1e3)};i.addEventListener("ended",e),i.addEventListener("timeupdate",s);const a=r(t,()=>{const e=n.animatedElementsIds;if(e.length&&!e.includes(t.id)){return}const r=n.currentTime-t.delay,s=t.speed,a=t.duration*(t.endTime-t.startTime),o=r>=0&&r<t.visibleDuration;if(!n.isPlaying||0!==n.animatedElementsIds.length||!o){return void i.pause()}i.volume=t.volume,i.playbackRate=s,i.preservesPitch=!1,i.paused&&i.play();const u=r*s%a/1e3+t.startTime*t.duration/1e3,d=i.currentTime;Math.abs(d-u)>.5&&u!==d&&(i.currentTime=u)});return()=>{i.pause(),i.removeEventListener("ended",e),i.removeEventListener("timeupdate",s),a()}},[n.isPlaying,t.startTime,t.endTime,t.volume,t.speed,i]),null});
|
package/canvas/element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{createElement as o}from"react";import r from"react";import{observer as n}from"mobx-react-lite";import{ROLES as i}from"../model/store.js";import s from"konva";import{TextElement as
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{createElement as o}from"react";import r from"react";import{observer as n}from"mobx-react-lite";import{ROLES as i}from"../model/store.js";import s from"konva";import{TextElement as a}from"./text-element.js";import{ImageElement as l}from"./image-element.js";import{HTMLElement as m}from"./html-element.js";import{RenderTagElement as f}from"./render-tag-element.js";import{LineElement as c}from"./line-element.js";import{VideoElement as d}from"./video-element.js";import{FigureElement as p}from"./figure-element.js";import{GifElement as u}from"./gif-element.js";import{TableElement as g}from"./table-element.js";import{Group as h}from"react-konva";import{Highlighter as x}from"./highlighter.js";import{forEveryChild as v}from"../model/group-model.js";import{flags as y}from"../utils/flags.js";const j={text:a,image:l,svg:l,line:c,video:d,figure:p,group:n(t=>{const{element:r,store:n}=t,s=r,{children:a}=s,l=r.selectable||n.role===i.ADMIN,m=s.a;return e(h,{x:m.x,y:m.y,offsetX:m.offsetX,offsetY:m.offsetY,scaleX:m.scaleX,scaleY:m.scaleY,rotation:m.rotation,opacity:m.opacity,listening:l,hideInExport:!r.showInExport,id:r.id,children:a.map(e=>o(b,Object.assign({},t,{key:e.id,store:n,element:e})))})}),gif:u,table:g};export function registerShapeComponent(e,t){j[e]=t}const E=(e,t)=>{const o=[];v(e,e=>{"group"!==e.type&&o.push(e.a)});const r=[];o.forEach(e=>{const t=[{x:0,y:0},{x:0+e.width,y:0},{x:0+e.width,y:0+e.height},{x:0,y:0+e.height}],o=new s.Transform;o.translate(e.x,e.y),o.rotate(s.Util.degToRad(e.rotation)),t.forEach(e=>{const t=o.point(e);r.push(t)})});const n=new s.Transform;n.rotate(-s.Util.degToRad(t));let i=1/0,a=1/0,l=-1/0,m=-1/0;r.forEach(e=>{const t=n.point(e);i=Math.min(i,t.x),a=Math.min(a,t.y),l=Math.max(l,t.x),m=Math.max(m,t.y)}),n.invert();const f=n.point({x:i,y:a});return{x:f.x,y:f.y,width:l-i,height:m-a,rotation:t}},b=n(o=>{var n,i;const{element:s,store:a}=o,[l,c]=r.useState(!1),d=s.isSelectedDirectly,p="group"===(null===(n=s.parent)||void 0===n?void 0:n.type),u="group"!==s.type||p?null:a.selectedElements,g=!!u&&1===u.length&&u[0]!==s&&u[0].top===s,[v,b]=r.useState(!1),[T,w]=r.useState(null),S=r.useCallback(e=>{w(e?e.getStage():null)},[]),M=r.useRef(void 0),k=()=>(M.current||(M.current=null==T?void 0:T.findOne("Transformer")),M.current);r.useEffect(()=>{if(T){const e=e=>{const t=e.target.findAncestor(".element",!0),o=a.getElementById(null==t?void 0:t.id()),r=null==o?void 0:o.top,n=null==r?void 0:r.id;c(n===s.id)};T.on("mouseover",e);const t=()=>{c(!1)};return T.on("mouseleave",t),()=>{T.off("mouseover",e),T.off("mouseleave",t)}}},[T]),r.useEffect(()=>{if(!g){return}const e=k();if(!T||!e){return}b(!1);const t=()=>b(!0),o=()=>b(!1);return T.on("dragstart",t),T.on("dragend",o),e.on("transformstart",t),e.on("transformend",o),()=>{T.off("dragstart",t),T.off("dragend",o),e.off("transformstart",t),e.off("transformend",o)}},[T,g]);let I=j[o.element.type];return"text"===o.element.type&&(y.renderTagTextEnabled?I=f:y.htmlRenderEnabled&&(I=m)),o.element.visible?I?t(h,{name:"element-container",ref:S,visible:s.active,listening:s.active,children:[e(I,Object.assign({},o)),(l||g)&&!d&&!p&&!v&&e(x,{element:"group"===s.type?{a:E(s,g?"rotation"in u[0]?u[0].rotation:0:(null===(i=k())||void 0===i?void 0:i.rotation())||0)}:s})]}):(console.error("Can not find component for "+o.element.type),null):null});export default b;
|
package/canvas/gif-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as a}from"mobx-react-lite";import{
|
|
1
|
+
import{jsx as t,jsxs as e,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as a}from"mobx-react-lite";import{nodeAutorun as o}from"../utils/mobx.js";import{Image as n,Group as s,Rect as h,Arc as d,Text as l}from"react-konva";import{ROLES as c}from"../model/store.js";import g from"konva";import{parseGIF as f,decompressFrames as m}from"gifuct-js";import{useCornerRadiusAndCrop as u}from"./video-element.js";import{useImageLoader as p}from"./image-element.js";import{useWorkspaceStyle as w}from"./workspace-style.js";import{applyFilter as y}from"./apply-filters.js";import{useFadeIn as x}from"./use-fadein.js";import{isTouchDevice as E}from"../utils/screen.js";function b(t,e,r){const i=e.getContext("2d"),a=r.getContext("2d");if(!i||!a){return}2===t.disposalType&&i.clearRect(0,0,e.width,e.height),r.width=t.width,r.height=t.height;const o=a.createImageData(t.width,t.height);o.data.set(t.patch),a.putImageData(o,0,0),i.drawImage(r,t.left,t.top)}const v=a(({element:r})=>{const a=Math.min(30,r.width/4,r.height/4),o=i.useRef(null);i.useEffect(()=>{const t=o.current;if(!t){return}const e=new g.Animation(e=>{t.rotate(((null==e?void 0:e.timeDiff)||0)/2)},t.getLayer());return e.start(),()=>{e.stop()}},[]);const{mediaLoadingStyle:n}=w();return e(s,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(h,{width:r.width,height:r.height,fill:n.fill}),t(d,{ref:o,x:r.width/2,y:r.height/2,fill:n.textFill,outerRadius:Math.abs(a),innerRadius:Math.max(1,a-5),angle:270})]})}),S=a(({element:r})=>{const{mediaErrorStyle:i}=w(),a=Math.max(10,Math.min(30,r.width/22));return e(s,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(h,{width:r.width,height:r.height,fill:i.fill}),t(l,{text:"Cannot load the GIF...",fontSize:a,width:r.width,height:r.height,align:"center",fill:i.textFill,verticalAlign:"middle",padding:5})]})});export const GifElement=a(({element:a,store:s})=>{var d,l;const[w,I]=i.useState(!1),M=a.isSelected,R=i.useRef(null),j=i.useRef(void 0),[C,T,z,O]=function(t){const[e,r]=i.useState([]),[a,o]=i.useState(0),[n,s]=i.useState("loading"),[h,d]=i.useState({width:0,height:0});return i.useEffect(()=>{(async()=>{try{const e=await fetch(t),i=await e.arrayBuffer(),a=f(i),n=m(a,!0),h=a.lsd.width,l=a.lsd.height;d({width:h,height:l});const c=n.map(t=>({patch:new Uint8ClampedArray(t.patch),delay:t.delay,width:t.dims.width,height:t.dims.height,left:t.dims.left,top:t.dims.top,disposalType:t.disposalType})),g=c.reduce((t,e)=>t+e.delay,0);r(c),o(g),s("loaded")}catch(e){console.error("Failed to load GIF:",e),s("failed")}})()},[t]),[e,a,h,n]}(a.src);p(O,a.src,a.id),i.useEffect(()=>(j.current=document.createElement("canvas"),()=>{j.current&&g.Util.releaseCanvas(j.current)}),[]),i.useEffect(()=>{if("loaded"===O&&j.current&&(j.current.width=z.width,j.current.height=z.height,C.length>0)){const t=j.current.getContext("2d");if(t){t.clearRect(0,0,z.width,z.height);const e=document.createElement("canvas");b(C[0],j.current,e)}}},[z,O,C]),i.useEffect(()=>{var t;if(!C.length||!j.current){return}const e=j.current;e.width=z.width,e.height=z.height;const r=document.createElement("canvas"),i=e.getContext("2d");i&&i.clearRect(0,0,e.width,e.height);let n=-1;b(C[0],e,r),L(),n=0;const h=t=>{const i=(t=>{const e=t%T;let r=0;for(let i=0;i<C.length;i++){if(r+=C[i].delay,r>e){return i}}return 0})(t);i!==n&&(b(C[i],e,r),L(),R.current.getLayer().draw(),n=i)};if(s.isPlaying||(null===(t=a.page)||void 0===t?void 0:t._exportingOrRendering)){return o(a,()=>{h(s.currentTime-a.page.startTime)})}{const t=window.setInterval(()=>{h(s.currentTime||performance.now())},16);return()=>{clearInterval(t)}}},[s.isPlaying,C,T,null===(d=a.page)||void 0===d?void 0:d._exportingOrRendering]),i.useEffect(()=>{T&&s.history.ignore(()=>{a.set({duration:T})})},[T]);let{cropX:D,cropY:X,cropWidth:Y,cropHeight:F}=a;"loaded"!==O&&(D=X=0,Y=F=1);const _={x:z.width*D,y:z.height*X,width:z.width*Y,height:z.height*F},k=null!==(l=a.cornerRadius)&&void 0!==l?l:0,[A,L]=u(a,j.current,_,s._elementsPixelRatio,k,w||a._cropModeEnabled);i.useLayoutEffect(()=>{if(!w&&!a._cropModeEnabled&&R.current){return y(R.current,a),o(a,()=>{y(R.current,a)},{delay:100})}},[j.current,w,Y,F,a._cropModeEnabled,z.width,z.height]);const B="loading"===O,G="failed"===O,P=B||G?0:a.a.opacity;x(R,P);const U=a.selectable||s.role===c.ADMIN,W=E();return e(r,{children:[B&&t(v,{element:a}),G&&t(S,{element:a}),t(n,{ref:R,name:"element",id:a.id,image:A,x:a.a.x,y:a.a.y,width:a.a.width||1,height:a.a.height||1,rotation:a.a.rotation,opacity:P,shadowEnabled:a.shadowEnabled,shadowBlur:a.shadowBlur,shadowOffsetX:a.shadowOffsetX,shadowOffsetY:a.shadowOffsetY,shadowColor:a.shadowColor,shadowOpacity:a.shadowOpacity,customCrop:_,listening:U,draggable:W?a.draggable&&M:a.draggable,preventDefault:!W||M,hideInExport:!a.showInExport,onDragMove:t=>{a.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{a.set({x:t.target.x(),y:t.target.y()})},onTransformStart:()=>I(!0),onTransform:t=>{const e=t.currentTarget,r=Math.abs(e.scaleX()-1)<1e-7?1:e.scaleX(),i=Math.abs(e.scaleY()-1)<1e-7?1:e.scaleY();e.scaleX(1),e.scaleY(1),a.set({x:e.x(),y:e.y(),width:e.width()*r,height:e.height()*i,rotation:e.rotation()})},onTransformEnd:()=>I(!1)}),t(h,{x:a.a.x,y:a.a.y,width:Math.max(a.a.width-a.borderSize,0),height:Math.max(a.a.height-a.borderSize,0),opacity:P,offsetX:-a.borderSize/2,offsetY:-a.borderSize/2,stroke:a.borderColor,strokeWidth:a.borderSize,listening:!1,visible:!!a.borderSize,rotation:a.rotation,cornerRadius:Math.max(0,k-a.borderSize),hideInExport:!a.showInExport})]})});
|
package/canvas/hotkeys.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
import { StoreType } from '../model/store.js';
|
|
2
|
+
import { TableElementType } from '../model/table-model.js';
|
|
3
|
+
export declare function getWorkspaceEventScope(store: StoreType): {
|
|
4
|
+
handle: boolean;
|
|
5
|
+
table: TableElementType | null;
|
|
6
|
+
};
|
|
2
7
|
export declare function handleHotkey(e: KeyboardEvent, store: StoreType): void;
|
|
8
|
+
export declare function handleCopyEvent(e: ClipboardEvent, store: StoreType): void;
|
|
9
|
+
export declare function handleCutEvent(e: ClipboardEvent, store: StoreType): void;
|
|
10
|
+
export declare function handlePasteEvent(e: ClipboardEvent, store: StoreType): void;
|
package/canvas/hotkeys.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ROLES as e}from"../model/store.js";import{
|
|
1
|
+
import{ROLES as e}from"../model/store.js";import{copyToEvent as t,cutToEvent as o,pasteFromEvent as l,insertTextElement as n}from"../utils/clipboard.js";import{duplicateElements as r}from"../utils/duplicate.js";import{alignBottom as i,alignCenter as a,alignLeft as c,alignMiddle as s,alignRight as d,alignTop as u}from"../utils/alignment.js";import{removeTags as f}from"../utils/text.js";import{isBoldWeight as p}from"../utils/rich-text-html.js";const v="rgba(191, 191, 191, 100)";function y(e){if(1!==e.selectedElements.length){return null}const t=e.selectedElements[0];return"table"!==t.type?null:t}function h(e,t,o){const l=e.getCell(t,o);l&&e.focusCell(l.id)}function m(e,t,o){const l=e.getCell(t,o);l&&e.enterCellEdit(l.id)}function w(e){var t;const o=document.activeElement,l=document.querySelector(".polotno-workspace-container"),n="INPUT"===(null==o?void 0:o.tagName)||"TEXTAREA"===(null==o?void 0:o.tagName)||!!(null==o?void 0:o.isContentEditable),r=!(!o||!(null==l?void 0:l.contains(o))),i=document.activeElement===l||r;return{workspaceContainer:l,activeIsEditable:n,activeIsInsideWorkspace:r,isWorkspaceActive:i,hasOutsideTextSelection:!i&&((null===(t=window.getSelection())||void 0===t?void 0:t.toString().length)||0)>0}}export function getWorkspaceEventScope(t){if(t.role===e.VIEWER){return{handle:!1,table:null}}const o=w();if(o.activeIsEditable||o.hasOutsideTextSelection){return{handle:!1,table:null}}const l=y(t);return{handle:!0,table:l&&l._focusedCellIds.length>0&&!l._editingCellId?l:null}}export function handleHotkey(t,o){var l,f,g,D,E,k,C,x,K,b;if(o.role===e.VIEWER){return}const A=w(),R=A.activeIsEditable&&!A.activeIsInsideWorkspace,S=y(o);if(!R&&S&&function(e,t,o){const l=t._focusedCellIds.length>0,n=!!t._editingCellId;if(!l&&!n){return!1}if(n){if("Escape"===e.key){return e.preventDefault(),t.exitCellEdit(),!0}if("Tab"===e.key){e.preventDefault();const o=t.editingCell;if(t.exitCellEdit(),o){if(e.shiftKey){let e=o.col-1,l=o.row;e<0&&(l-=1,e=t.cols-1),l<0&&(l=t.rows-1,e=t.cols-1),m(t,l,e)}else{let e=o.col+1,l=o.row;e>=t.cols&&(l+=1,e=0),l>=t.rows&&(l=0,e=0),m(t,l,e)}}return!0}if(e.metaKey||e.ctrlKey){const o=t.editingCell;if(o){if("b"===e.key){return e.preventDefault(),o.set({fontWeight:p(o.fontWeight)?"normal":"bold"}),!0}if("i"===e.key){return e.preventDefault(),o.set({fontStyle:"italic"===o.fontStyle?"normal":"italic"}),!0}if("u"===e.key){e.preventDefault();const t=o.textDecoration.split(" ").filter(Boolean),l=t.includes("underline");return o.set({textDecoration:l?t.filter(e=>"underline"!==e).join(" "):[...t,"underline"].join(" ")}),!0}}}return!0}if("Escape"===e.key){return e.preventDefault(),t.clearCellFocus(),!0}const r=t.focusedCells[0];if(!r){return!1}const i=r.row,a=r.col;if("Enter"===e.key){return e.preventDefault(),t.enterCellEdit(r.id),!0}if("Tab"===e.key){if(e.preventDefault(),e.shiftKey){let e=a-1,o=i;e<0&&(o-=1,e=t.cols-1),o<0&&(o=t.rows-1,e=t.cols-1),h(t,o,e)}else{let e=a+1,o=i;e>=t.cols&&(o+=1,e=0),o>=t.rows&&(o=0,e=0),h(t,o,e)}return!0}if("ArrowRight"===e.key||"ArrowLeft"===e.key||"ArrowDown"===e.key||"ArrowUp"===e.key){if(e.preventDefault(),e.shiftKey){const o=function(e){const t=e.cells.find(t=>t.id===e._anchorCellId);if(!t){return null}const o=e.focusedCells;if(o.length<=1){return{row:t.row,col:t.col}}let l=1/0,n=-1,r=1/0,i=-1;for(const a of o){a.row<l&&(l=a.row),a.row>n&&(n=a.row),a.col<r&&(r=a.col),a.col>i&&(i=a.col)}return{row:t.row===l?n:l,col:t.col===r?i:r}}(t)||{row:i,col:a};let l=o.row,n=o.col;"ArrowRight"===e.key&&(n=Math.min(o.col+1,t.cols-1)),"ArrowLeft"===e.key&&(n=Math.max(o.col-1,0)),"ArrowDown"===e.key&&(l=Math.min(o.row+1,t.rows-1)),"ArrowUp"===e.key&&(l=Math.max(o.row-1,0)),t.focusCellRange(l,n)}else{"ArrowRight"===e.key&&h(t,i,Math.min(a+1,t.cols-1)),"ArrowLeft"===e.key&&h(t,i,Math.max(a-1,0)),"ArrowDown"===e.key&&h(t,Math.min(i+1,t.rows-1),a),"ArrowUp"===e.key&&h(t,Math.max(i-1,0),a)}return!0}const c=e.ctrlKey||e.metaKey;if(!(c||e.shiftKey||e.altKey||"Delete"!==e.key&&"Backspace"!==e.key)){return e.preventDefault(),t.focusedCells.forEach(e=>{e.set({text:""})}),!0}if(c&&e.shiftKey&&!e.altKey&&"Equal"===e.code){e.preventDefault();const l=t.getFocusedCellRange(),n=l?l.maxRow+1:i+1;return o.history.transaction(()=>{t.addRow(n)}),!0}if(c&&e.shiftKey&&e.altKey&&"Equal"===e.code){e.preventDefault();const l=t.getFocusedCellRange(),n=l?l.maxCol+1:a+1;return o.history.transaction(()=>{t.addColumn(n)}),!0}if(c&&!e.shiftKey&&"Backspace"===e.code){const l=t.getFocusedCellRange();if(l&&0===l.minCol&&l.maxCol===t.cols-1&&t.rows>1){return e.preventDefault(),o.history.transaction(()=>{t.removeRowRange(l.minRow,l.maxRow)}),!0}}if(c&&e.shiftKey&&"Backspace"===e.code){const l=t.getFocusedCellRange();if(l&&0===l.minRow&&l.maxRow===t.rows-1&&t.cols>1){return e.preventDefault(),o.history.transaction(()=>{t.removeColumnRange(l.minCol,l.maxCol)}),!0}}return c&&"KeyA"===e.code?(e.preventDefault(),t.cells.forEach(e=>{t.focusCell(e.id,!0)}),!0):!c||"z"!==e.key.toLowerCase()&&"y"!==e.key.toLowerCase()}(t,S,o)){return}if(A.activeIsEditable){return}if(A.hasOutsideTextSelection){return}if("Alt"===t.key){const e=A.workspaceContainer;return void((A.isWorkspaceActive||o.distanceGuidesVisible||e&&e.matches(":hover"))&&t.preventDefault())}const W=o.selectedElements.filter(e=>e.removable).map(e=>e.id);46!==t.keyCode&&8!==t.keyCode||o.deleteElements(W);const I=t.ctrlKey||t.metaKey,T=t.shiftKey,L=t.altKey;if("Escape"===t.key){return t.preventDefault(),void("draw"===o.tool?o.setTool("selection"):o.selectElements([]))}if(I&&!T&&"z"===t.key.toLowerCase()){return t.preventDefault(),void o.history.undo()}if(I&&(T&&"z"===t.key.toLowerCase()||"y"===t.key.toLowerCase())){return t.preventDefault(),void o.history.redo()}if(I&&"KeyA"===t.code){t.preventDefault();const e=null===(l=o.activePage)||void 0===l?void 0:l.children.filter(e=>e.selectable),n=(null==e?void 0:e.map(e=>e.id))||[];o.selectElements(n)}if("ArrowDown"===t.code){t.preventDefault();const e=t.shiftKey?10:1;o.selectedShapes.forEach(t=>{t.draggable&&t.set({y:t.y+e})})}if("ArrowUp"===t.code){t.preventDefault();const e=t.shiftKey?10:1;o.selectedShapes.forEach(t=>{t.draggable&&t.set({y:t.y-e})})}if("ArrowLeft"===t.code){t.preventDefault();const e=t.shiftKey?10:1;o.selectedShapes.forEach(t=>{t.draggable&&t.set({x:t.x-e})})}if("ArrowRight"===t.code){t.preventDefault();const e=t.shiftKey?10:1;o.selectedShapes.forEach(t=>{t.draggable&&t.set({x:t.x+e})})}if(I&&"KeyG"===t.code){t.preventDefault();const e=o.selectedElements[0];if(e&&"group"===e.type){const t=e;o.ungroupElements([t.id])}else{o.groupElements(o.selectedElements.map(e=>e.id))}}if(I&&"KeyD"===t.code&&(t.preventDefault(),r(o.selectedElements,o)),"KeyT"!==t.code||I||(t.preventDefault(),n(o,"Sample Text",{fontFamily:"Roboto"})),"KeyR"===t.code&&!I){t.preventDefault();const e={type:"figure",x:o.width/4,y:o.height/4,width:300,height:300,fill:v,stroke:"#0c0c0c",strokeWidth:0,subType:"rect"};null===(f=o.activePage)||void 0===f||f.addElement(e)}if("KeyL"===t.code&&!I){t.preventDefault();const e=(null!==(D=null===(g=o.activePage)||void 0===g?void 0:g.computedWidth)&&void 0!==D?D:0)/3,l={type:"line",x:(null!==(k=null===(E=o.activePage)||void 0===E?void 0:E.computedWidth)&&void 0!==k?k:0)/2-e/2,y:(null!==(x=null===(C=o.activePage)||void 0===C?void 0:C.computedHeight)&&void 0!==x?x:0)/2,width:e,color:v};null===(K=o.activePage)||void 0===K||K.addElement(l)}if("KeyO"===t.code&&!I){t.preventDefault(),t.preventDefault();const e={type:"figure",x:o.width/4,y:o.height/4,width:300,height:300,fill:v,stroke:"#0c0c0c",strokeWidth:0,subType:"circle"};null===(b=o.activePage)||void 0===b||b.addElement(e)}I&&"Equal"===t.code&&(t.preventDefault(),o.setScale(o.scale+.1)),I&&"Minus"===t.code&&(t.preventDefault(),o.setScale(o.scale-.1)),L&&("KeyA"===t.code&&(t.preventDefault(),c(o)),"KeyD"===t.code&&(t.preventDefault(),d(o)),"KeyS"===t.code&&(t.preventDefault(),i(o)),"KeyW"===t.code&&(t.preventDefault(),u(o)),"KeyV"===t.code&&(t.preventDefault(),s(o)),"KeyH"===t.code&&(t.preventDefault(),a(o))),"BracketRight"===t.code&&(t.preventDefault(),o.selectedElements.forEach(e=>I?e.moveUp():e.moveTop())),"BracketLeft"===t.code&&(t.preventDefault(),o.selectedElements.forEach(e=>I?e.moveDown():e.moveBottom()))}function g(e,t){const o=e.focusedCells.map(e=>f(e.text)).join("\n");t.clipboardData.setData("text/plain",o||" "),t.preventDefault()}export function handleCopyEvent(e,o){const l=getWorkspaceEventScope(o);l.handle&&e.clipboardData&&(l.table?g(l.table,e):t(o,e))}export function handleCutEvent(e,t){const l=getWorkspaceEventScope(t);if(l.handle&&e.clipboardData){if(l.table){const o=l.table;return g(o,e),void t.history.transaction(()=>{o.focusedCells.forEach(e=>e.set({text:""}))})}o(t,e)}}export function handlePasteEvent(e,t){const o=getWorkspaceEventScope(t);if(!o.handle){return}const n=o.table;l(t,e,{onText:n?e=>{var t;return null===(t=n.focusedCells[0])||void 0===t?void 0:t.set({text:e})}:void 0})}
|
package/canvas/html-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{Group as r,Image as a,Path as s,Rect as l}from"react-konva";import c from"konva";import*as f from"mobx";import{isAlive as h}from"mobx-state-tree";import{flags as d}from"../utils/flags.js";import{applyFilter as u}from"./apply-filters.js";import{getLineHeight as g,useFontFamiliesLoader as m,usePrevious as x}from"./text-element.js";import{getCurvePath as y}from"../utils/text-html.js";import{useColor as p}from"./use-color.js";import{useWorkspaceStyle as w}from"./workspace-style.js";import{detectSize as v,detectLineRects as b,htmlToCanvas as E}from"../utils/html2canvas.js";import{generateBackgroundShapeFromRects as S}from"../utils/background-shape.js";import{useFadeIn as z}from"./use-fadein.js";import{Html as k}from"react-konva-utils";import{incrementLoader as F,triggerLoadError as O}from"../utils/loader.js";import{removeTags as M}from"../utils/text.js";import*as j from"../utils/fonts.js";import{isTouchDevice as R}from"../utils/screen.js";import{getLimitedFontSize as X}from"./text-element/max-font-size.js";import{useDelayer as Y}from"./use-delayer.js";import{getHtml as I}from"../utils/text-html.js";import{normalizeRichTextHtml as C,extractFontFamiliesFromHtml as T,scaleRichTextFontSizesInHtml as A}from"../utils/rich-text-html.js";import{findFitFontSize as P}from"./text-element/fit-font-size.js";import{RichEditor as B,RichTextContainer as W,applyOpacityToColor as $,quillRef as D,createQuill as H,setQuillContent as _,setQuillFormats as L,syncQuillFormatState as J,setCursorFromCoords as N}from"./rich-editor.js";export{D as quillRef,H as createQuill,_ as setQuillContent,L as setQuillFormats,J as syncQuillFormatState,N as setCursorFromCoords};function q(t){const e=document.createElement("canvas"),o=e.getContext("2d");return null==o||o.drawImage(t,0,0,e.width,e.height),function(t){return!function(t){const e=t.getContext("2d").getImageData(0,0,t.width,t.height).data;for(let o=0;o<e.length;o+=4){if(0!==e[o+3]){return!0}}return!1}(t)}(e)}const V=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),G=navigator.userAgent.includes("Firefox");export const HTMLElement=n(({element:n,store:D})=>{var H,_;const{textOverflowIndicatorStyle:L}=w(),J=i.useRef(null),[N,K]=i.useState(),[Q,U]=i.useState(!1),[Z,tt]=i.useState(!1),et=i.useRef(n.height),ot=n.isSelected,it=x(ot),nt=n.fontSize/3,{textVerticalResizeEnabled:rt}=d,at=d.autoDeleteEmptyText,st=x(n.fontFamily),lt=i.useMemo(()=>C(n.text,{fontSize:n.fontSize,fontFamily:n.fontFamily}),[n.text,n.fontSize,n.fontFamily]),ct=i.useMemo(()=>[...new Set([n.fontFamily,...T(lt)])].filter(Boolean),[n.fontFamily,lt]),[ft]=m(D,ct,n.fontStyle,n.fontWeight,n.text||n.placeholder),ht=n._editModeEnabled;z(J);const dt=ft?n.fontFamily:st!==n.fontFamily?st:"Arial",ut=p(n).fill,gt=I(n,{fontFamily:dt,color:ut}),mt=i.useRef([]),xt=i.useRef(!0),[,yt]=i.useReducer(t=>t+1,0);i.useEffect(()=>{const t=mt.current;t.length>0&&(mt.current=[],t.forEach(t=>t()))}),i.useEffect(()=>()=>{xt.current=!1;const t=mt.current;t.length>0&&(mt.current=[],t.forEach(t=>t()))},[]);let{width:pt,height:wt}=function(t,e,o){return i.useMemo(()=>v(t),[t,e.width,o])}(gt,n,ft);i.useEffect(()=>{if(!ft){return}const t=(t,e,o,i)=>{const r=F(`text ${n.id}`),a=()=>{D.history.ignore(t,e,o).then(()=>{xt.current?(mt.current.push(r),yt()):r()})};i?queueMicrotask(a):a()};if(n.curveEnabled&&Math.abs(pt-n.width)>1&&!Q&&t(()=>{if(h(n)&&Math.abs(pt-n.width)>1){const t=n.x+n.width/2;n.set({width:pt,x:t-pt/2})}},!1,!0),!n.height){return void t(()=>{h(n)&&(n.height||n.set({height:wt}))},void 0,void 0,!0)}const{textOverflow:e}=d;if("change-font-size"!==e||Q||ht||n.curveEnabled){"resize"===e&&(rt&&n.height<wt&&!Q&&t(()=>{h(n)&&n.set({height:wt})},!1,!0),rt||n.height===wt||Q||t(()=>{h(n)&&n.set({height:wt})},!1,!0))}else{const e=P(n,{fontFamily:n.fontFamily});e.fontSize!==n.fontSize?t(()=>{if(!h(n)){return}const t={fontSize:e.fontSize};void 0!==e.text&&e.text!==n.text&&(t.text=e.text),n.set(t)},!1,!0):n.height!==wt&&(rt&&n.height<wt?t(()=>{h(n)&&n.set({height:wt})},!1,!0):rt||t(()=>{h(n)&&n.set({height:wt})},!1,!0))}});const vt=i.useMemo(()=>{const t={lastArgs:null,lastResult:null};return async function(e){return t.lastArgs&&t.lastResult&&(o=t.lastArgs,i=e,JSON.stringify(o)===JSON.stringify(i))||(t.lastResult=await E(e),t.lastArgs=Object.assign({},e)),t.lastResult;var o,i}},[]),bt=i.useRef(0),Et=i.useRef(null);i.useEffect(()=>{Q||ht||(async()=>{bt.current++;const t=bt.current;let e=F(`text ${n.id} ${t}`);Et.current&&Et.current(),Et.current=e,tt(!0);let o=null;const i=V?5:1;for(let a=0;a<i;a++){const e=a>0?vt:E;try{if(o=await e({skipCache:a>0,html:gt,width:pt||n.width||1,height:n.height||wt||1,fontFamily:dt,fontFamilies:T(gt),resolveFont:t=>D.fonts.find(e=>e.fontFamily===t)||j.globalFonts.find(e=>e.fontFamily===t),padding:nt,pixelRatio:D._elementsPixelRatio,font:D.fonts.find(t=>t.fontFamily===dt)||j.globalFonts.find(t=>t.fontFamily===dt)}),t!==bt.current){return}if((V||G)&&o&&q(o)){await new Promise(t=>setTimeout(t,50*(a+1)));continue}break}catch(r){console.error(r),O(`Error rendering rich text with id ${n.id}`);break}}o?K(o):e?(e(),e=null):console.error("Finish function is called twice!"),tt(!1)})()},[gt,Q,wt,ht,dt,n.height,D._elementsPixelRatio,ft]);const[St,zt]=Y(Z,300),[kt]=Y(Q,300,!0),Ft=kt||St;i.useEffect(()=>{var t;if(!Ft){return f.autorun(()=>{const t=J.current;u(t,n)})}null===(t=J.current)||void 0===t||t.clearCache()},[N,Ft,n.shadowColor,n.shadowOffsetX,n.shadowOffsetY,n.shadowOpacity]),i.useEffect(()=>{N&&!Z&&Et.current&&(Et.current(),Et.current=null)},[N,Z]),i.useLayoutEffect(()=>{if(!ft){return}if(!n.curveEnabled){return}const t=new c.TextPath({data:y(n.a.width,n.a.height,n.curvePower,n.a.fontSize),text:M(n.text),letterSpacing:n.letterSpacing*n.a.fontSize,fontSize:n.a.fontSize,fontFamily:n.fontFamily,fontWeight:n.fontWeight,fontStyle:n.fontStyle,align:"center",textBaseline:"middle",fill:n.fill}),e=t.getSelfRect().width;if(e){const t=e-n.a.width,o=n.a.rotation*Math.PI/180,i=-t/2*Math.cos(o),r=-t/2*Math.sin(o);queueMicrotask(()=>{h(n)&&n.set({width:e,x:n.a.x+i,y:n.a.y+r})})}t.destroy()},[ft,n.curveEnabled,n.curvePower,n.text,n.fontSize,n.fontFamily,n.fontWeight,n.fontStyle,n.letterSpacing]),i.useEffect(()=>()=>{Et.current&&Et.current()},[]),i.useEffect(()=>{it&&!ot&&at&&""===M(n.text)&&n.removable&&!n.placeholder&&D.deleteElements([n.id])},[at,n.placeholder,n.removable,n.text,ot,it]);let Ot=0;"middle"===n.verticalAlign&&(Ot=(n.height-wt)/2),"bottom"===n.verticalAlign&&(Ot=n.height-wt);const Mt=g({fontLoaded:ft,fontFamily:n.fontFamily,fontSize:n.fontSize,lineHeight:n.lineHeight}),jt=n.backgroundPadding*(n.fontSize*Mt*.5),Rt=n.backgroundCornerRadius*(n.fontSize*Mt*.5),Xt=i.useMemo(()=>{if(!n.backgroundEnabled||n.curveEnabled||n.legacyBackground){return""}const t=b(gt);if(0===t.length){return""}const e=t.map(t=>({left:t.left+nt,right:t.right+nt,top:t.top+nt,bottom:t.bottom+nt}));return S({rects:e,padding:jt,cornerRadius:Rt})},[n.backgroundEnabled,n.curveEnabled,n.legacyBackground,gt,ft,jt,Rt,nt]),Yt=R(),It=y(n.a.width,wt,n.curvePower,n.fontSize),Ct=i.useRef(null),Tt=i.useRef(null),At=i.useRef(0),Pt=i.useRef(0),Bt=i.useRef(null),Wt=ht&&n.strokeWidth>0&&!n.curveEnabled,$t=pt>0?(n.a.width+2*nt)/(pt+2*nt):1;return o(e,{children:[n.curveEnabled||n.legacyBackground?t(l,{x:n.a.x,y:n.a.y,offsetX:jt/$t,offsetY:jt/$t,rotation:n.a.rotation,scaleX:$t,scaleY:$t,hideInExport:!n.showInExport,listening:!1,visible:n.backgroundEnabled,opacity:n.backgroundOpacity*n.a.opacity,fill:n.backgroundColor,width:n.width+2*jt,height:n.height+2*jt,cornerRadius:Rt}):t(s,{name:"html-background",x:n.a.x,y:n.a.y,offsetX:nt/$t,offsetY:(nt-Ot)/$t,rotation:n.a.rotation,scaleX:$t,scaleY:$t,hideInExport:!n.showInExport,listening:!1,visible:n.backgroundEnabled&&Xt.length>0,opacity:n.backgroundOpacity*n.a.opacity,fill:n.backgroundColor,data:Xt}),t(s,{x:n.a.x,y:n.a.y,rotation:n.a.rotation,data:It,stroke:L.stroke,strokeWidth:1,visible:!1}),t(l,{ref:J,name:"element",x:n.a.x,y:n.a.y,listening:n.selectable,rotation:n.a.rotation,width:n.a.width,height:n.a.height,visible:!Ft,draggable:Yt?n.draggable&&ot:n.draggable,preventDefault:!Yt||ot,opacity:ht?0:n.a.opacity,hideInExport:!n.showInExport,onDragMove:t=>{n.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{n.set({x:t.target.x(),y:t.target.y()})},id:n.id,onDblClick:t=>{n.contentEditable&&(Bt.current={x:t.evt.clientX,y:t.evt.clientY},n.toggleEditMode(!0))},onDblTap:t=>{var e;if(n.contentEditable){const o=null===(e=t.evt.changedTouches)||void 0===e?void 0:e[0];Bt.current=o?{x:o.clientX,y:o.clientY}:null,n.toggleEditMode(!0)}},onTransformStart:t=>{var e,o;U(!0),et.current=n.height;const i=null===(e=t.target.getStage())||void 0===e?void 0:e.findOne("Transformer");Tt.current=null!==(o=null==i?void 0:i.getActiveAnchor())&&void 0!==o?o:null,At.current=n.a.rotation,Pt.current=n.height},onTransform:t=>{var e;const o=t.target,i=(null===(e=o.getStage())||void 0===e?void 0:e.findOne("Transformer")).getActiveAnchor(),r="middle-left"===i||"middle-right"===i,a="top-center"===i||"bottom-center"===i,s=o.scaleX();if(r){const t=o.scaleX(),e=o.width()*t,i=n.fontSize;let r=e;e<i&&(r=i,Ct.current&&o.position(Ct.current)),o.width(r),o.scaleX(1),o.scaleY(1);const a=I(Object.assign(Object.assign({},n.toJSON()),{width:r}),{fontFamily:dt,color:ut}),s=v(a).height,l=d.textVerticalResizeEnabled?Math.max(s,et.current):s;o.height(l),n.set({width:o.width(),height:l,x:o.x(),y:o.y()})}else if(a){const t="resize"===d.textOverflow,e="number"==typeof n.lineHeight?n.lineHeight:1,i=t?wt:e*n.fontSize,r=o.height()*o.scaleY();if(r<i){if(o.height(i),Ct.current){if("top-center"===Tt.current){const t=At.current*Math.PI/180,e=Pt.current-i;o.x(Ct.current.x-e*Math.sin(t)),o.y(Ct.current.y+e*Math.cos(t))}else{o.position(Ct.current)}}}else{o.height(r)}o.scaleY(1),o.scaleX(1),Pt.current=Math.max(i,r),n.set({x:o.x(),y:o.y(),height:o.height(),rotation:o.rotation()})}else{o.scaleX(1),o.scaleY(1),n.set({fontSize:n.fontSize*s,letterSpacing:n.letterSpacing,width:o.width()*s,x:o.x(),y:o.y(),rotation:o.rotation(),height:o.height()*s,text:A(n.text,s)})}Ct.current=t.target.position()},onTransformEnd:t=>{U(!1),tt(!0);const e=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),n.set({fontSize:n.fontSize*e,width:t.target.width()*e,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),shadowBlur:n.shadowBlur*e,shadowOffsetX:n.shadowOffsetX*e,shadowOffsetY:n.shadowOffsetY*e,strokeWidth:n.strokeWidth*e,text:A(n.text,e)})}}),t(a,{ref:J,image:N,x:n.a.x,y:n.a.y,offsetX:nt,offsetY:nt-Ot,listening:!1,rotation:n.a.rotation,width:n.a.width+2*nt,height:(n.a.width+2*nt)*((null!==(H=null==N?void 0:N.height)&&void 0!==H?H:0)/((null==N?void 0:N.width)||1)||1),visible:!Ft&&!ht,opacity:n.a.opacity,shadowEnabled:n.shadowEnabled,shadowBlur:n.shadowBlur,shadowOffsetX:n.shadowOffsetX,shadowOffsetY:n.shadowOffsetY,shadowColor:n.shadowColor,shadowOpacity:n.shadowOpacity,hideInExport:!n.showInExport,editModeEnabled:n._editModeEnabled||Q||Ft}),(Ft&&!ht||Wt)&&t(r,{x:n.a.x,y:n.a.y,rotation:n.a.rotation,offsetY:-Ot,children:t(k,{divProps:{style:{pointerEvents:"none"}},children:t(W,{dangerouslySetInnerHTML:{__html:gt},style:{pointerEvents:"none",opacity:n.a.opacity,textShadow:n.shadowEnabled?`${n.shadowOffsetX}px ${n.shadowOffsetY}px ${n.shadowBlur}px ${$(n.shadowColor,null!==(_=n.shadowOpacity)&&void 0!==_?_:1)}`:void 0}})})}),ht&&t(r,{x:n.a.x,y:n.a.y,rotation:n.a.rotation,offsetY:-Ot,children:t(k,{divProps:{style:{zIndex:20}},children:t(B,{element:n,onChange:t=>{const e=X({oldText:M(n.text),newText:M(t),element:n});n.set({text:t,fontSize:e})},onBlur:t=>{h(n)&&(n.toggleEditMode(!1),zt(!0))},clickCoords:Bt.current})})})]})});
|
|
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{Group as r,Image as a,Path as s,Rect as l}from"react-konva";import c from"konva";import{isAlive as f}from"mobx-state-tree";import{nodeAutorun as h}from"../utils/mobx.js";import{flags as d}from"../utils/flags.js";import{applyFilter as u}from"./apply-filters.js";import{getLineHeight as g,useFontFamiliesLoader as m,usePrevious as x}from"./text-element.js";import{getCurvePath as y}from"../utils/text-html.js";import{useColor as p}from"./use-color.js";import{useWorkspaceStyle as w}from"./workspace-style.js";import{detectSize as v,detectLineRects as b,htmlToCanvas as E}from"../utils/html2canvas.js";import{generateBackgroundShapeFromRects as S}from"../utils/background-shape.js";import{useFadeIn as z}from"./use-fadein.js";import{Html as k}from"react-konva-utils";import{incrementLoader as F,triggerLoadError as O}from"../utils/loader.js";import{removeTags as j}from"../utils/text.js";import*as M from"../utils/fonts.js";import{isTouchDevice as R}from"../utils/screen.js";import{getLimitedFontSize as X}from"./text-element/max-font-size.js";import{useDelayer as Y}from"./use-delayer.js";import{getHtml as I}from"../utils/text-html.js";import{normalizeRichTextHtml as C,extractFontFamiliesFromHtml as T,scaleRichTextFontSizesInHtml as A}from"../utils/rich-text-html.js";import{findFitFontSize as P}from"./text-element/fit-font-size.js";import{RichEditor as B,RichTextContainer as W,applyOpacityToColor as $,quillRef as D,createQuill as H,setQuillContent as _,setQuillFormats as L,syncQuillFormatState as J,setCursorFromCoords as N}from"./rich-editor.js";export{D as quillRef,H as createQuill,_ as setQuillContent,L as setQuillFormats,J as syncQuillFormatState,N as setCursorFromCoords};function q(t){const e=document.createElement("canvas"),o=e.getContext("2d");return null==o||o.drawImage(t,0,0,e.width,e.height),function(t){return!function(t){const e=t.getContext("2d").getImageData(0,0,t.width,t.height).data;for(let o=0;o<e.length;o+=4){if(0!==e[o+3]){return!0}}return!1}(t)}(e)}const V=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),G=navigator.userAgent.includes("Firefox");export const HTMLElement=n(({element:n,store:D})=>{var H,_;const{textOverflowIndicatorStyle:L}=w(),J=i.useRef(null),[N,K]=i.useState(),[Q,U]=i.useState(!1),[Z,tt]=i.useState(!1),et=i.useRef(n.height),ot=n.isSelected,it=x(ot),nt=n.fontSize/3,{textVerticalResizeEnabled:rt}=d,at=d.autoDeleteEmptyText,st=x(n.fontFamily),lt=i.useMemo(()=>C(n.text,{fontSize:n.fontSize,fontFamily:n.fontFamily}),[n.text,n.fontSize,n.fontFamily]),ct=i.useMemo(()=>[...new Set([n.fontFamily,...T(lt)])].filter(Boolean),[n.fontFamily,lt]),[ft]=m(D,ct,n.fontStyle,n.fontWeight,n.text||n.placeholder),ht=n._editModeEnabled;z(J);const dt=ft?n.fontFamily:st!==n.fontFamily?st:"Arial",ut=p(n).fill,gt=I(n,{fontFamily:dt,color:ut}),mt=i.useRef([]),xt=i.useRef(!0),[,yt]=i.useReducer(t=>t+1,0);i.useEffect(()=>{const t=mt.current;t.length>0&&(mt.current=[],t.forEach(t=>t()))}),i.useEffect(()=>()=>{xt.current=!1;const t=mt.current;t.length>0&&(mt.current=[],t.forEach(t=>t()))},[]);let{width:pt,height:wt}=function(t,e,o){return i.useMemo(()=>v(t),[t,e.width,o])}(gt,n,ft);i.useEffect(()=>{if(!ft){return}const t=(t,e,o,i)=>{const r=F(`text ${n.id}`),a=()=>{D.history.ignore(t,e,o).then(()=>{xt.current?(mt.current.push(r),yt()):r()})};i?queueMicrotask(a):a()};if(n.curveEnabled&&Math.abs(pt-n.width)>1&&!Q&&t(()=>{if(f(n)&&Math.abs(pt-n.width)>1){const t=n.x+n.width/2;n.set({width:pt,x:t-pt/2})}},!1,!0),!n.height){return void t(()=>{f(n)&&(n.height||n.set({height:wt}))},void 0,void 0,!0)}const{textOverflow:e}=d;if("change-font-size"!==e||Q||ht||n.curveEnabled){"resize"===e&&(rt&&n.height<wt&&!Q&&t(()=>{f(n)&&n.set({height:wt})},!1,!0),rt||n.height===wt||Q||t(()=>{f(n)&&n.set({height:wt})},!1,!0))}else{const e=P(n,{fontFamily:n.fontFamily});e.fontSize!==n.fontSize?t(()=>{if(!f(n)){return}const t={fontSize:e.fontSize};void 0!==e.text&&e.text!==n.text&&(t.text=e.text),n.set(t)},!1,!0):n.height!==wt&&(rt&&n.height<wt?t(()=>{f(n)&&n.set({height:wt})},!1,!0):rt||t(()=>{f(n)&&n.set({height:wt})},!1,!0))}});const vt=i.useMemo(()=>{const t={lastArgs:null,lastResult:null};return async function(e){return t.lastArgs&&t.lastResult&&(o=t.lastArgs,i=e,JSON.stringify(o)===JSON.stringify(i))||(t.lastResult=await E(e),t.lastArgs=Object.assign({},e)),t.lastResult;var o,i}},[]),bt=i.useRef(0),Et=i.useRef(null);i.useEffect(()=>{Q||ht||(async()=>{bt.current++;const t=bt.current;let e=F(`text ${n.id} ${t}`);Et.current&&Et.current(),Et.current=e,tt(!0);let o=null;const i=V?5:1;for(let a=0;a<i;a++){const e=a>0?vt:E;try{if(o=await e({skipCache:a>0,html:gt,width:pt||n.width||1,height:n.height||wt||1,fontFamily:dt,fontFamilies:T(gt),resolveFont:t=>D.fonts.find(e=>e.fontFamily===t)||M.globalFonts.find(e=>e.fontFamily===t),padding:nt,pixelRatio:D._elementsPixelRatio,font:D.fonts.find(t=>t.fontFamily===dt)||M.globalFonts.find(t=>t.fontFamily===dt)}),t!==bt.current){return}if((V||G)&&o&&q(o)){await new Promise(t=>setTimeout(t,50*(a+1)));continue}break}catch(r){console.error(r),O(`Error rendering rich text with id ${n.id}`);break}}o?K(o):e?(e(),e=null):console.error("Finish function is called twice!"),tt(!1)})()},[gt,Q,wt,ht,dt,n.height,D._elementsPixelRatio,ft]);const[St,zt]=Y(Z,300),[kt]=Y(Q,300,!0),Ft=kt||St;i.useEffect(()=>{var t;if(!Ft){return h(n,()=>{const t=J.current;u(t,n)})}null===(t=J.current)||void 0===t||t.clearCache()},[N,Ft,n.shadowColor,n.shadowOffsetX,n.shadowOffsetY,n.shadowOpacity]),i.useEffect(()=>{N&&!Z&&Et.current&&(Et.current(),Et.current=null)},[N,Z]),i.useLayoutEffect(()=>{if(!ft){return}if(!n.curveEnabled){return}const t=new c.TextPath({data:y(n.a.width,n.a.height,n.curvePower,n.a.fontSize),text:j(n.text),letterSpacing:n.letterSpacing*n.a.fontSize,fontSize:n.a.fontSize,fontFamily:n.fontFamily,fontWeight:n.fontWeight,fontStyle:n.fontStyle,align:"center",textBaseline:"middle",fill:n.fill}),e=t.getSelfRect().width;if(e){const t=e-n.a.width,o=n.a.rotation*Math.PI/180,i=-t/2*Math.cos(o),r=-t/2*Math.sin(o);queueMicrotask(()=>{f(n)&&n.set({width:e,x:n.a.x+i,y:n.a.y+r})})}t.destroy()},[ft,n.curveEnabled,n.curvePower,n.text,n.fontSize,n.fontFamily,n.fontWeight,n.fontStyle,n.letterSpacing]),i.useEffect(()=>()=>{Et.current&&Et.current()},[]),i.useEffect(()=>{it&&!ot&&at&&""===j(n.text)&&n.removable&&!n.placeholder&&D.deleteElements([n.id])},[at,n.placeholder,n.removable,n.text,ot,it]);let Ot=0;"middle"===n.verticalAlign&&(Ot=(n.height-wt)/2),"bottom"===n.verticalAlign&&(Ot=n.height-wt);const jt=g({fontLoaded:ft,fontFamily:n.fontFamily,fontSize:n.fontSize,lineHeight:n.lineHeight}),Mt=n.backgroundPadding*(n.fontSize*jt*.5),Rt=n.backgroundCornerRadius*(n.fontSize*jt*.5),Xt=i.useMemo(()=>{if(!n.backgroundEnabled||n.curveEnabled||n.legacyBackground){return""}const t=b(gt);if(0===t.length){return""}const e=t.map(t=>({left:t.left+nt,right:t.right+nt,top:t.top+nt,bottom:t.bottom+nt}));return S({rects:e,padding:Mt,cornerRadius:Rt})},[n.backgroundEnabled,n.curveEnabled,n.legacyBackground,gt,ft,Mt,Rt,nt]),Yt=R(),It=y(n.a.width,wt,n.curvePower,n.fontSize),Ct=i.useRef(null),Tt=i.useRef(null),At=i.useRef(0),Pt=i.useRef(0),Bt=i.useRef(null),Wt=ht&&n.strokeWidth>0&&!n.curveEnabled,$t=pt>0?(n.a.width+2*nt)/(pt+2*nt):1;return o(e,{children:[n.curveEnabled||n.legacyBackground?t(l,{x:n.a.x,y:n.a.y,offsetX:Mt/$t,offsetY:Mt/$t,rotation:n.a.rotation,scaleX:$t,scaleY:$t,hideInExport:!n.showInExport,listening:!1,visible:n.backgroundEnabled,opacity:n.backgroundOpacity*n.a.opacity,fill:n.backgroundColor,width:n.width+2*Mt,height:n.height+2*Mt,cornerRadius:Rt}):t(s,{name:"html-background",x:n.a.x,y:n.a.y,offsetX:nt/$t,offsetY:(nt-Ot)/$t,rotation:n.a.rotation,scaleX:$t,scaleY:$t,hideInExport:!n.showInExport,listening:!1,visible:n.backgroundEnabled&&Xt.length>0,opacity:n.backgroundOpacity*n.a.opacity,fill:n.backgroundColor,data:Xt}),t(s,{x:n.a.x,y:n.a.y,rotation:n.a.rotation,data:It,stroke:L.stroke,strokeWidth:1,visible:!1}),t(l,{ref:J,name:"element",x:n.a.x,y:n.a.y,listening:n.selectable,rotation:n.a.rotation,width:n.a.width,height:n.a.height,visible:!Ft,draggable:Yt?n.draggable&&ot:n.draggable,preventDefault:!Yt||ot,opacity:ht?0:n.a.opacity,hideInExport:!n.showInExport,onDragMove:t=>{n.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{n.set({x:t.target.x(),y:t.target.y()})},id:n.id,onDblClick:t=>{n.contentEditable&&(Bt.current={x:t.evt.clientX,y:t.evt.clientY},n.toggleEditMode(!0))},onDblTap:t=>{var e;if(n.contentEditable){const o=null===(e=t.evt.changedTouches)||void 0===e?void 0:e[0];Bt.current=o?{x:o.clientX,y:o.clientY}:null,n.toggleEditMode(!0)}},onTransformStart:t=>{var e,o;U(!0),et.current=n.height;const i=null===(e=t.target.getStage())||void 0===e?void 0:e.findOne("Transformer");Tt.current=null!==(o=null==i?void 0:i.getActiveAnchor())&&void 0!==o?o:null,At.current=n.a.rotation,Pt.current=n.height},onTransform:t=>{var e;const o=t.target,i=(null===(e=o.getStage())||void 0===e?void 0:e.findOne("Transformer")).getActiveAnchor(),r="middle-left"===i||"middle-right"===i,a="top-center"===i||"bottom-center"===i,s=o.scaleX();if(r){const t=o.scaleX(),e=o.width()*t,i=n.fontSize;let r=e;e<i&&(r=i,Ct.current&&o.position(Ct.current)),o.width(r),o.scaleX(1),o.scaleY(1);const a=I(Object.assign(Object.assign({},n.toJSON()),{width:r}),{fontFamily:dt,color:ut}),s=v(a).height,l=d.textVerticalResizeEnabled?Math.max(s,et.current):s;o.height(l),n.set({width:o.width(),height:l,x:o.x(),y:o.y()})}else if(a){const t="resize"===d.textOverflow,e="number"==typeof n.lineHeight?n.lineHeight:1,i=t?wt:e*n.fontSize,r=o.height()*o.scaleY();if(r<i){if(o.height(i),Ct.current){if("top-center"===Tt.current){const t=At.current*Math.PI/180,e=Pt.current-i;o.x(Ct.current.x-e*Math.sin(t)),o.y(Ct.current.y+e*Math.cos(t))}else{o.position(Ct.current)}}}else{o.height(r)}o.scaleY(1),o.scaleX(1),Pt.current=Math.max(i,r),n.set({x:o.x(),y:o.y(),height:o.height(),rotation:o.rotation()})}else{o.scaleX(1),o.scaleY(1),n.set({fontSize:n.fontSize*s,letterSpacing:n.letterSpacing,width:o.width()*s,x:o.x(),y:o.y(),rotation:o.rotation(),height:o.height()*s,text:A(n.text,s)})}Ct.current=t.target.position()},onTransformEnd:t=>{U(!1),tt(!0);const e=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),n.set({fontSize:n.fontSize*e,width:t.target.width()*e,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),shadowBlur:n.shadowBlur*e,shadowOffsetX:n.shadowOffsetX*e,shadowOffsetY:n.shadowOffsetY*e,strokeWidth:n.strokeWidth*e,text:A(n.text,e)})}}),t(a,{ref:J,image:N,x:n.a.x,y:n.a.y,offsetX:nt,offsetY:nt-Ot,listening:!1,rotation:n.a.rotation,width:n.a.width+2*nt,height:(n.a.width+2*nt)*((null!==(H=null==N?void 0:N.height)&&void 0!==H?H:0)/((null==N?void 0:N.width)||1)||1),visible:!Ft&&!ht,opacity:n.a.opacity,shadowEnabled:n.shadowEnabled,shadowBlur:n.shadowBlur,shadowOffsetX:n.shadowOffsetX,shadowOffsetY:n.shadowOffsetY,shadowColor:n.shadowColor,shadowOpacity:n.shadowOpacity,hideInExport:!n.showInExport,editModeEnabled:n._editModeEnabled||Q||Ft}),(Ft&&!ht||Wt)&&t(r,{x:n.a.x,y:n.a.y,rotation:n.a.rotation,offsetY:-Ot,children:t(k,{divProps:{style:{pointerEvents:"none"}},children:t(W,{dangerouslySetInnerHTML:{__html:gt},style:{pointerEvents:"none",opacity:n.a.opacity,textShadow:n.shadowEnabled?`${n.shadowOffsetX}px ${n.shadowOffsetY}px ${n.shadowBlur}px ${$(n.shadowColor,null!==(_=n.shadowOpacity)&&void 0!==_?_:1)}`:void 0}})})}),ht&&t(r,{x:n.a.x,y:n.a.y,rotation:n.a.rotation,offsetY:-Ot,children:t(k,{divProps:{style:{zIndex:20}},children:t(B,{element:n,onChange:t=>{const e=X({oldText:j(n.text),newText:j(t),element:n});n.set({text:t,fontSize:e})},onBlur:t=>{f(n)&&(n.toggleEditMode(!1),zt(!0))},clickCoords:Bt.current})})})]})});
|
package/canvas/image-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e,Fragment as r}from"react/jsx-runtime";import a from"react";import{observer as o}from"mobx-react-lite";import{autorun as i}from"mobx";import{Arc as n,Group as h,Image as d,Rect as s,Text as c,Transformer as l}from"react-konva";import{ROLES as g}from"../model/store.js";import u from"use-image";import f from"konva";import{Portal as p}from"react-konva-utils";import{useWorkspaceStyle as m}from"./workspace-style.js";import{incrementLoader as w,triggerLoadError as x}from"../utils/loader.js";import*as y from"../utils/svg.js";import{flags as M}from"../utils/flags.js";import{trySetCanvasSize as v}from"../utils/canvas.js";import{applyFilter as b}from"./apply-filters.js";import{useFadeIn as E}from"./use-fadein.js";import{isTouchDevice as S}from"../utils/screen.js";import{useDelayer as I}from"./use-delayer.js";import{useColor as R}from"./use-color.js";function C(){return document.createElement("canvas")}const X=t=>t.indexOf("data:image/svg+xml")>=0||t.indexOf(".svg")>=0;export const useSizeFixer=t=>{const[e,r]=a.useState(t);return a.useEffect(()=>{(async()=>{const a=await async function(t){if(!X(t)){return t}const e=await y.urlToString(t),r=y.fixSize(e);return y.svgToURL(r)}(t);a!==e&&r(a)})()},[t]),e};function Y(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}const O=(t,e)=>e.width<5||e.height<5?t:e,T={keepRatio:!1,rotateEnabled:!1,boundBoxFunc:O},D={enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],rotateEnabled:!1,borderEnabled:!1,boundBoxFunc:O};const A=(t,e,r)=>Math.max(e,Math.min(r,t));export const useCornerRadiusAndCrop=(t,e,r,o,i=0,n=!1,h=!0)=>{var d,s;const c=Math.floor(A(t.a.width*o,1,1e4)),l=Math.floor(A(t.a.height*o,1,1e4)),g=Math.min(i*o,c/2,l/2),u=Math.max(t.a.width/r.width,t.a.height/r.height)*o,p=(null===(d=t.page)||void 0===d?void 0:d._exportingOrRendering)&&M.imageDownScalingEnabled&&u<1&&!n,m=0===r.x&&0===r.y&&r.width===(null==e?void 0:e.width)&&r.height===(null==e?void 0:e.height),w=a.useMemo(()=>{if(e&&e.width&&e.height){return m&&0===g&&!p?void 0:C()}},[e,g,p,m]);return a.useLayoutEffect(()=>{if(!w||!e){return}v(w,c,l);const t=w.getContext("2d");if(!t){return}g&&(t.beginPath(),t.moveTo(g,0),t.lineTo(c-g,0),t.arc(c-g,g,g,3*Math.PI/2,0,!1),t.lineTo(c,l-g),t.arc(c-g,l-g,g,0,Math.PI/2,!1),t.lineTo(g,l),t.arc(g,l-g,g,Math.PI/2,Math.PI,!1),t.lineTo(0,g),t.arc(g,g,g,Math.PI,3*Math.PI/2,!1),t.clip());const a=p?function(t,e){var r,a;const o=C();o.width=t.width,o.height=t.height;const i=Math.max(1,Math.floor(o.width*e)),n=Math.max(1,Math.floor(o.height*e));null===(r=o.getContext("2d"))||void 0===r||r.drawImage(t,0,0,o.width,o.height);const h=function(t,e,r,a,o,i,n){for(var h=new ImageData(e,r),d=new Int32Array(t.data.buffer),s=t.width,c=new Int32Array(h.data.buffer),l=h.width,g=e/i,u=r/n,f=Math.round(1/g),p=Math.round(1/u),m=f*p,w=0;w<h.height;w++){for(var x=0;x<l;x++){for(var y=0+Math.round(x/g)+(0+Math.round(w/u))*s,M=0,v=0,b=0,E=0,S=0;S<p;S++){for(var I=0;I<f;I++){var R=d[y+I+S*s];M+=R<<24>>>24,v+=R<<16>>>24,b+=R<<8>>>24,E+=R>>>24}}M=Math.round(M/m),v=Math.round(v/m),b=Math.round(b/m),E=Math.round(E/m),c[x+w*l]=E<<24|b<<16|v<<8|M}}return h}(o.getContext("2d").getImageData(0,0,o.width,o.height),i,n,0,0,o.width,o.height);return o.width=i,o.height=n,null===(a=o.getContext("2d"))||void 0===a||a.putImageData(h,0,0),o}(e,u):e,o=p?{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;t.drawImage(a,o.x,o.y,o.width,o.height,0,0,w.width,w.height)},[w,t.a.width,t.a.height,r.x,r.y,r.width,r.height,i,o,n,null===(s=t.page)||void 0===s?void 0:s._exportingOrRendering,p]),a.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&f.Util.releaseCanvas(w)},[w]),w||e};const L=C(),W=o(({element:r})=>{const o=Math.min(30,r.a.width/4,r.a.height/4),i=a.useRef(null);a.useEffect(()=>{const t=i.current;if(!t){return}const e=new f.Animation(e=>{t.rotate(((null==e?void 0:e.timeDiff)||0)/2)},t.getLayer());return e.start(),()=>{e.stop()}});const{mediaLoadingStyle:d}=m();return e(h,{x:r.x,y:r.y,rotation:r.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(s,{width:r.a.width,height:r.a.height,fill:d.fill}),t(n,{ref:i,x:r.a.width/2,y:r.a.height/2,fill:d.textFill,outerRadius:Math.abs(o),innerRadius:Math.max(1,o-5),angle:270})]})}),_=o(({element:r})=>{const{mediaErrorStyle:a}=m(),o=Math.max(10,Math.min(30,r.a.width/25));return e(h,{x:r.x,y:r.y,rotation:r.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(s,{width:r.a.width,height:r.a.height,fill:a.fill}),t(c,{text:"Can not load the image...",fontSize:o,width:r.a.width,height:r.a.height,align:"center",fill:a.textFill,verticalAlign:"middle",padding:5})]})});let j=u;export const setImageLoaderHook=t=>{j=t};export const useImageLoader=(t,e="",r="")=>{const o=a.useRef(void 0),i=()=>{var t;null===(t=o.current)||void 0===t||t.call(o),o.current=void 0};a.useEffect(()=>i,[]),a.useLayoutEffect(()=>{const a=e.slice(0,200),n=`image with id ${r} url: ${a}`;"loading"!==t||o.current||(o.current=w(n)),"loading"!==t&&i(),"failed"===t&&x(n)},[t])};export const ImageElement=o(({element:o,store:n})=>{var c,u,w,x;const M=m(),[O,A]=a.useState(!1),k=a.useRef(null),H=a.useRef(null),z=o.isSelected,[P,F]=(t=>{const[e,r]=a.useReducer(t=>t+1,0),o=a.useRef("loading"),i=a.useRef(t.src),n=a.useRef(t.src);n.current!==t.src&&(n.current=t.src,o.current="loading");const h=a.useMemo(()=>X(t.src)||"svg"===t.type,[t.src,t.type]);return a.useEffect(()=>{if(!h){return}if(!t.src){return}let e=!1;return(async()=>{o.current="loading",r();const a=await y.urlToString(t.src),n=y.fixSize(a);let h;h=t.colorsReplace?y.replaceColors(n,t.colorsReplace||new Map):y.svgToURL(n),e||(i.current=h,o.current="loaded",r())})(),()=>{e=!0}},[t.src,JSON.stringify(t.colorsReplace)]),h?[i.current,o.current]:[t.src,"loaded"]})(o),[B,N]=j(P,"anonymous"),U="svg"!==o.type||"loaded"===F?N:"loading";useImageLoader(U,o.src,o.id);const V=(null===(c=o.page)||void 0===c?void 0:c._exportingOrRendering)?1:Math.max(1,n.scale),$=n._elementsPixelRatio*V,q=(({image:t,status:e,type:r})=>{const o=a.useRef(void 0);return a.useEffect(()=>{o.current=t||o.current},[t]),"failed"!==e||"failed"!==e&&"svg"===r?o.current:void 0})({image:B,status:N,type:o.type}),J=((t,e,r)=>{const o=a.useMemo(()=>{var a,o;const{flipX:i,flipY:n}=t,h="svg"===t.type||t.src.indexOf("data:image/svg+xml")>=0||t.src.indexOf(".svg")>=0,d=navigator.userAgent.toLowerCase().indexOf("firefox")>-1,s=(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||d)&&h||t.maskSrc;if(!i&&!n&&!s){return e}if(!e||!e.width||!e.height){return null}const c=C();let l=1;"svg"===t.type&&(l=Math.max(t.a.width/e.width*r,t.a.height/e.height*r)),v(c,Math.max(e.width*l,1),Math.max(e.height*l,1));let g=i?-c.width:0,u=n?-c.height:0;return null===(a=c.getContext("2d"))||void 0===a||a.scale(i?-1:1,n?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(e,g,u,c.width,c.height),c},[t.maskSrc,t.flipX,t.flipY,e,t.a.width,t.a.height,r]);return a.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&f.Util.releaseCanvas(o)},[o]),o})(o,B||q,$),G=((t,e)=>{const r=useSizeFixer(t.maskSrc||""),[o,i]=j(r,"anonymous");return useImageLoader(r?i:"loaded",r||"",t.id),a.useMemo(()=>{if(!o){return e}if(!e||!e.width||!e.height){return e}const r=C();r.width=Math.max(e.width,1),r.height=Math.max(e.height,1);const a=r.getContext("2d");if(!a){return e}a.drawImage(e,0,0),a.globalCompositeOperation="source-in";const i=function(t,e){const r=e.width/e.height;let a,o;return r>=t.width/t.height?(a=t.width,o=t.width/r):(a=t.height*r,o=t.height),{x:(t.width-a)/2,y:(t.height-o)/2,width:a,height:o}}(o,t);return a.drawImage(o,i.x,i.y,i.width,i.height,0,0,e.width,e.height),r},[e,o,t.a.width,t.a.height])})(o,J)||L;let{cropX:K,cropY:Q,cropWidth:Z,cropHeight:tt}=o.a;"loaded"!==N&&(K=Q=0,Z=tt=1);const et=G.width*Z,rt=G.height*tt,at=o.a.width/o.a.height;let ot,it;const nt=et/rt,ht=o.stretchEnabled;ht?(ot=et,it=rt):at>=nt?(ot=et,it=et/at):(ot=rt*at,it=rt);const dt={x:G.width*K,y:G.height*Q,width:ot,height:it},st=null!==(u=o.cornerRadius)&&void 0!==u?u:0,ct=(null===(w=o.page)||void 0===w?void 0:w._exportingOrRendering)?1:Math.min(2,n.scale),lt=n._elementsPixelRatio*ct;let gt=((t,e,r,o)=>{const i=useSizeFixer(t.clipSrc||""),[n,h]=j(i,"anonymous"),d=t.clipSrc?h:"loaded";useImageLoader(d,t.clipSrc,t.id);const s=a.useMemo(()=>{if(e&&n){return C()}},[e,n]);return a.useLayoutEffect(()=>{var a;if(!n){return}if(!e||!e.width||!e.height){return}if(!n||!n.width||!n.height){return}if(!s){return}const o=C(),i=Math.max(t.a.width/n.width*r,t.a.height/n.height*r);o.width=Math.max(n.width*i,1),o.height=Math.max(n.height*i,1),null===(a=o.getContext("2d"))||void 0===a||a.drawImage(n,0,0,o.width,o.height),s.width=Math.max(e.width,1),s.height=Math.max(e.height,1);const h=s.getContext("2d");h&&(h.save(),h.drawImage(o,0,0,e.width,e.height),f.Util.releaseCanvas(o),h.globalCompositeOperation="source-in",h.drawImage(e,0,0,s.width,s.height),h.restore())},[s,e,n,t.a.width,t.a.height,r,...o]),t.clipSrc&&n?s:e})(o,useCornerRadiusAndCrop(o,G,dt,lt,st,O||o._cropModeEnabled||"svg"===o.type,!0),lt,[dt,st,lt]);const ut=Math.max(o.a.width/ot,o.a.height/it);a.useEffect(()=>{var t;if(!o._cropModeEnabled){return}const e=null===(t=k.current)||void 0===t?void 0:t.getStage();function r(t){o._cropModeEnabled&&t.target!==H.current&&o.toggleCropMode(!1)}function a(t){o._cropModeEnabled&&t.target.parentNode!==(null==e?void 0:e.content)&&o.toggleCropMode(!1)}return document.body.addEventListener("click",a),null==e||e.on("click",r),null==e||e.on("tap",r),()=>{document.body.removeEventListener("click",a),document.body.removeEventListener("touchstart",a),null==e||e.off("click",r),null==e||e.off("click",r)}},[o._cropModeEnabled]),a.useLayoutEffect(()=>{if(!O&&!o._cropModeEnabled){return b(k.current,o),i(()=>{b(k.current,o)},{delay:100})}},[gt,null===(x=o.page)||void 0===x?void 0:x._exportingOrRendering,O,Z,tt,o._cropModeEnabled]),a.useLayoutEffect(()=>{var t;O||o._cropModeEnabled?null===(t=k.current)||void 0===t||t.clearCache():b(k.current,o)},[O,o.a.width,o.a.height,o._cropModeEnabled]),a.useEffect(()=>{b(k.current,o)},[o.shadowEnabled,o.shadowBlur,o.cornerRadius,o.shadowColor,o.shadowOffsetX,o.shadowOffsetY,o.shadowOpacity]);const ft=a.useRef(null),pt=a.useRef(null),mt=a.useRef(null);a.useLayoutEffect(()=>{o._cropModeEnabled&&(pt.current.nodes([ft.current]),mt.current.nodes([H.current]))},[o._cropModeEnabled]);var wt=a.useRef(null),xt=a.useRef(0),yt=a.useRef(!1);const Mt=t=>{var e;(null===(e=t.evt.touches)||void 0===e?void 0:e.length)>2&&t.target.stopDrag(),Math.round(t.target.x())>0&&(t.target.x(0),t.target.scaleX(1)),Math.round(t.target.y())>0&&(t.target.y(0),t.target.scaleY(1));const r=t.target.width()*t.target.scaleX(),a=t.target.height()*t.target.scaleY(),i=Math.min(1,ot/r),n=Math.min(1,it/a),h=1-i,d=Math.min(h,Math.max(0,Math.round(-t.target.x())/r)),s=1-n,c=Math.min(s,Math.max(0,Math.round(-t.target.y())/a));t.target.setAttrs({x:-d*G.width,y:-c*G.height,scaleX:1,scaleY:1}),o.set({cropX:d,cropY:c,cropWidth:i,cropHeight:n})},vt=()=>{"svg"!==o.type&&o.contentEditable&&(o.stretchEnabled||setTimeout(()=>{o.toggleCropMode(!0)}))},bt="svg"===o.type&&q,Et="loading"===N&&!bt,[St]=I(Et,100,!1,!1),It="failed"===N,Rt=!St&&!It,Ct=a.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Xt=Rt?o.a.opacity:0;E(k,Xt);const Yt=o.selectable||n.role===g.ADMIN,Ot=S(),Tt=R(o,o.borderColor,"stroke");return e(r,{children:[St&&t(W,{element:o}),It&&t(_,{element:o}),t(d,{ref:k,name:"element",id:o.id,image:gt,x:o.a.x,y:o.a.y,width:o.a.width||1,height:o.a.height||1,rotation:o.a.rotation,opacity:Xt,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,customCrop:dt,listening:Yt,draggable:Ot?o.draggable&&z:o.draggable,preventDefault:!Ot||z,hideInExport:!o.showInExport,onDragMove:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDblClick:vt,onDblTap:vt,onTransformStart:()=>{A(!0),Ct.current={cropX:o.cropX,cropY:o.cropY,cropWidth:o.cropWidth,cropHeight:o.cropHeight}},onTransform:t=>{var e;const r=t.currentTarget,a=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),i=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const n=null===(e=t.target.getStage())||void 0===e?void 0:e.findOne("Transformer"),h=1-ot/G.width,d=Math.min(h,Math.max(0,o.cropX)),s=1-it/G.height,c=Math.min(s,Math.max(0,o.cropY)),l=n.getActiveAnchor(),g=!(l.indexOf("middle")>=0||l.indexOf("center")>=0),u=!g&&a<1&&Ct.current.cropHeight>it/G.height;let f=g?o.cropWidth:o.cropWidth*a;u&&(f=o.cropWidth);const p=!g&&i<1&&Ct.current.cropWidth>ot/G.width;let m=g?o.cropHeight:o.cropHeight*i;p&&(m=o.cropHeight),ht&&(f=o.cropWidth,m=o.cropHeight),o.set({cropX:d,cropY:c,x:r.x(),y:r.y(),width:r.width()*a,height:r.height()*i,rotation:t.target.rotation(),cropWidth:Math.min(f,1-d),cropHeight:Math.min(m,1-c)})},onTransformEnd:t=>{const e=t.currentTarget;o.set({width:e.width(),height:e.height(),x:e.x(),y:e.y(),rotation:t.target.rotation(),cropWidth:ot/G.width,cropHeight:it/G.height}),A(!1)}}),t(s,Object.assign({x:o.x,y:o.y,width:Math.max(o.a.width-o.borderSize,0),height:Math.max(o.a.height-o.borderSize,0),opacity:Xt,offsetX:-o.borderSize/2,offsetY:-o.borderSize/2},Tt,{strokeWidth:o.borderSize,listening:!1,visible:!!o.borderSize,rotation:o.rotation,cornerRadius:Math.max(0,st-o.borderSize),hideInExport:!o.showInExport})),o._cropModeEnabled&&e(p,{selector:".page-abs-container",enabled:!0,children:[t(s,{x:-window.innerWidth/n.scale,y:-window.innerWidth/n.scale,width:window.innerWidth/n.scale*3,height:window.innerWidth/n.scale*3,fill:M.cropOverlayFill}),t(d,{listening:!1,image:gt,x:o.x,y:o.y,width:o.a.width,height:o.a.height,rotation:o.rotation,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur}),e(h,{x:o.x,y:o.y,rotation:o.rotation,scaleX:ut,scaleY:ut,children:[t(d,{image:G,ref:H,opacity:.4,draggable:!0,x:-o.cropX*G.width,y:-o.cropY*G.height,onDragMove:Mt,onTransform:Mt,onTouchMove:t=>{t.evt.preventDefault();const e=t.target.getStage().getPointersPositions();var r=e[0],a=e[1];const o=t.target;if(r&&!a&&!o.isDragging()&&yt.current&&(o.startDrag(),yt.current=!1),r&&a){f.hitOnDragEnabled=!0,o.isDragging()&&(yt.current=!0,o.stopDrag());const e=t.target.getAbsoluteTransform().copy();e.invert();var i={x:r.x,y:r.y},n={x:a.x,y:a.y};if(!wt.current){return void(wt.current=Y(i,n))}var h=Y(i,n),d=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}(i,n);xt.current||(xt.current=d);const p=o.position();var s={x:h.x-p.x,y:h.y-p.y},c=d/xt.current;o.scaleX(c),o.scaleY(c);const m=e.point(h),w=e.point(wt.current);var l=m.x-w.x,g=m.y-w.y,u={x:Math.min(0,h.x-s.x*c+l),y:Math.min(0,h.y-s.y*c+g)};o.position(u),xt.current=d,wt.current=h,Mt(t)}},onTouchEnd:t=>{xt.current=0,wt.current=null,f.hitOnDragEnabled=!1}}),t(l,Object.assign({ref:mt},D,M.outerImageCropTransformerStyle)),t(s,{width:ot,height:it,ref:ft,listening:!1,onTransform:t=>{if(o.cropX<Math.abs(t.target.x()/G.width)&&t.target.x()<0&&o.cropX>0){const e=(o.cropWidth+o.cropX)*G.width;t.target.scaleX(1),t.target.width(e)}if(o.cropY<Math.abs(t.target.y()/G.height)&&t.target.y()<0&&o.cropY>0){const e=(o.cropHeight+o.cropY)*G.height;t.target.scaleY(1),t.target.height(e)}t.target.x()<-o.cropX*G.width-1e-9&&(t.target.x(-o.cropX*G.width),t.target.scaleX(1)),t.target.y()<-o.cropY*G.height-1e-9&&(t.target.y(-o.cropY*G.height),t.target.scaleY(1));const e=Math.min(1,Math.max(0,o.cropX+t.target.x()/G.width)),r=Math.min(1,Math.max(0,t.target.y()/G.height+o.cropY)),a=t.target.width()*t.target.scaleX(),i=t.target.height()*t.target.scaleY(),n=Math.min(1-e,a/G.width),h=Math.min(1-r,i/G.height),d=t.target.getAbsolutePosition(t.target.getParent().getParent());t.target.scale({x:1,y:1}),t.target.position({x:0,y:0}),o.set({x:d.x,y:d.y,cropX:e,cropY:r,cropWidth:n,cropHeight:h,width:Math.min(a*ut,G.width*(1-e)*ut),height:Math.min(i*ut,G.height*(1-r)*ut)})}}),t(l,Object.assign({ref:pt},T,M.innerImageCropTransformerStyle,{visible:o.resizable}))]})]})]})});
|
|
1
|
+
import{jsx as t,jsxs as e,Fragment as r}from"react/jsx-runtime";import a from"react";import{observer as o}from"mobx-react-lite";import{nodeAutorun as i}from"../utils/mobx.js";import{Arc as n,Group as h,Image as d,Rect as s,Text as c,Transformer as l}from"react-konva";import{ROLES as g}from"../model/store.js";import u from"use-image";import f from"konva";import{Portal as p}from"react-konva-utils";import{useWorkspaceStyle as m}from"./workspace-style.js";import{incrementLoader as w,triggerLoadError as x}from"../utils/loader.js";import*as y from"../utils/svg.js";import{flags as M}from"../utils/flags.js";import{trySetCanvasSize as v}from"../utils/canvas.js";import{applyFilter as b}from"./apply-filters.js";import{useFadeIn as E}from"./use-fadein.js";import{isTouchDevice as S}from"../utils/screen.js";import{useDelayer as I}from"./use-delayer.js";import{useColor as R}from"./use-color.js";function C(){return document.createElement("canvas")}const X=t=>t.indexOf("data:image/svg+xml")>=0||t.indexOf(".svg")>=0;export const useSizeFixer=t=>{const[e,r]=a.useState(t);return a.useEffect(()=>{(async()=>{const a=await async function(t){if(!X(t)){return t}const e=await y.urlToString(t),r=y.fixSize(e);return y.svgToURL(r)}(t);a!==e&&r(a)})()},[t]),e};function Y(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}const O=(t,e)=>e.width<5||e.height<5?t:e,T={keepRatio:!1,rotateEnabled:!1,boundBoxFunc:O},D={enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],rotateEnabled:!1,borderEnabled:!1,boundBoxFunc:O};const A=(t,e,r)=>Math.max(e,Math.min(r,t));export const useCornerRadiusAndCrop=(t,e,r,o,i=0,n=!1,h=!0)=>{var d,s;const c=Math.floor(A(t.a.width*o,1,1e4)),l=Math.floor(A(t.a.height*o,1,1e4)),g=Math.min(i*o,c/2,l/2),u=Math.max(t.a.width/r.width,t.a.height/r.height)*o,p=(null===(d=t.page)||void 0===d?void 0:d._exportingOrRendering)&&M.imageDownScalingEnabled&&u<1&&!n,m=0===r.x&&0===r.y&&r.width===(null==e?void 0:e.width)&&r.height===(null==e?void 0:e.height),w=a.useMemo(()=>{if(e&&e.width&&e.height){return m&&0===g&&!p?void 0:C()}},[e,g,p,m]);return a.useLayoutEffect(()=>{if(!w||!e){return}v(w,c,l);const t=w.getContext("2d");if(!t){return}g&&(t.beginPath(),t.moveTo(g,0),t.lineTo(c-g,0),t.arc(c-g,g,g,3*Math.PI/2,0,!1),t.lineTo(c,l-g),t.arc(c-g,l-g,g,0,Math.PI/2,!1),t.lineTo(g,l),t.arc(g,l-g,g,Math.PI/2,Math.PI,!1),t.lineTo(0,g),t.arc(g,g,g,Math.PI,3*Math.PI/2,!1),t.clip());const a=p?function(t,e){var r,a;const o=C();o.width=t.width,o.height=t.height;const i=Math.max(1,Math.floor(o.width*e)),n=Math.max(1,Math.floor(o.height*e));null===(r=o.getContext("2d"))||void 0===r||r.drawImage(t,0,0,o.width,o.height);const h=function(t,e,r,a,o,i,n){for(var h=new ImageData(e,r),d=new Int32Array(t.data.buffer),s=t.width,c=new Int32Array(h.data.buffer),l=h.width,g=e/i,u=r/n,f=Math.round(1/g),p=Math.round(1/u),m=f*p,w=0;w<h.height;w++){for(var x=0;x<l;x++){for(var y=0+Math.round(x/g)+(0+Math.round(w/u))*s,M=0,v=0,b=0,E=0,S=0;S<p;S++){for(var I=0;I<f;I++){var R=d[y+I+S*s];M+=R<<24>>>24,v+=R<<16>>>24,b+=R<<8>>>24,E+=R>>>24}}M=Math.round(M/m),v=Math.round(v/m),b=Math.round(b/m),E=Math.round(E/m),c[x+w*l]=E<<24|b<<16|v<<8|M}}return h}(o.getContext("2d").getImageData(0,0,o.width,o.height),i,n,0,0,o.width,o.height);return o.width=i,o.height=n,null===(a=o.getContext("2d"))||void 0===a||a.putImageData(h,0,0),o}(e,u):e,o=p?{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;t.drawImage(a,o.x,o.y,o.width,o.height,0,0,w.width,w.height)},[w,t.a.width,t.a.height,r.x,r.y,r.width,r.height,i,o,n,null===(s=t.page)||void 0===s?void 0:s._exportingOrRendering,p]),a.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&f.Util.releaseCanvas(w)},[w]),w||e};const L=C(),W=o(({element:r})=>{const o=Math.min(30,r.a.width/4,r.a.height/4),i=a.useRef(null);a.useEffect(()=>{const t=i.current;if(!t){return}const e=new f.Animation(e=>{t.rotate(((null==e?void 0:e.timeDiff)||0)/2)},t.getLayer());return e.start(),()=>{e.stop()}});const{mediaLoadingStyle:d}=m();return e(h,{x:r.x,y:r.y,rotation:r.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(s,{width:r.a.width,height:r.a.height,fill:d.fill}),t(n,{ref:i,x:r.a.width/2,y:r.a.height/2,fill:d.textFill,outerRadius:Math.abs(o),innerRadius:Math.max(1,o-5),angle:270})]})}),_=o(({element:r})=>{const{mediaErrorStyle:a}=m(),o=Math.max(10,Math.min(30,r.a.width/25));return e(h,{x:r.x,y:r.y,rotation:r.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(s,{width:r.a.width,height:r.a.height,fill:a.fill}),t(c,{text:"Can not load the image...",fontSize:o,width:r.a.width,height:r.a.height,align:"center",fill:a.textFill,verticalAlign:"middle",padding:5})]})});let j=u;export const setImageLoaderHook=t=>{j=t};export const useImageLoader=(t,e="",r="")=>{const o=a.useRef(void 0),i=()=>{var t;null===(t=o.current)||void 0===t||t.call(o),o.current=void 0};a.useEffect(()=>i,[]),a.useLayoutEffect(()=>{const a=e.slice(0,200),n=`image with id ${r} url: ${a}`;"loading"!==t||o.current||(o.current=w(n)),"loading"!==t&&i(),"failed"===t&&x(n)},[t])};export const ImageElement=o(({element:o,store:n})=>{var c,u,w,x;const M=m(),[O,A]=a.useState(!1),k=a.useRef(null),H=a.useRef(null),z=o.isSelected,[P,F]=(t=>{const[e,r]=a.useReducer(t=>t+1,0),o=a.useRef("loading"),i=a.useRef(t.src),n=a.useRef(t.src);n.current!==t.src&&(n.current=t.src,o.current="loading");const h=a.useMemo(()=>X(t.src)||"svg"===t.type,[t.src,t.type]);return a.useEffect(()=>{if(!h){return}if(!t.src){return}let e=!1;return(async()=>{o.current="loading",r();const a=await y.urlToString(t.src),n=y.fixSize(a);let h;h=t.colorsReplace?y.replaceColors(n,t.colorsReplace||new Map):y.svgToURL(n),e||(i.current=h,o.current="loaded",r())})(),()=>{e=!0}},[t.src,JSON.stringify(t.colorsReplace)]),h?[i.current,o.current]:[t.src,"loaded"]})(o),[B,N]=j(P,"anonymous"),U="svg"!==o.type||"loaded"===F?N:"loading";useImageLoader(U,o.src,o.id);const V=(null===(c=o.page)||void 0===c?void 0:c._exportingOrRendering)?1:Math.max(1,n.scale),$=n._elementsPixelRatio*V,q=(({image:t,status:e,type:r})=>{const o=a.useRef(void 0);return a.useEffect(()=>{o.current=t||o.current},[t]),"failed"!==e||"failed"!==e&&"svg"===r?o.current:void 0})({image:B,status:N,type:o.type}),J=((t,e,r)=>{const o=a.useMemo(()=>{var a,o;const{flipX:i,flipY:n}=t,h="svg"===t.type||t.src.indexOf("data:image/svg+xml")>=0||t.src.indexOf(".svg")>=0,d=navigator.userAgent.toLowerCase().indexOf("firefox")>-1,s=(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||d)&&h||t.maskSrc;if(!i&&!n&&!s){return e}if(!e||!e.width||!e.height){return null}const c=C();let l=1;"svg"===t.type&&(l=Math.max(t.a.width/e.width*r,t.a.height/e.height*r)),v(c,Math.max(e.width*l,1),Math.max(e.height*l,1));let g=i?-c.width:0,u=n?-c.height:0;return null===(a=c.getContext("2d"))||void 0===a||a.scale(i?-1:1,n?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(e,g,u,c.width,c.height),c},[t.maskSrc,t.flipX,t.flipY,e,t.a.width,t.a.height,r]);return a.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&f.Util.releaseCanvas(o)},[o]),o})(o,B||q,$),G=((t,e)=>{const r=useSizeFixer(t.maskSrc||""),[o,i]=j(r,"anonymous");return useImageLoader(r?i:"loaded",r||"",t.id),a.useMemo(()=>{if(!o){return e}if(!e||!e.width||!e.height){return e}const r=C();r.width=Math.max(e.width,1),r.height=Math.max(e.height,1);const a=r.getContext("2d");if(!a){return e}a.drawImage(e,0,0),a.globalCompositeOperation="source-in";const i=function(t,e){const r=e.width/e.height;let a,o;return r>=t.width/t.height?(a=t.width,o=t.width/r):(a=t.height*r,o=t.height),{x:(t.width-a)/2,y:(t.height-o)/2,width:a,height:o}}(o,t);return a.drawImage(o,i.x,i.y,i.width,i.height,0,0,e.width,e.height),r},[e,o,t.a.width,t.a.height])})(o,J)||L;let{cropX:K,cropY:Q,cropWidth:Z,cropHeight:tt}=o.a;"loaded"!==N&&(K=Q=0,Z=tt=1);const et=G.width*Z,rt=G.height*tt,at=o.a.width/o.a.height;let ot,it;const nt=et/rt,ht=o.stretchEnabled;ht?(ot=et,it=rt):at>=nt?(ot=et,it=et/at):(ot=rt*at,it=rt);const dt={x:G.width*K,y:G.height*Q,width:ot,height:it},st=null!==(u=o.cornerRadius)&&void 0!==u?u:0,ct=(null===(w=o.page)||void 0===w?void 0:w._exportingOrRendering)?1:Math.min(2,n.scale),lt=n._elementsPixelRatio*ct;let gt=((t,e,r,o)=>{const i=useSizeFixer(t.clipSrc||""),[n,h]=j(i,"anonymous"),d=t.clipSrc?h:"loaded";useImageLoader(d,t.clipSrc,t.id);const s=a.useMemo(()=>{if(e&&n){return C()}},[e,n]);return a.useLayoutEffect(()=>{var a;if(!n){return}if(!e||!e.width||!e.height){return}if(!n||!n.width||!n.height){return}if(!s){return}const o=C(),i=Math.max(t.a.width/n.width*r,t.a.height/n.height*r);o.width=Math.max(n.width*i,1),o.height=Math.max(n.height*i,1),null===(a=o.getContext("2d"))||void 0===a||a.drawImage(n,0,0,o.width,o.height),s.width=Math.max(e.width,1),s.height=Math.max(e.height,1);const h=s.getContext("2d");h&&(h.save(),h.drawImage(o,0,0,e.width,e.height),f.Util.releaseCanvas(o),h.globalCompositeOperation="source-in",h.drawImage(e,0,0,s.width,s.height),h.restore())},[s,e,n,t.a.width,t.a.height,r,...o]),t.clipSrc&&n?s:e})(o,useCornerRadiusAndCrop(o,G,dt,lt,st,O||o._cropModeEnabled||"svg"===o.type,!0),lt,[dt,st,lt]);const ut=Math.max(o.a.width/ot,o.a.height/it);a.useEffect(()=>{var t;if(!o._cropModeEnabled){return}const e=null===(t=k.current)||void 0===t?void 0:t.getStage();function r(t){o._cropModeEnabled&&t.target!==H.current&&o.toggleCropMode(!1)}function a(t){o._cropModeEnabled&&t.target.parentNode!==(null==e?void 0:e.content)&&o.toggleCropMode(!1)}return document.body.addEventListener("click",a),null==e||e.on("click",r),null==e||e.on("tap",r),()=>{document.body.removeEventListener("click",a),document.body.removeEventListener("touchstart",a),null==e||e.off("click",r),null==e||e.off("click",r)}},[o._cropModeEnabled]),a.useLayoutEffect(()=>{if(!O&&!o._cropModeEnabled){return b(k.current,o),i(o,()=>{b(k.current,o)},{delay:100})}},[gt,null===(x=o.page)||void 0===x?void 0:x._exportingOrRendering,O,Z,tt,o._cropModeEnabled]),a.useLayoutEffect(()=>{var t;O||o._cropModeEnabled?null===(t=k.current)||void 0===t||t.clearCache():b(k.current,o)},[O,o.a.width,o.a.height,o._cropModeEnabled]),a.useEffect(()=>{b(k.current,o)},[o.shadowEnabled,o.shadowBlur,o.cornerRadius,o.shadowColor,o.shadowOffsetX,o.shadowOffsetY,o.shadowOpacity]);const ft=a.useRef(null),pt=a.useRef(null),mt=a.useRef(null);a.useLayoutEffect(()=>{o._cropModeEnabled&&(pt.current.nodes([ft.current]),mt.current.nodes([H.current]))},[o._cropModeEnabled]);var wt=a.useRef(null),xt=a.useRef(0),yt=a.useRef(!1);const Mt=t=>{var e;(null===(e=t.evt.touches)||void 0===e?void 0:e.length)>2&&t.target.stopDrag(),Math.round(t.target.x())>0&&(t.target.x(0),t.target.scaleX(1)),Math.round(t.target.y())>0&&(t.target.y(0),t.target.scaleY(1));const r=t.target.width()*t.target.scaleX(),a=t.target.height()*t.target.scaleY(),i=Math.min(1,ot/r),n=Math.min(1,it/a),h=1-i,d=Math.min(h,Math.max(0,Math.round(-t.target.x())/r)),s=1-n,c=Math.min(s,Math.max(0,Math.round(-t.target.y())/a));t.target.setAttrs({x:-d*G.width,y:-c*G.height,scaleX:1,scaleY:1}),o.set({cropX:d,cropY:c,cropWidth:i,cropHeight:n})},vt=()=>{"svg"!==o.type&&o.contentEditable&&(o.stretchEnabled||setTimeout(()=>{o.toggleCropMode(!0)}))},bt="svg"===o.type&&q,Et="loading"===N&&!bt,[St]=I(Et,100,!1,!1),It="failed"===N,Rt=!St&&!It,Ct=a.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Xt=Rt?o.a.opacity:0;E(k,Xt);const Yt=o.selectable||n.role===g.ADMIN,Ot=S(),Tt=R(o,o.borderColor,"stroke");return e(r,{children:[St&&t(W,{element:o}),It&&t(_,{element:o}),t(d,{ref:k,name:"element",id:o.id,image:gt,x:o.a.x,y:o.a.y,width:o.a.width||1,height:o.a.height||1,rotation:o.a.rotation,opacity:Xt,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,customCrop:dt,listening:Yt,draggable:Ot?o.draggable&&z:o.draggable,preventDefault:!Ot||z,hideInExport:!o.showInExport,onDragMove:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDblClick:vt,onDblTap:vt,onTransformStart:()=>{A(!0),Ct.current={cropX:o.cropX,cropY:o.cropY,cropWidth:o.cropWidth,cropHeight:o.cropHeight}},onTransform:t=>{var e;const r=t.currentTarget,a=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),i=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const n=null===(e=t.target.getStage())||void 0===e?void 0:e.findOne("Transformer"),h=1-ot/G.width,d=Math.min(h,Math.max(0,o.cropX)),s=1-it/G.height,c=Math.min(s,Math.max(0,o.cropY)),l=n.getActiveAnchor(),g=!(l.indexOf("middle")>=0||l.indexOf("center")>=0),u=!g&&a<1&&Ct.current.cropHeight>it/G.height;let f=g?o.cropWidth:o.cropWidth*a;u&&(f=o.cropWidth);const p=!g&&i<1&&Ct.current.cropWidth>ot/G.width;let m=g?o.cropHeight:o.cropHeight*i;p&&(m=o.cropHeight),ht&&(f=o.cropWidth,m=o.cropHeight),o.set({cropX:d,cropY:c,x:r.x(),y:r.y(),width:r.width()*a,height:r.height()*i,rotation:t.target.rotation(),cropWidth:Math.min(f,1-d),cropHeight:Math.min(m,1-c)})},onTransformEnd:t=>{const e=t.currentTarget;o.set({width:e.width(),height:e.height(),x:e.x(),y:e.y(),rotation:t.target.rotation(),cropWidth:ot/G.width,cropHeight:it/G.height}),A(!1)}}),t(s,Object.assign({x:o.x,y:o.y,width:Math.max(o.a.width-o.borderSize,0),height:Math.max(o.a.height-o.borderSize,0),opacity:Xt,offsetX:-o.borderSize/2,offsetY:-o.borderSize/2},Tt,{strokeWidth:o.borderSize,listening:!1,visible:!!o.borderSize,rotation:o.rotation,cornerRadius:Math.max(0,st-o.borderSize),hideInExport:!o.showInExport})),o._cropModeEnabled&&e(p,{selector:".page-abs-container",enabled:!0,children:[t(s,{x:-window.innerWidth/n.scale,y:-window.innerWidth/n.scale,width:window.innerWidth/n.scale*3,height:window.innerWidth/n.scale*3,fill:M.cropOverlayFill}),t(d,{listening:!1,image:gt,x:o.x,y:o.y,width:o.a.width,height:o.a.height,rotation:o.rotation,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur}),e(h,{x:o.x,y:o.y,rotation:o.rotation,scaleX:ut,scaleY:ut,children:[t(d,{image:G,ref:H,opacity:.4,draggable:!0,x:-o.cropX*G.width,y:-o.cropY*G.height,onDragMove:Mt,onTransform:Mt,onTouchMove:t=>{t.evt.preventDefault();const e=t.target.getStage().getPointersPositions();var r=e[0],a=e[1];const o=t.target;if(r&&!a&&!o.isDragging()&&yt.current&&(o.startDrag(),yt.current=!1),r&&a){f.hitOnDragEnabled=!0,o.isDragging()&&(yt.current=!0,o.stopDrag());const e=t.target.getAbsoluteTransform().copy();e.invert();var i={x:r.x,y:r.y},n={x:a.x,y:a.y};if(!wt.current){return void(wt.current=Y(i,n))}var h=Y(i,n),d=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}(i,n);xt.current||(xt.current=d);const p=o.position();var s={x:h.x-p.x,y:h.y-p.y},c=d/xt.current;o.scaleX(c),o.scaleY(c);const m=e.point(h),w=e.point(wt.current);var l=m.x-w.x,g=m.y-w.y,u={x:Math.min(0,h.x-s.x*c+l),y:Math.min(0,h.y-s.y*c+g)};o.position(u),xt.current=d,wt.current=h,Mt(t)}},onTouchEnd:t=>{xt.current=0,wt.current=null,f.hitOnDragEnabled=!1}}),t(l,Object.assign({ref:mt},D,M.outerImageCropTransformerStyle)),t(s,{width:ot,height:it,ref:ft,listening:!1,onTransform:t=>{if(o.cropX<Math.abs(t.target.x()/G.width)&&t.target.x()<0&&o.cropX>0){const e=(o.cropWidth+o.cropX)*G.width;t.target.scaleX(1),t.target.width(e)}if(o.cropY<Math.abs(t.target.y()/G.height)&&t.target.y()<0&&o.cropY>0){const e=(o.cropHeight+o.cropY)*G.height;t.target.scaleY(1),t.target.height(e)}t.target.x()<-o.cropX*G.width-1e-9&&(t.target.x(-o.cropX*G.width),t.target.scaleX(1)),t.target.y()<-o.cropY*G.height-1e-9&&(t.target.y(-o.cropY*G.height),t.target.scaleY(1));const e=Math.min(1,Math.max(0,o.cropX+t.target.x()/G.width)),r=Math.min(1,Math.max(0,t.target.y()/G.height+o.cropY)),a=t.target.width()*t.target.scaleX(),i=t.target.height()*t.target.scaleY(),n=Math.min(1-e,a/G.width),h=Math.min(1-r,i/G.height),d=t.target.getAbsolutePosition(t.target.getParent().getParent());t.target.scale({x:1,y:1}),t.target.position({x:0,y:0}),o.set({x:d.x,y:d.y,cropX:e,cropY:r,cropWidth:n,cropHeight:h,width:Math.min(a*ut,G.width*(1-e)*ut),height:Math.min(i*ut,G.height*(1-r)*ut)})}}),t(l,Object.assign({ref:pt},T,M.innerImageCropTransformerStyle,{visible:o.resizable}))]})]})]})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,Fragment as e,jsxs as r}from"react/jsx-runtime";import o from"react";import{observer as n}from"mobx-react-lite";import{Group as i,Path as a,Rect as s,Shape as l}from"react-konva";import*as c from"mobx";import{isAlive as h}from"mobx-state-tree";import{Html as d}from"react-konva-utils";import{layout as f,drawLayout as u}from"render-tag";import{layoutTextOnPath as g,drawTextOnPathLayout as m}from"render-tag/path";import{flags as x}from"../utils/flags.js";import{applyFilter as p}from"./apply-filters.js";import{getLineHeight as y,usePrevious as b}from"./text-element.js";import{useFontSpecsLoader as w}from"./text-element/font-specs-loader.js";import{getHtml as v,getCurvePath as E,getCurveTextHeight as O}from"../utils/text-html.js";import{useColor as S}from"./use-color.js";import{isGradient as z}from"../utils/gradient.js";import{detectSize as k}from"../utils/html2canvas.js";import{generateBackgroundShapeFromRects as j}from"../utils/background-shape.js";import{useFadeIn as M}from"./use-fadein.js";import{incrementLoader as R}from"../utils/loader.js";import{removeTags as F}from"../utils/text.js";import{isTouchDevice as T}from"../utils/screen.js";import{getLimitedFontSize as Y}from"./text-element/max-font-size.js";import{normalizeRichTextHtml as X,extractFontSpecsFromHtml as C,scaleRichTextFontSizesInHtml as I}from"../utils/rich-text-html.js";import{RichEditor as B}from"./rich-editor.js";import{findFitFontSize as A}from"./text-element/fit-font-size.js";import{resetStyleContent as D}from"../utils/reset-style.js";import{xmlEscape as H}from"../utils/xml.js";const P=`<style>${D}\n/* render-tag draws list markers natively from the <ol>/<ul> tag + tree position\n (it ignores the polotno reset's ::before + counter() markers, which only work\n in real DOM — the Quill editor and the foreignObject rasterizer). The shared\n reset sets list-style:none for those ::before markers, which would suppress\n render-tag's native ones; restore the canonical marker types here so render-tag\n paints them. element.text is canonicalized to <ul>/<ol> upstream\n (normalizeRichTextHtml), so the tag alone selects bullet vs. number. */\nol { list-style-type: decimal; }\nul { list-style-type: disc; }\n/* Chrome's <code>/<pre> font-size UA quirk isn't reproducible on canvas — let\n them inherit so DOM and canvas line up. */\ncode, pre, kbd, samp { font-size: inherit; }</style>`;export function wrapHtmlForRenderTag(t){return P+t}export const RenderTagElement=n(({element:n,store:D})=>{var P;const W=o.useRef(null),J=o.useRef(null),[N,L]=o.useState(!1),q=o.useRef(n.height),V=n.isSelected,$=b(V),{textVerticalResizeEnabled:_}=x,Q=x.autoDeleteEmptyText,U=b(n.fontFamily),G=o.useMemo(()=>X(n.text,{fontSize:n.fontSize,fontFamily:n.fontFamily}),[n.text,n.fontSize,n.fontFamily]),K=o.useMemo(()=>C(G,{fontFamily:n.fontFamily,fontWeight:n.fontWeight,fontStyle:n.fontStyle}),[G,n.fontFamily,n.fontWeight,n.fontStyle]),[Z]=w(D,K,n.text||n.placeholder),tt=n._editModeEnabled;M(W);const et=Z?n.fontFamily:U&&U!==n.fontFamily?U:"Arial",rt=S(n).fill,ot=z(n.fill),nt=z(n.stroke)&&!!n.strokeWidth,it=!!n.strokeWidth&&(nt||ot),at="ellipsis"===x.textOverflow&&!n.curveEnabled&&!!n.height&&!it,st=!F(n.text)&&!!n.placeholder,lt=st?H(n.placeholder):n.text,ct=st?.6:n.a.opacity,ht=v(st?Object.assign(Object.assign({},n.toJSON()),{text:lt}):n,{fontFamily:et,color:rt,forEditor:!at}),dt=n.width||1,ft=n.curveEnabled,ut=function(t,e,r,n){return o.useMemo(()=>{if(n){return null}try{return f({html:wrapHtmlForRenderTag(t),width:Math.max(1,e),accuracy:"performance"})}catch(r){return console.error("render-tag layout failed:",r),null}},[t,e,r,n])}(ht,dt,Z,ft),gt=function(t,e,r){return o.useMemo(()=>{if(!e.curveEnabled){return null}const r=e.width||1,o=O(e),n=E(r,o,e.curvePower,e.fontSize);try{return g({html:wrapHtmlForRenderTag(t),path:n,align:"center",textBaseline:"middle"})}catch(i){return console.error("render-tag/path layoutTextOnPath failed:",i),null}},[r,e.curveEnabled,e.curvePower,e.fontSize,e.width,e.height,t])}(ht,n,Z),mt=y({fontLoaded:Z,fontFamily:n.fontFamily,fontSize:n.fontSize,lineHeight:n.lineHeight}),xt=ft?0:Math.max(null!==(P=null==ut?void 0:ut.height)&&void 0!==P?P:0,n.fontSize*mt),pt=gt?gt.bounds:null,yt=o.useMemo(()=>ut?ut.lines.map(t=>({left:t.bounds.x,right:t.bounds.x+t.bounds.width,top:t.bounds.y,bottom:t.bounds.y+t.bounds.height})):[],[ut]),bt=o.useRef([]),wt=o.useRef(!0),[,vt]=o.useReducer(t=>t+1,0);o.useEffect(()=>{const t=bt.current;t.length>0&&(bt.current=[],t.forEach(t=>t()))});const Et=o.useCallback((t,e,r,o)=>{const i=R(`text ${n.id}`),a=()=>{D.history.ignore(t,e,r).then(()=>{wt.current?(bt.current.push(i),vt()):i()})};o?queueMicrotask(a):a()},[n.id,D]);o.useEffect(()=>{if(!Z){return}if(!ut){return}if(!n.height){return void Et(()=>{h(n)&&(n.height||n.set({height:xt}))},void 0,void 0,!0)}if(D.isPlaying){return}const{textOverflow:t}=x,e=n.height!==xt&&(!_||n.height<xt),r=()=>Et(()=>{h(n)&&n.set({height:xt})},!1,!0);if("change-font-size"!==t||N||tt||n.curveEnabled){"resize"===t&&e&&!N&&r()}else{const t=A(st?Object.assign(Object.assign({},n.toJSON()),{text:lt,toJSON:()=>Object.assign(Object.assign({},n.toJSON()),{text:lt})}):n,{fontFamily:et,color:rt,forEditor:!0},t=>{try{return f({html:wrapHtmlForRenderTag(t),width:dt,accuracy:"performance"}).height}catch(P){return k(t).height}});t.fontSize!==n.fontSize?Et(()=>{if(!h(n)){return}const e={fontSize:t.fontSize};void 0!==t.text&&t.text!==n.text&&(e.text=t.text),n.set(e)},!1,!0):e&&r()}}),o.useEffect(()=>()=>{wt.current=!1;const t=bt.current;t.length>0&&(bt.current=[],t.forEach(t=>t()))},[]),o.useLayoutEffect(()=>{if(!Z||!n.curveEnabled||N){return}if(!pt||!pt.width){return}const t=t=>t&&_?Math.max(t,pt.height):pt.height;Math.abs(pt.width-n.width)<1&&Math.abs(t(n.height)-n.height)<1||Et(()=>{if(!h(n)){return}const e=pt.width-n.width,r=t(n.height),o=r-n.height;if(Math.abs(e)<1&&Math.abs(o)<1){return}const i=n.a.rotation*Math.PI/180,a=-e/2*Math.cos(i),s=-e/2*Math.sin(i);n.set({width:pt.width,height:r,x:n.a.x+a,y:n.a.y+s})},!1,!0,!0)},[Z,n.curveEnabled,pt,N,_,Et]),o.useEffect(()=>{$&&!V&&Q&&""===F(n.text)&&n.removable&&!n.placeholder&&D.deleteElements([n.id])},[Q,n.placeholder,n.removable,n.text,V,$]),o.useEffect(()=>c.autorun(()=>{const t=W.current;t&&p(t,n)}),[ut,gt,n.a.width,n.a.height,n.shadowColor,n.shadowOffsetX,n.shadowOffsetY,n.shadowOpacity]);let Ot=0;ft||"middle"!==n.verticalAlign?ft||"bottom"!==n.verticalAlign||(Ot=n.height-xt):Ot=(n.height-xt)/2;const St=n.backgroundPadding*(n.fontSize*mt*.5),zt=n.backgroundCornerRadius*(n.fontSize*mt*.5),kt=o.useMemo(()=>!n.backgroundEnabled||n.curveEnabled||n.legacyBackground||0===yt.length?"":j({rects:yt,padding:St,cornerRadius:zt}),[n.backgroundEnabled,n.curveEnabled,n.legacyBackground,yt,St,zt]),jt=T(),Mt=o.useRef(null),Rt=o.useRef(null),Ft=o.useRef(null),Tt=o.useRef(0),Yt=o.useRef(0),Xt=tt&&n.strokeWidth>0&&!n.curveEnabled,Ct=n.width>0?n.a.width/n.width:1;return r(e,{children:[n.curveEnabled||n.legacyBackground?t(s,{x:n.a.x,y:n.a.y,offsetX:St/Ct,offsetY:St/Ct,rotation:n.a.rotation,scaleX:Ct,scaleY:Ct,hideInExport:!n.showInExport,listening:!1,visible:n.backgroundEnabled,opacity:n.backgroundOpacity*ct,fill:n.backgroundColor,width:n.width+2*St,height:n.height+2*St,cornerRadius:zt}):t(a,{name:"rendertag-background",x:n.a.x,y:n.a.y,offsetY:-Ot/Ct,rotation:n.a.rotation,scaleX:Ct,scaleY:Ct,hideInExport:!n.showInExport,listening:!1,visible:n.backgroundEnabled&&kt.length>0,opacity:n.backgroundOpacity*ct,fill:n.backgroundColor,data:kt}),t(l,{ref:W,name:"rendertag-text",x:n.a.x,y:n.a.y,rotation:n.a.rotation,scaleX:Ct,scaleY:Ct,offsetY:Ct>0?-Ot/Ct:0,width:n.width,height:Math.max(n.height,xt),listening:!1,visible:(!tt||Xt)&&!!(ft?gt:ut),opacity:ct,shadowEnabled:n.shadowEnabled,shadowBlur:n.shadowBlur,shadowOffsetX:n.shadowOffsetX,shadowOffsetY:n.shadowOffsetY,shadowColor:n.shadowColor,shadowOpacity:n.shadowOpacity,hideInExport:!n.showInExport,sceneFunc:(t,e)=>{const r=t._context;if(r){try{if(ft){if(!gt||!pt){return}const t=(n.width-pt.width)/2-pt.x;r.save(),r.translate(t,-pt.y),m({layout:gt,ctx:r}),r.restore()}else{if(!ut){return}u({layout:ut,width:dt,ctx:r,pixelRatio:1})}}catch(o){console.error("render-tag draw failed:",o)}}}}),t(s,{ref:J,name:"element",x:n.a.x,y:n.a.y,listening:n.selectable,rotation:n.a.rotation,width:n.a.width,height:n.a.height,visible:!tt,draggable:jt?n.draggable&&V:n.draggable,preventDefault:!jt||V,opacity:0,hideInExport:!0,id:n.id,onDragMove:t=>{n.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{n.set({x:t.target.x(),y:t.target.y()})},onDblClick:t=>{n.contentEditable&&(Rt.current={x:t.evt.clientX,y:t.evt.clientY},n.toggleEditMode(!0))},onDblTap:t=>{var e;if(n.contentEditable){const r=null===(e=t.evt.changedTouches)||void 0===e?void 0:e[0];Rt.current=r?{x:r.clientX,y:r.clientY}:null,n.toggleEditMode(!0)}},onTransformStart:t=>{var e,r;L(!0),q.current=n.height;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.findOne("Transformer");Ft.current=null!==(r=null==o?void 0:o.getActiveAnchor())&&void 0!==r?r:null,Tt.current=n.a.rotation,Yt.current=n.height},onTransform:t=>{var e;const r=t.target,o=(null===(e=r.getStage())||void 0===e?void 0:e.findOne("Transformer")).getActiveAnchor(),i="middle-left"===o||"middle-right"===o,a="top-center"===o||"bottom-center"===o,s=r.scaleX();if(i){const t=r.scaleX(),e=r.width()*t,o=n.fontSize;let i=e;e<o&&(i=o,Mt.current&&r.position(Mt.current)),r.width(i),r.scaleX(1),r.scaleY(1);let a=0;if(n.curveEnabled){a=O(Object.assign(Object.assign({},n.toJSON()),{width:i}))}else{const t=v(Object.assign(Object.assign({},n.toJSON()),{text:lt,width:i}),{fontFamily:et,color:rt,forEditor:!0});try{a=f({html:wrapHtmlForRenderTag(t),width:i,accuracy:"performance"}).height}catch(l){a=k(t).height}}let s=x.textVerticalResizeEnabled?Math.max(a,q.current):a;"ellipsis"===x.textOverflow&&(s=q.current),r.height(s),n.set({width:r.width(),height:s,x:r.x(),y:r.y()})}else if(a){const t="resize"===x.textOverflow?ft?(null==pt?void 0:pt.height)||n.fontSize:xt:mt*n.fontSize,e=r.height()*r.scaleY();if(e<t){if(r.height(t),Mt.current){if("top-center"===Ft.current){const e=Tt.current*Math.PI/180,o=Yt.current-t;r.x(Mt.current.x-o*Math.sin(e)),r.y(Mt.current.y+o*Math.cos(e))}else{r.position(Mt.current)}}}else{r.height(e)}r.scaleY(1),r.scaleX(1),Yt.current=Math.max(t,e),n.set({x:r.x(),y:r.y(),height:r.height(),rotation:r.rotation()})}else{r.scaleX(1),r.scaleY(1),n.set({fontSize:n.fontSize*s,letterSpacing:n.letterSpacing,width:r.width()*s,x:r.x(),y:r.y(),rotation:r.rotation(),height:r.height()*s,text:I(n.text,s)})}Mt.current=t.target.position()},onTransformEnd:t=>{L(!1);const e=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),n.set({fontSize:n.fontSize*e,width:t.target.width()*e,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),shadowBlur:n.shadowBlur*e,shadowOffsetX:n.shadowOffsetX*e,shadowOffsetY:n.shadowOffsetY*e,strokeWidth:n.strokeWidth*e,text:I(n.text,e)})}}),tt&&t(i,{x:n.a.x,y:n.a.y,rotation:n.a.rotation,offsetY:-Ot,children:t(d,{divProps:{style:{zIndex:20}},children:t(B,{element:n,onChange:t=>{const e=Y({oldText:F(n.text),newText:F(t),element:n});n.set({text:t,fontSize:e})},onBlur:()=>{h(n)&&n.toggleEditMode(!1)},clickCoords:Rt.current})})})]})});
|
|
1
|
+
import{jsx as t,Fragment as e,jsxs as r}from"react/jsx-runtime";import o from"react";import{observer as n}from"mobx-react-lite";import{Group as i,Path as a,Rect as s,Shape as l}from"react-konva";import{nodeAutorun as c}from"../utils/mobx.js";import{isAlive as h}from"mobx-state-tree";import{Html as d}from"react-konva-utils";import{layout as f,drawLayout as u}from"render-tag";import{layoutTextOnPath as g,drawTextOnPathLayout as m}from"render-tag/path";import{flags as x}from"../utils/flags.js";import{applyFilter as p}from"./apply-filters.js";import{getLineHeight as y,usePrevious as b}from"./text-element.js";import{useFontSpecsLoader as w}from"./text-element/font-specs-loader.js";import{getHtml as v,getCurvePath as E,getCurveTextHeight as O}from"../utils/text-html.js";import{useColor as S}from"./use-color.js";import{isGradient as z}from"../utils/gradient.js";import{detectSize as j}from"../utils/html2canvas.js";import{generateBackgroundShapeFromRects as k}from"../utils/background-shape.js";import{useFadeIn as M}from"./use-fadein.js";import{incrementLoader as R}from"../utils/loader.js";import{removeTags as F}from"../utils/text.js";import{isTouchDevice as T}from"../utils/screen.js";import{getLimitedFontSize as Y}from"./text-element/max-font-size.js";import{normalizeRichTextHtml as X,extractFontSpecsFromHtml as C,scaleRichTextFontSizesInHtml as I}from"../utils/rich-text-html.js";import{RichEditor as B}from"./rich-editor.js";import{findFitFontSize as A}from"./text-element/fit-font-size.js";import{resetStyleContent as D}from"../utils/reset-style.js";import{xmlEscape as H}from"../utils/xml.js";const P=`<style>${D}\n/* render-tag draws list markers natively from the <ol>/<ul> tag + tree position\n (it ignores the polotno reset's ::before + counter() markers, which only work\n in real DOM — the Quill editor and the foreignObject rasterizer). The shared\n reset sets list-style:none for those ::before markers, which would suppress\n render-tag's native ones; restore the canonical marker types here so render-tag\n paints them. element.text is canonicalized to <ul>/<ol> upstream\n (normalizeRichTextHtml), so the tag alone selects bullet vs. number. */\nol { list-style-type: decimal; }\nul { list-style-type: disc; }\n/* Chrome's <code>/<pre> font-size UA quirk isn't reproducible on canvas — let\n them inherit so DOM and canvas line up. */\ncode, pre, kbd, samp { font-size: inherit; }</style>`;export function wrapHtmlForRenderTag(t){return P+t}export const RenderTagElement=n(({element:n,store:D})=>{var P;const W=o.useRef(null),J=o.useRef(null),[N,L]=o.useState(!1),q=o.useRef(n.height),V=n.isSelected,$=b(V),{textVerticalResizeEnabled:_}=x,Q=x.autoDeleteEmptyText,U=b(n.fontFamily),G=o.useMemo(()=>X(n.text,{fontSize:n.fontSize,fontFamily:n.fontFamily}),[n.text,n.fontSize,n.fontFamily]),K=o.useMemo(()=>C(G,{fontFamily:n.fontFamily,fontWeight:n.fontWeight,fontStyle:n.fontStyle}),[G,n.fontFamily,n.fontWeight,n.fontStyle]),[Z]=w(D,K,n.text||n.placeholder),tt=n._editModeEnabled;M(W);const et=Z?n.fontFamily:U&&U!==n.fontFamily?U:"Arial",rt=S(n).fill,ot=z(n.fill),nt=z(n.stroke)&&!!n.strokeWidth,it=!!n.strokeWidth&&(nt||ot),at="ellipsis"===x.textOverflow&&!n.curveEnabled&&!!n.height&&!it,st=!F(n.text)&&!!n.placeholder,lt=st?H(n.placeholder):n.text,ct=st?.6:n.a.opacity,ht=v(st?Object.assign(Object.assign({},n.toJSON()),{text:lt}):n,{fontFamily:et,color:rt,forEditor:!at}),dt=n.width||1,ft=n.curveEnabled,ut=function(t,e,r,n){return o.useMemo(()=>{if(n){return null}try{return f({html:wrapHtmlForRenderTag(t),width:Math.max(1,e),accuracy:"performance"})}catch(r){return console.error("render-tag layout failed:",r),null}},[t,e,r,n])}(ht,dt,Z,ft),gt=function(t,e,r){return o.useMemo(()=>{if(!e.curveEnabled){return null}const r=e.width||1,o=O(e),n=E(r,o,e.curvePower,e.fontSize);try{return g({html:wrapHtmlForRenderTag(t),path:n,align:"center",textBaseline:"middle"})}catch(i){return console.error("render-tag/path layoutTextOnPath failed:",i),null}},[r,e.curveEnabled,e.curvePower,e.fontSize,e.width,e.height,t])}(ht,n,Z),mt=y({fontLoaded:Z,fontFamily:n.fontFamily,fontSize:n.fontSize,lineHeight:n.lineHeight}),xt=ft?0:Math.max(null!==(P=null==ut?void 0:ut.height)&&void 0!==P?P:0,n.fontSize*mt),pt=gt?gt.bounds:null,yt=o.useMemo(()=>ut?ut.lines.map(t=>({left:t.bounds.x,right:t.bounds.x+t.bounds.width,top:t.bounds.y,bottom:t.bounds.y+t.bounds.height})):[],[ut]),bt=o.useRef([]),wt=o.useRef(!0),[,vt]=o.useReducer(t=>t+1,0);o.useEffect(()=>{const t=bt.current;t.length>0&&(bt.current=[],t.forEach(t=>t()))});const Et=o.useCallback((t,e,r,o)=>{const i=R(`text ${n.id}`),a=()=>{D.history.ignore(t,e,r).then(()=>{wt.current?(bt.current.push(i),vt()):i()})};o?queueMicrotask(a):a()},[n.id,D]);o.useEffect(()=>{if(!Z){return}if(!ut){return}if(!n.height){return void Et(()=>{h(n)&&(n.height||n.set({height:xt}))},void 0,void 0,!0)}if(D.isPlaying){return}const{textOverflow:t}=x,e=n.height!==xt&&(!_||n.height<xt),r=()=>Et(()=>{h(n)&&n.set({height:xt})},!1,!0);if("change-font-size"!==t||N||tt||n.curveEnabled){"resize"===t&&e&&!N&&r()}else{const t=A(st?Object.assign(Object.assign({},n.toJSON()),{text:lt,toJSON:()=>Object.assign(Object.assign({},n.toJSON()),{text:lt})}):n,{fontFamily:et,color:rt,forEditor:!0},t=>{try{return f({html:wrapHtmlForRenderTag(t),width:dt,accuracy:"performance"}).height}catch(P){return j(t).height}});t.fontSize!==n.fontSize?Et(()=>{if(!h(n)){return}const e={fontSize:t.fontSize};void 0!==t.text&&t.text!==n.text&&(e.text=t.text),n.set(e)},!1,!0):e&&r()}}),o.useEffect(()=>()=>{wt.current=!1;const t=bt.current;t.length>0&&(bt.current=[],t.forEach(t=>t()))},[]),o.useLayoutEffect(()=>{if(!Z||!n.curveEnabled||N){return}if(!pt||!pt.width){return}const t=t=>t&&_?Math.max(t,pt.height):pt.height;Math.abs(pt.width-n.width)<1&&Math.abs(t(n.height)-n.height)<1||Et(()=>{if(!h(n)){return}const e=pt.width-n.width,r=t(n.height),o=r-n.height;if(Math.abs(e)<1&&Math.abs(o)<1){return}const i=n.a.rotation*Math.PI/180,a=-e/2*Math.cos(i),s=-e/2*Math.sin(i);n.set({width:pt.width,height:r,x:n.a.x+a,y:n.a.y+s})},!1,!0,!0)},[Z,n.curveEnabled,pt,N,_,Et]),o.useEffect(()=>{$&&!V&&Q&&""===F(n.text)&&n.removable&&!n.placeholder&&D.deleteElements([n.id])},[Q,n.placeholder,n.removable,n.text,V,$]),o.useEffect(()=>c(n,()=>{const t=W.current;t&&p(t,n)}),[ut,gt,n.a.width,n.a.height,n.shadowColor,n.shadowOffsetX,n.shadowOffsetY,n.shadowOpacity]);let Ot=0;ft||"middle"!==n.verticalAlign?ft||"bottom"!==n.verticalAlign||(Ot=n.height-xt):Ot=(n.height-xt)/2;const St=n.backgroundPadding*(n.fontSize*mt*.5),zt=n.backgroundCornerRadius*(n.fontSize*mt*.5),jt=o.useMemo(()=>!n.backgroundEnabled||n.curveEnabled||n.legacyBackground||0===yt.length?"":k({rects:yt,padding:St,cornerRadius:zt}),[n.backgroundEnabled,n.curveEnabled,n.legacyBackground,yt,St,zt]),kt=T(),Mt=o.useRef(null),Rt=o.useRef(null),Ft=o.useRef(null),Tt=o.useRef(0),Yt=o.useRef(0),Xt=tt&&n.strokeWidth>0&&!n.curveEnabled,Ct=n.width>0?n.a.width/n.width:1;return r(e,{children:[n.curveEnabled||n.legacyBackground?t(s,{x:n.a.x,y:n.a.y,offsetX:St/Ct,offsetY:St/Ct,rotation:n.a.rotation,scaleX:Ct,scaleY:Ct,hideInExport:!n.showInExport,listening:!1,visible:n.backgroundEnabled,opacity:n.backgroundOpacity*ct,fill:n.backgroundColor,width:n.width+2*St,height:n.height+2*St,cornerRadius:zt}):t(a,{name:"rendertag-background",x:n.a.x,y:n.a.y,offsetY:-Ot/Ct,rotation:n.a.rotation,scaleX:Ct,scaleY:Ct,hideInExport:!n.showInExport,listening:!1,visible:n.backgroundEnabled&&jt.length>0,opacity:n.backgroundOpacity*ct,fill:n.backgroundColor,data:jt}),t(l,{ref:W,name:"rendertag-text",x:n.a.x,y:n.a.y,rotation:n.a.rotation,scaleX:Ct,scaleY:Ct,offsetY:Ct>0?-Ot/Ct:0,width:n.width,height:Math.max(n.height,xt),listening:!1,visible:(!tt||Xt)&&!!(ft?gt:ut),opacity:ct,shadowEnabled:n.shadowEnabled,shadowBlur:n.shadowBlur,shadowOffsetX:n.shadowOffsetX,shadowOffsetY:n.shadowOffsetY,shadowColor:n.shadowColor,shadowOpacity:n.shadowOpacity,hideInExport:!n.showInExport,sceneFunc:(t,e)=>{const r=t._context;if(r){try{if(ft){if(!gt||!pt){return}const t=(n.width-pt.width)/2-pt.x;r.save(),r.translate(t,-pt.y),m({layout:gt,ctx:r}),r.restore()}else{if(!ut){return}u({layout:ut,width:dt,ctx:r,pixelRatio:1})}}catch(o){console.error("render-tag draw failed:",o)}}}}),t(s,{ref:J,name:"element",x:n.a.x,y:n.a.y,listening:n.selectable,rotation:n.a.rotation,width:n.a.width,height:n.a.height,visible:!tt,draggable:kt?n.draggable&&V:n.draggable,preventDefault:!kt||V,opacity:0,hideInExport:!0,id:n.id,onDragMove:t=>{n.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{n.set({x:t.target.x(),y:t.target.y()})},onDblClick:t=>{n.contentEditable&&(Rt.current={x:t.evt.clientX,y:t.evt.clientY},n.toggleEditMode(!0))},onDblTap:t=>{var e;if(n.contentEditable){const r=null===(e=t.evt.changedTouches)||void 0===e?void 0:e[0];Rt.current=r?{x:r.clientX,y:r.clientY}:null,n.toggleEditMode(!0)}},onTransformStart:t=>{var e,r;L(!0),q.current=n.height;const o=null===(e=t.target.getStage())||void 0===e?void 0:e.findOne("Transformer");Ft.current=null!==(r=null==o?void 0:o.getActiveAnchor())&&void 0!==r?r:null,Tt.current=n.a.rotation,Yt.current=n.height},onTransform:t=>{var e;const r=t.target,o=(null===(e=r.getStage())||void 0===e?void 0:e.findOne("Transformer")).getActiveAnchor(),i="middle-left"===o||"middle-right"===o,a="top-center"===o||"bottom-center"===o,s=r.scaleX();if(i){const t=r.scaleX(),e=r.width()*t,o=n.fontSize;let i=e;e<o&&(i=o,Mt.current&&r.position(Mt.current)),r.width(i),r.scaleX(1),r.scaleY(1);let a=0;if(n.curveEnabled){a=O(Object.assign(Object.assign({},n.toJSON()),{width:i}))}else{const t=v(Object.assign(Object.assign({},n.toJSON()),{text:lt,width:i}),{fontFamily:et,color:rt,forEditor:!0});try{a=f({html:wrapHtmlForRenderTag(t),width:i,accuracy:"performance"}).height}catch(l){a=j(t).height}}let s=x.textVerticalResizeEnabled?Math.max(a,q.current):a;"ellipsis"===x.textOverflow&&(s=q.current),r.height(s),n.set({width:r.width(),height:s,x:r.x(),y:r.y()})}else if(a){const t="resize"===x.textOverflow?ft?(null==pt?void 0:pt.height)||n.fontSize:xt:mt*n.fontSize,e=r.height()*r.scaleY();if(e<t){if(r.height(t),Mt.current){if("top-center"===Ft.current){const e=Tt.current*Math.PI/180,o=Yt.current-t;r.x(Mt.current.x-o*Math.sin(e)),r.y(Mt.current.y+o*Math.cos(e))}else{r.position(Mt.current)}}}else{r.height(e)}r.scaleY(1),r.scaleX(1),Yt.current=Math.max(t,e),n.set({x:r.x(),y:r.y(),height:r.height(),rotation:r.rotation()})}else{r.scaleX(1),r.scaleY(1),n.set({fontSize:n.fontSize*s,letterSpacing:n.letterSpacing,width:r.width()*s,x:r.x(),y:r.y(),rotation:r.rotation(),height:r.height()*s,text:I(n.text,s)})}Mt.current=t.target.position()},onTransformEnd:t=>{L(!1);const e=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),n.set({fontSize:n.fontSize*e,width:t.target.width()*e,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),shadowBlur:n.shadowBlur*e,shadowOffsetX:n.shadowOffsetX*e,shadowOffsetY:n.shadowOffsetY*e,strokeWidth:n.strokeWidth*e,text:I(n.text,e)})}}),tt&&t(i,{x:n.a.x,y:n.a.y,rotation:n.a.rotation,offsetY:-Ot,children:t(d,{divProps:{style:{zIndex:20}},children:t(B,{element:n,onChange:t=>{const e=Y({oldText:F(n.text),newText:F(t),element:n});n.set({text:t,fontSize:e})},onBlur:()=>{h(n)&&n.toggleEditMode(!1)},clickCoords:Rt.current})})})]})});
|
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")}
|