polotno 2.34.2 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/canvas/drawing-layer.js +1 -1
- package/canvas/page.d.ts +7 -1
- package/canvas/page.js +1 -1
- package/canvas/text-element.js +1 -1
- package/canvas/tooltip.js +1 -1
- package/canvas/workspace-canvas.js +1 -1
- package/package.json +3 -2
- package/pages-timeline/audio-track.js +1 -1
- package/pages-timeline/element-track.js +1 -1
- package/pages-timeline/track-styles.d.ts +2 -0
- package/pages-timeline/track-styles.js +29 -4
- package/polotno.bundle.js +14 -14
- package/utils/text-html.js +1 -1
- package/utils/validate-key.js +1 -1
package/canvas/drawing-layer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{observer as t}from"mobx-react-lite";import{Group as r,Line as o,Rect as n}from"react-konva";import{pathToSVG as s}from"../utils/path-to-svg.js";export const DrawingLayer=t(({store:t,page:i,width:c,height:a,scale:l,xPadding:u,yPadding:h,bleed:g})=>{const[y,d]=e.useState(!1),[p,f]=e.useState([]),m=e.useRef(null),x="draw"===t.tool,{strokeWidth:k,stroke:w,opacity:$,brushType:b}=t.toolOptions,v=e.useCallback(e=>{if(!x){return}if(d(!0),e.cancelBubble=!0,!e.target.getStage()){return}const t=m.current.getRelativePointerPosition();t&&f([{x:t.x,y:t.y}])},[x,l,u,h,g]),E=e.useCallback(e=>{if(!x||!y){return}if(e.cancelBubble=!0,!e.target.getStage()){return}const t=m.current.getRelativePointerPosition();t&&f(e=>[...e,{x:t.x,y:t.y}])},[x,y,l,u,h,g]),S=e.useCallback(()=>{if(x&&y){if(d(!1),p.length
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import{Group as r,Line as o,Rect as n}from"react-konva";import{pathToSVG as s}from"../utils/path-to-svg.js";export const DrawingLayer=t(({store:t,page:i,width:c,height:a,scale:l,xPadding:u,yPadding:h,bleed:g})=>{const[y,d]=e.useState(!1),[p,f]=e.useState([]),m=e.useRef(null),x="draw"===t.tool,{strokeWidth:k,stroke:w,opacity:$,brushType:b}=t.toolOptions,v=e.useCallback(e=>{if(!x){return}if(d(!0),e.cancelBubble=!0,!e.target.getStage()){return}const t=m.current.getRelativePointerPosition();t&&f([{x:t.x,y:t.y}])},[x,l,u,h,g]),E=e.useCallback(e=>{if(!x||!y){return}if(e.cancelBubble=!0,!e.target.getStage()){return}const t=m.current.getRelativePointerPosition();t&&f(e=>[...e,{x:t.x,y:t.y}])},[x,y,l,u,h,g]),S=e.useCallback(()=>{if(x&&y){if(d(!1),p.length>=1){try{const e=s(p,{stroke:w,strokeWidth:k,smooth:!0}),r=t.selectedElementsIds.slice();t.history.transaction(()=>{i.addElement({type:"svg",x:e.x,y:e.y,width:e.width,height:e.height,src:e.src,opacity:$},{skipSelect:!0})}),t.selectElements(r)}catch(e){console.error("Error creating path SVG:",e)}}f([])}},[x,y,p,w,k,$,i,t.history,t]),M=e.useMemo(()=>p.flatMap(e=>[e.x,e.y]),[p]);return e.useEffect(()=>{if(x&&m.current){const e=m.current.getStage();if(!e){return}const t=k*l;if(t>100||t<4){e.container().style.cursor="crosshair"}else{const r=t/2,o=t/2,n=`data:image/svg+xml;base64,${btoa(`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}" viewBox="0 0 ${t} ${t}">\n <circle cx="${o}" cy="${o}" r="${r-1}" fill="${w}" opacity="${$}" stroke="white" stroke-width="1"/>\n <circle cx="${o}" cy="${o}" r="${r-1}" fill="none" stroke="black" stroke-width="1" opacity="0.3"/>\n </svg>`)}`;e.container().style.cursor=`url("${n}") ${o} ${o}, crosshair`}return()=>{e.container()&&(e.container().style.cursor="")}}},[x,w,k,$,l]),x?e.createElement(r,{ref:m,listening:x,x:u+g*l,y:h+g*l,scaleX:l,scaleY:l},e.createElement(n,{x:-(u+g*l)/l,y:-(h+g*l)/l,width:c/l,height:a/l,fill:"transparent",onMouseDown:v,onMouseMove:E,onMouseUp:S,onTouchStart:v,onTouchMove:E,onTouchEnd:S}),p.length>0&&e.createElement(o,{points:M,stroke:w,strokeWidth:k,lineCap:"round",lineJoin:"round",opacity:$,tension:.5,listening:!1})):null});
|
package/canvas/page.d.ts
CHANGED
|
@@ -66,8 +66,14 @@ type PageProps = {
|
|
|
66
66
|
left?: number;
|
|
67
67
|
right?: number;
|
|
68
68
|
};
|
|
69
|
+
transformerSafeArea?: {
|
|
70
|
+
top?: number;
|
|
71
|
+
bottom?: number;
|
|
72
|
+
left?: number;
|
|
73
|
+
right?: number;
|
|
74
|
+
};
|
|
69
75
|
};
|
|
70
|
-
declare const _default: (({ store, page, width, height, pageControlsEnabled, backColor, pageBorderColor, activePageBorderColor, components, bleedColor, altCloneEnabled, viewportSize, selectionRectFill, selectionRectStroke, selectionRectStrokeWidth, snapGuideStroke, snapGuideStrokeWidth, snapGuideDash, transformLabelFill, transformLabelTextFill, distanceGuideStroke, distanceLabelFill, distanceLabelTextFill, layout, tooltipSafeArea, }: PageProps) => React.JSX.Element) & {
|
|
76
|
+
declare const _default: (({ store, page, width, height, pageControlsEnabled, backColor, pageBorderColor, activePageBorderColor, components, bleedColor, altCloneEnabled, viewportSize, selectionRectFill, selectionRectStroke, selectionRectStrokeWidth, snapGuideStroke, snapGuideStrokeWidth, snapGuideDash, transformLabelFill, transformLabelTextFill, distanceGuideStroke, distanceLabelFill, distanceLabelTextFill, layout, tooltipSafeArea, transformerSafeArea, }: PageProps) => React.JSX.Element) & {
|
|
71
77
|
displayName: string;
|
|
72
78
|
};
|
|
73
79
|
export default _default;
|
package/canvas/page.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__rest||function(e,t){var n={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++){t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]])}}return n};import t from"react";import{observer as n,useLocalObservable as i}from"mobx-react-lite";import{action as o,runInAction as r}from"mobx";import{Group as l,Image as a,Label as s,Layer as c,Line as d,Rect as m,Stage as h,Tag as u,Text as g,Transformer as x}from"react-konva";import p from"use-image";import f from"konva";import b from"./element.js";import{DrawingLayer as y}from"./drawing-layer.js";import{ensureDragOrder as v,useSnap as E}from"./use-transformer-snap.js";import{useImageLoader as w}from"./image-element.js";import{getCrop as Y}from"../utils/crop.js";import{___ as X,isCreditVisible as S}from"../utils/validate-key.js";import{getClientRect as k,getTotalClientRect as A}from"../utils/math.js";import{pxToUnitRounded as R,pxToUnitString as C}from"../utils/unit.js";import{flags as O}from"../utils/flags.js";import{isTouchDevice as M}from"../utils/screen.js";import{useColor as P}from"./use-color.js";import{isGradient as L}from"../utils/gradient.js";import{Html as T}from"react-konva-utils";const j=f.DD._drag;window.removeEventListener("mousemove",j),f.DD._drag=function(e){r(()=>{j.call(this,e)})},window.addEventListener("mousemove",f.DD._drag);const I=new f.Group,D=20;I.add(new f.Rect({width:D,height:D,fill:"white"})),I.add(new f.Path({scaleX:D/24,scaleY:D/24,data:"M4.98313549,11.0001422 C5.49589839,10.9914935 5.92501998,11.3703506 5.99116425,11.8666444 L5.99985778,11.9831355 L6.00348884,12.2068855 C6.11245031,15.4321748 8.76323537,17.9999971 11.9999971,17.9999971 C12.1869612,17.9999971 12.3726725,17.9914753 12.5567465,17.9745765 L12.2928932,17.7071068 C11.9023689,17.3165825 11.9023689,16.6834175 12.2928932,16.2928932 C12.6834175,15.9023689 13.3165825,15.9023689 13.7071068,16.2928932 L15.7071068,18.2928932 C16.0976311,18.6834175 16.0976311,19.3165825 15.7071068,19.7071068 L13.7071068,21.7071068 C13.3165825,22.0976311 12.6834175,22.0976311 12.2928932,21.7071068 C11.9023689,21.3165825 11.9023689,20.6834175 12.2928932,20.2928932 L12.6111505,19.9769552 C12.4086045,19.9922816 12.2047796,19.9999971 11.9999971,19.9999971 C7.7687005,19.9999971 4.28886152,16.7094374 4.01666425,12.5105203 L4.00420123,12.2575143 L4.00014222,12.0168645 C3.9908282,11.4646583 4.43092928,11.0094562 4.98313549,11.0001422 Z M11.7071068,2.29289322 C12.0675907,2.65337718 12.0953203,3.22060824 11.7902954,3.61289944 L11.7071068,3.70710678 L11.3891629,4.0230186 C11.5916051,4.00770767 11.7953244,4 12,4 C16.418278,4 20,7.581722 20,12 C20,12.5522847 19.5522847,13 19,13 C18.4477153,13 18,12.5522847 18,12 C18,8.6862915 15.3137085,6 12,6 C11.8129339,6 11.6271216,6.00853145 11.4429483,6.02544919 L11.7071068,6.29289322 C12.0976311,6.68341751 12.0976311,7.31658249 11.7071068,7.70710678 C11.3466228,8.06759074 10.7793918,8.09532028 10.3871006,7.79029539 L10.2928932,7.70710678 L8.29289322,5.70710678 C7.93240926,5.34662282 7.90467972,4.77939176 8.20970461,4.38710056 L8.29289322,4.29289322 L10.2928932,2.29289322 C10.6834175,1.90236893 11.3165825,1.90236893 11.7071068,2.29289322 Z",fill:"black"}));const W=I.toCanvas({pixelRatio:2,width:D,height:D});export const TRANSFORMER_STYLE={enabledAnchors:["top-left","top-center","top-right","middle-left","bottom-left","bottom-right","bottom-center","middle-right"],borderEnabled:!0,rotateEnabled:!0,rotationSnaps:[0,45,90,135,180,225,270,315],ignoreStroke:!0,flipEnabled:!1,anchorStrokeWidth:2,borderStrokeWidth:2,rotateAnchorOffset:30,anchorStyleFunc:e=>{if(e.hasName("rotater")){const t=20;e.setAttrs({width:t,height:t,cornerRadius:t/2,offsetX:t/2,offsetY:t/2,fillPatternImage:W,fillPatternScaleX:t/D/2,fillPatternScaleY:t/D/2,fillPriority:"pattern",fillPatternRepeat:"no-repeat"})}}};export const setTransformerStyle=e=>{Object.assign(TRANSFORMER_STYLE,e)};const F={text:{enabledAnchors:["top-left","top-right","middle-left","bottom-left","bottom-right","middle-right"]},svg:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},gif:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},line:{enabledAnchors:[],borderEnabled:!1,rotateEnabled:!1},image:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},many:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},group:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]}};export function registerTransformerAttrs(e,t){F[e]=F[e]||t,Object.assign(F[e],t)}const B=e=>t.createElement(m,Object.assign({},e,{preventDefault:!1})),_=n=>{var{url:i}=n,o=e(n,["url"]);const[r,l]=p(i,"anonymous"),s=r?Y(r,{width:o.width,height:o.height},"center-middle"):{};return w(l,i,"page background"),t.createElement(a,Object.assign({image:r},o,s))},G=e=>{const n=P({fill:e.fill,a:{width:e.width,height:e.height}});return t.createElement(m,Object.assign({},e,n))},N=n=>{const{background:i,scale:o,borderColor:r}=n,l=e(n,["background","scale","borderColor"]),a=t.useMemo(()=>!!f.Util.colorToRGBA(i)||L(i),[i]),s=t.useMemo(()=>{const e=document.createElement("canvas"),t=30;e.width=60,e.height=60;const n=e.getContext("2d");return n&&(n.fillStyle="black",n.fillRect(t,0,t,t),n.fillRect(0,t,t,t)),e},[]);return t.createElement(t.Fragment,null,t.createElement(m,Object.assign({fillPatternImage:s},l,{opacity:.1,hideInExport:!0})),a?t.createElement(G,Object.assign({fill:i},l)):t.createElement(_,Object.assign({url:i},l)))},V=n(({selection:e,fill:n="rgba(0, 161, 255, 0.3)",stroke:i="rgb(0, 161, 255)",strokeWidth:o=1})=>e.visible?t.createElement(m,{name:"selection",x:Math.min(e.x1,e.x2),y:Math.min(e.y1,e.y2),width:Math.abs(e.x1-e.x2),height:Math.abs(e.y1-e.y2),fill:n,stroke:i,strokeWidth:o}):null);function z(e){let t=180*e/Math.PI;return t%=360,t>180?t-=360:t<-180&&(t+=360),Math.round(t)}const H=n(({x:e,y:n,width:i,height:o,rotation:r,anchor:l,store:a,tagFill:c,textFill:d})=>{const m=k({x:e,y:n,width:i,height:o,rotation:f.Util.radToDeg(r)});if(void 0===l){return null}const h=(o/2+70)*Math.cos(r-Math.PI/2),x=(o/2+70)*Math.sin(r-Math.PI/2),p=R({unit:a.unit,dpi:a.dpi,px:i/a.scale,precious:"px"===a.unit?0:1})+" x "+R({unit:a.unit,dpi:a.dpi,px:o/a.scale,precious:"px"===a.unit?0:1})+("px"===a.unit?"":" "+a.unit);return t.createElement(t.Fragment,null,t.createElement(s,{x:(m.minX+m.maxX)/2+h,y:(m.minY+m.maxY)/2+x,offsetX:14,offsetY:14,visible:"rotater"===l},t.createElement(u,{cornerRadius:5,fill:c||"rgb(0, 161, 255)"}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:d||"white",padding:8,text:z(r).toString()+"°"})),t.createElement(s,{x:(m.minX+m.maxX)/2,y:m.maxY+20,visible:"rotater"!==l},t.createElement(u,{cornerRadius:5,fill:c||"rgb(0, 161, 255)",pointerDirection:"up",pointerHeight:0,pointerWidth:0}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:d||"white",padding:8,text:p})))}),Z=n(({elements:e,store:n})=>{const i=e.filter(e=>e.alwaysOnTop),o=e.filter(e=>!e.alwaysOnTop).concat(i);return t.createElement(t.Fragment,null,o.map(e=>t.createElement(b,{key:e.id,store:n,element:e,onClick:()=>{console.warn("Polotno warning: onClick callback is deprecated. Just stop using it. Polotno will do selection automatically.")}})))});export const useContextMenu=({store:e})=>{const[n,i]=t.useState(!1),[o,r]=t.useState({x:0,y:0}),l=t.useCallback(e=>{i(!0),r(e)},[]);return{open:l,close:t.useCallback(()=>{i(!1)},[]),props:{isOpen:n,offset:o,setIsOpen:i}}};let $=null;export const registerNextDomDrop=e=>{$=e};const K=atob("UG9sb3RubyBmcmVlIGxpY2Vuc2UgbGltaXRhdGlvbiBleGNlZWRlZCAtIFBsZWFzZSB1cGdyYWRlIHlvdXIgYWNjb3VudC4="),U=atob("cmVk"),J=atob("djAuOS4y"),q=e=>t.createElement(t.Fragment,null,t.createElement(s,{fill:U,height:200},t.createElement(u,{fill:U}),t.createElement(g,Object.assign({},e,{fill:"white",text:K,height:void 0,padding:10,fontSize:20}))));export default n(({store:e,page:n,width:r,height:a,pageControlsEnabled:p,backColor:b,pageBorderColor:w,activePageBorderColor:Y,components:R,bleedColor:P,altCloneEnabled:L,viewportSize:j,selectionRectFill:I,selectionRectStroke:D,selectionRectStrokeWidth:W,snapGuideStroke:_,snapGuideStrokeWidth:G,snapGuideDash:z,transformLabelFill:K,transformLabelTextFill:U,distanceGuideStroke:Q,distanceLabelFill:ee,distanceLabelTextFill:te,layout:ne="vertical",tooltipSafeArea:ie})=>{const oe=e.bleedVisible?n.bleed:0,re=n.computedWidth+2*oe,le=n.computedHeight+2*oe,ae=(r-re*e.scale)/2,se=(a-le*e.scale)/2,ce=t.useRef(null),de=t.useRef(null),me=t.useRef(null),he=null==p||p,[ue,ge]=t.useState(null),[xe,pe]=t.useState({}),fe=useContextMenu({store:e}),be=e.selectedElements.find(e=>e._cropModeEnabled),ye=e.selectedElements.find(e=>e.curveEnabled),ve=e.selectedShapes.filter(e=>!e.resizable).length>0,Ee=e.selectedShapes.filter(e=>!e.draggable).length>0,we=e.selectedElements.filter(e=>!e.visible).length>0;t.useLayoutEffect(()=>{var t,n,i;if(!ce.current){return}const o=ce.current.getStage(),r=e.selectedShapes.map(e=>e._cropModeEnabled?null:o.findOne("#"+e.id)).filter(e=>e),l=1===e.selectedElements.length,a=l&&(null===(t=e.selectedElements[0])||void 0===t?void 0:t.type)||"many";F[a]?(ce.current.setAttrs(Object.assign(Object.assign({},TRANSFORMER_STYLE),F[a])),"svg"!==a&&"image"!==a&&"gif"!==a||e.selectedElements[0].keepRatio||ce.current.setAttrs({enabledAnchors:TRANSFORMER_STYLE.enabledAnchors}),"text"===a&&O.textVerticalResizeEnabled&&ce.current.setAttrs({enabledAnchors:null===(n=F.text.enabledAnchors)||void 0===n?void 0:n.concat(["bottom-center"])}),"text"===a&&l&&e.selectedElements[0].curveEnabled&&ce.current.setAttrs({enabledAnchors:F.many.enabledAnchors})):ce.current.setAttrs(TRANSFORMER_STYLE),ve&&ce.current.enabledAnchors([]),Ee&&ce.current.rotateEnabled(!1),r.find(e=>null==e?void 0:e.isDragging())&&r.forEach(e=>{e.isDragging()||null==e||e.startDrag()}),ce.current.nodes(r),v(),null===(i=ce.current.getLayer())||void 0===i||i.batchDraw()},[e.selectedShapes,be,ve,we,Ee,ye]);const Ye=()=>{const e=ce.current;if(!e){return}if(!e.isTransforming()){return void pe({})}if(!e.nodes().length||!e.isTransforming()){return}const t=e.__getNodeRect(),n=null==e?void 0:e.getActiveAnchor(),i=e.getStage();pe({anchor:n,x:t.x-i.x(),y:t.y-i.y(),rotation:t.rotation,width:t.width,height:t.height})};t.useEffect(()=>{var e;null===(e=ce.current)||void 0===e||e.update(),Ye()},[e.scale]);const Xe=i(()=>({visible:!1,x1:0,y1:0,x2:0,y2:0})),Se=t.useRef(!1),ke=M(),Ae=o(e=>{var t,n,i,o;if(ke){return}Se.current=!1;const r=e.target.findAncestor(".elements-container"),l=e.target.findAncestor("Transformer"),a=e.target.findAncestor(".page-abs-container");if(r||l||a){return}const s=null===(t=e.target.getStage())||void 0===t?void 0:t.getPointerPosition();s.x-=null===(n=e.target.getStage())||void 0===n?void 0:n.x(),s.y-=null===(i=e.target.getStage())||void 0===i?void 0:i.y(),s&&(Xe.visible=!0,Xe.x1=s.x,Xe.y1=s.y,Xe.x2=s.x,Xe.y2=s.y,(null===(o=e.target.getStage())||void 0===o?void 0:o.getPointersPositions().length)>=2&&(Xe.visible=!1))});(({stageRef:e,containerRef:n,viewportSize:i})=>{t.useEffect(()=>{var t;const i=null===(t=n.current)||void 0===t?void 0:t.closest(".polotno-workspace-inner");function o(){var t;if(!e.current){return}const o=null===(t=n.current)||void 0===t?void 0:t.getBoundingClientRect(),r=null==i?void 0:i.getBoundingClientRect(),l=Math.max(0,r.left-o.left-100),a=Math.max(0,r.top-o.top-100);e.current.position({x:-l,y:-a}),e.current.container().style.transform=`translate(${l}px, ${a}px)`}return o(),i.addEventListener("scroll",o),()=>{i.removeEventListener("scroll",o)}},[i.width,i.height])})({stageRef:de,containerRef:me,viewportSize:j}),t.useEffect(()=>{const t=o(e=>{var t,n,i,o;if(!Xe.visible){return}null===(t=de.current)||void 0===t||t.setPointersPositions(e);let r=null===(n=de.current)||void 0===n?void 0:n.getPointerPosition();r?(r.x-=null===(i=de.current)||void 0===i?void 0:i.x(),r.y-=null===(o=de.current)||void 0===o?void 0:o.y()):r={x:Xe.x2,y:Xe.y2},Xe.x2=r.x,Xe.y2=r.y}),n=o(()=>{if(!Xe.visible){return}if(!de.current){return}const t=de.current.findOne(".selection"),n=t?t.getClientRect():{width:0,height:0,x:0,y:0};if(n.width&&n.height){const t=[];de.current.find(".element").forEach(i=>{const o=i.getClientRect(),r=e.getElementById(i.id()),l=null==r?void 0:r.draggable,a=null==r?void 0:r.selectable;f.Util.haveIntersection(n,o)&&l&&a&&t.push(r.top.id)});const i=[...new Set(t)];e.selectElements(i)}Xe.visible=!1,Se.current=!0});return window.addEventListener("mousemove",t),window.addEventListener("touchmove",t),window.addEventListener("mouseup",n),window.addEventListener("touchend",n),()=>{window.removeEventListener("mousemove",t),window.removeEventListener("touchmove",t),window.removeEventListener("mouseup",n),window.removeEventListener("touchend",n)}},[]);const Re=t.useCallback(t=>{if(!e.selectedElements[0]){return}if(t&&e.selectedElementsIds.includes(t)){return}const i=A(e.selectedShapes),o=t?e.getElementById(t):{x:0,y:0,width:n.computedWidth,height:n.computedHeight,rotation:0},r=k(o),l=[];i.minX>r.maxX&&l.push({distance:i.minX-r.maxX,box1:i,box2:r,points:[{x:i.minX,y:i.minY+i.height/2},{x:r.maxX,y:i.minY+i.height/2},{x:r.maxX,y:r.minY+r.height/2}]}),i.maxX<r.minX&&l.push({distance:r.minX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:i.minY+i.height/2},{x:r.minX,y:i.minY+i.height/2},{x:r.minX,y:r.minY+r.height/2}]}),i.minY>r.maxY&&l.push({box1:i,box2:r,distance:i.minY-r.maxY,points:[{x:i.minX+i.width/2,y:i.minY},{x:i.minX+i.width/2,y:r.maxY},{x:r.minX+r.width/2,y:r.maxY}]}),i.maxY<r.minY&&l.push({box1:i,box2:r,distance:r.minY-i.maxY,points:[{x:i.minX+i.width/2,y:i.maxY},{x:i.minX+i.width/2,y:r.minY},{x:r.minX+r.width/2,y:r.minY}]});const a=i.minX>=r.minX&&i.maxX<=r.maxX&&i.minY>=r.minY&&i.maxY<=r.maxY;if(a&&(l.push({distance:i.minX-r.minX,box1:i,box2:r,points:[{x:i.minX,y:i.minY+i.height/2},{x:r.minX,y:i.minY+i.height/2},{x:r.minX,y:r.minY+r.height/2}]}),l.push({distance:r.maxX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:i.minY+i.height/2},{x:r.maxX,y:i.minY+i.height/2},{x:r.maxX,y:r.minY+r.height/2}]}),l.push({box1:i,box2:r,distance:i.minY-r.minY,points:[{x:i.minX+i.width/2,y:i.minY},{x:i.minX+i.width/2,y:r.minY},{x:r.minX+r.width/2,y:r.minY}]}),l.push({box1:i,box2:r,distance:r.maxY-i.maxY,points:[{x:i.minX+i.width/2,y:i.maxY},{x:i.minX+i.width/2,y:r.maxY},{x:r.minX+r.width/2,y:r.maxY}]})),0===l.length&&!a){const e=i.minX<r.maxX&&i.maxX>r.minX,t=i.minY<r.maxY&&i.maxY>r.minY;if(e&&t){const e=(Math.max(i.minY,r.minY)+Math.min(i.maxY,r.maxY))/2,t=(Math.max(i.minX,r.minX)+Math.min(i.maxX,r.maxX))/2;i.minX<r.minX?l.push({distance:r.minX-i.minX,box1:i,box2:r,points:[{x:i.minX,y:e},{x:r.minX,y:e},{x:r.minX,y:e}]}):l.push({distance:i.minX-r.minX,box1:i,box2:r,points:[{x:i.minX,y:e},{x:r.minX,y:e},{x:r.minX,y:e}]}),i.maxX>r.maxX?l.push({distance:i.maxX-r.maxX,box1:i,box2:r,points:[{x:r.maxX,y:e},{x:i.maxX,y:e},{x:r.maxX,y:e}]}):l.push({distance:r.maxX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:e},{x:r.maxX,y:e},{x:r.maxX,y:e}]}),i.minY<r.minY?l.push({box1:i,box2:r,distance:r.minY-i.minY,points:[{x:t,y:i.minY},{x:t,y:r.minY},{x:t,y:r.minY}]}):l.push({box1:i,box2:r,distance:i.minY-r.minY,points:[{x:t,y:i.minY},{x:t,y:r.minY},{x:t,y:r.minY}]}),i.maxY>r.maxY?l.push({box1:i,box2:r,distance:i.maxY-r.maxY,points:[{x:t,y:r.maxY},{x:t,y:i.maxY},{x:t,y:r.maxY}]}):l.push({box1:i,box2:r,distance:r.maxY-i.maxY,points:[{x:t,y:i.maxY},{x:t,y:r.maxY},{x:t,y:r.maxY}]})}}JSON.stringify(ue)!==JSON.stringify(l)&&ge(l)},[e,n]);t.useEffect(()=>{e.distanceGuidesVisible?Re():ue&&ge(null)},[e.distanceGuidesVisible,Re,e.selectedShapes.map(e=>`${e.x},${e.y},${e.width},${e.height},${e.rotation}`).join("|")]);const Ce=t.useRef(!1);t.useEffect(()=>{var e;let t;const n=null===(e=me.current)||void 0===e?void 0:e.closest(".polotno-workspace-inner"),i=()=>{Ce.current=!0,clearTimeout(t),t=setTimeout(()=>{Ce.current=!1},300)};return n.addEventListener("scroll",i),()=>{clearTimeout(t),n.removeEventListener("scroll",i)}},[]);const Oe=t=>{if(e.activePage!==n&&n.select(),Ce.current){return}if(Se.current){return}const i=t.evt.ctrlKey||t.evt.metaKey||t.evt.shiftKey,o=t.target.findAncestor(".elements-container"),r=t.target.findAncestor(".page-abs-container"),l=t.target.findAncestor("Transformer");if(!(i||o||l||r||Xe.visible)){return void e.selectElements([])}const a=t.target.findAncestor(".element-container",!0),s=(null==a?void 0:a.findOne(".element"))||t.target.findAncestor(".element",!0),c=e.getElementById(null==s?void 0:s.id()),d=null==c?void 0:c.top,m=null==d?void 0:d.id,h=e.selectedElementsIds.indexOf(m)>=0,u=t.target.findAncestor(".page-container",!0);m&&i&&!h?e.selectElements(e.selectedElementsIds.concat([m])):m&&i&&h?e.selectElements(e.selectedElementsIds.filter(e=>e!==m)):!m||i||h?u?e.selectPages([n.id]):e.selectPages([]):e.selectElements([m])};E(ce,e,{stroke:_,strokeWidth:G,dash:z});const Me=e.activePage===n,Pe=e._selectedPagesIds.includes(n.id),Le=null==R?void 0:R.PageControls,Te=null==R?void 0:R.Tooltip,je=null==R?void 0:R.ContextMenu,Ie=1/e.scale,De=0/e.scale;return t.createElement("div",{ref:me,onDragOver:e=>e.preventDefault(),onDrop:t=>{if(t.preventDefault(),!de.current){return}de.current.setPointersPositions(t);const i=de.current.findOne(".elements-container").getRelativePointerPosition(),o=de.current.getPointerPosition(),r=de.current.getAllIntersections(o).map(e=>e.findAncestor(".element",!0)).filter(Boolean),l=[...new Set(r.reverse())].map(t=>e.getElementById(t.id())),a=l[0];$&&($(i,a,{elements:l,page:n}),$=null)},style:{position:"relative",width:r+"px",height:a+"px",overflow:"hidden",flexShrink:0},className:"polotno-page-container"+(Me?" active-page":"")},t.createElement(h,{ref:de,width:Math.min(r,j.width+200),height:Math.min(j.height+200,a),onClick:Oe,onTap:Oe,onContextMenu:t=>{t.evt.preventDefault();const n=t.target.findAncestor(".element",!0),i=e.getElementById(null==n?void 0:n.id()),o=null==i?void 0:i.top,r=null==o?void 0:o.id;r?e.selectedElementsIds.indexOf(r)>=0||e.selectElements([r]):e.selectElements([]),fe.open({x:t.evt.clientX,y:t.evt.clientY})},onMouseDown:Ae,onMouseMove:t=>{if(!e.distanceGuidesVisible&&!t.evt.altKey){return void(ue&&ge(null))}const n=t.target.findAncestor(".element",!0),i=null==n?void 0:n.id();Re(i)},onDragStart:t=>{var n;const i=t.target.findAncestor(".element",!0);if(i){const o=e.getElementById(null==i?void 0:i.id()),r=null==o?void 0:o.top,l=null==r?void 0:r.id;!(e.selectedElementsIds.indexOf(l)>=0)&&l&&(e.selectElements([l]),t.target.stopDrag(),t.target.startDrag(t),null===(n=ce.current)||void 0===n||n.startDrag(t))}ue&&ge(null)},pageId:n.id,style:{position:"absolute",overflow:"hidden",top:0,left:0}},t.createElement(c,null,t.createElement(B,{width:r,height:a,fill:b}),t.createElement(l,{x:ae,y:se,scaleX:e.scale,scaleY:e.scale,name:"page-container"},t.createElement(l,{name:"page-container-2"},t.createElement(l,{name:"page-background-group",x:oe,y:oe},t.createElement(N,{x:-n.bleed,y:-n.bleed,width:n.computedWidth+2*n.bleed,height:n.computedHeight+2*n.bleed,background:n.background,name:"page-background",preventDefault:!1,scale:e.scale})),t.createElement(l,{x:oe,y:oe,name:"elements-container",listening:!e.isPlaying},t.createElement(m,{name:"elements-area",width:n.computedWidth,height:n.computedHeight,listening:!1}),t.createElement(Z,{elements:n.children,store:e})),t.createElement(m,{stroke:P,name:"bleed",strokeWidth:n.bleed,x:n.bleed/2,y:n.bleed/2,width:n.computedWidth+n.bleed,height:n.computedHeight+n.bleed,listening:!1,visible:n.bleed>0&&e.bleedVisible,hideInExport:!0}),X()===J&&t.createElement(q,{name:"hit-detection",x:-Ie/2-De,y:-Ie/2-De,width:re+Ie+2*De,height:le+Ie+2*De}))),t.createElement(d,{name:"workspace-background",points:[0,0,r,0,r,a,0,a,0,0,ae,se,ae,a-se,r-ae,a-se,r-ae,se,ae,se],listening:!1,closed:!0,fill:b}),t.createElement(l,{x:ae,y:se,scaleX:e.scale,scaleY:e.scale},t.createElement(m,{name:"page-highlight",hideInExport:!0,x:-Ie/2-De,y:-Ie/2-De,width:re+Ie+2*De,height:le+Ie+2*De,stroke:Pe?Y:w,strokeWidth:2,listening:!1,strokeScaleEnabled:!1})),t.createElement(l,{x:ae+oe*e.scale,y:se+oe*e.scale,scaleX:e.scale,scaleY:e.scale,name:"page-abs-container"},t.createElement(x,{ref:ce,onDragStart:t=>{var i;(null===(i=t.evt)||void 0===i?void 0:i.altKey)&&L&&e.selectedElements.forEach(e=>{const t=e.clone({},{skipSelect:!0}),i=n.children.indexOf(e);n.setElementZIndex(t.id,i)}),e.history.startTransaction()},onDragEnd:()=>{e.history.endTransaction()},onTransformStart:()=>{e.history.startTransaction(),ge(null)},boundBoxFunc:(e,t)=>{const n=Math.abs(t.width)<1||Math.abs(t.height)<1,i=Math.abs(e.width)<1||Math.abs(e.height)<1;return n&&!i?e:t},onTransform:e=>{const t=ce.current.nodes(),n=t[t.length-1];e.target===n&&setTimeout(()=>{Ye()},0)},onTransformEnd:t=>{pe({}),e.history.endTransaction()},visible:!e.isPlaying}),ue&&ue.map(({points:n,distance:i,box1:o,box2:r},a)=>t.createElement(l,{name:"distances-container",hideInExport:!0,key:a,listening:!1},t.createElement(m,Object.assign({},o,{stroke:Q,strokeWidth:1,strokeScaleEnabled:!1})),t.createElement(m,Object.assign({},r,{stroke:Q,strokeWidth:1,strokeScaleEnabled:!1})),t.createElement(d,{points:[n[0].x,n[0].y,n[1].x,n[1].y],stroke:Q,strokeWidth:1,strokeScaleEnabled:!1}),t.createElement(d,{points:[n[1].x,n[1].y,n[2].x,n[2].y],stroke:Q,strokeWidth:1,strokeScaleEnabled:!1}),t.createElement(s,{x:(n[0].x+n[1].x)/2,y:(n[0].y+n[1].y)/2,offsetY:-10,scaleX:1/e.scale,scaleY:1/e.scale},t.createElement(u,{cornerRadius:5,fill:ee,pointerDirection:"down"}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:te,padding:5,text:C({unit:e.unit,dpi:e.dpi,px:i})})))),n._rendering&&t.createElement(l,null,t.createElement(m,{width:re,height:le,fill:"rgba(255,255,255,0.9)"}),t.createElement(g,{text:"Rendering...",fontSize:60,width:re,height:le,align:"center",verticalAlign:"middle"})),Te&&t.createElement(Te,{components:R,store:e,page:n,stageRef:de,tooltipSafeArea:ie}),je&&t.createElement(T,null,t.createElement(je,Object.assign({components:R,store:e},fe.props)))),t.createElement(y,{store:e,page:n,width:r,height:a,scale:e.scale,xPadding:ae,yPadding:se,bleed:oe}),t.createElement(H,Object.assign({},xe,{store:e,tagFill:K,textFill:U})),t.createElement(V,{selection:Xe,fill:I,stroke:D,strokeWidth:W}),S()&&t.createElement(g,{text:"Powered by polotno.com",fontSize:14,fill:"rgba(0,0,0,0.6)",x:r-170,y:a-18,onMouseEnter:e=>{e.target.getStage().container().style.cursor="pointer"},onMouseLeave:e=>{e.target.getStage().container().style.cursor=""},onTouchStart:e=>{e.cancelBubble=!0},onMouseDown:e=>{e.cancelBubble=!0},onClick:()=>{window.open("https://polotno.com")},onTap:()=>{window.open("https://polotno.com")}}),t.createElement(l,{name:"line-guides"}))),he&&Le&&t.createElement(Le,{store:e,page:n,xPadding:ae,yPadding:se,layout:ne}))});
|
|
1
|
+
var e=this&&this.__rest||function(e,t){var n={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++){t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]])}}return n};import t from"react";import{observer as n,useLocalObservable as i}from"mobx-react-lite";import{action as o,runInAction as r}from"mobx";import{Group as l,Image as a,Label as s,Layer as c,Line as d,Rect as m,Stage as h,Tag as u,Text as g,Transformer as x}from"react-konva";import p from"use-image";import f from"konva";import b from"./element.js";import{DrawingLayer as v}from"./drawing-layer.js";import{ensureDragOrder as y,useSnap as E}from"./use-transformer-snap.js";import{useImageLoader as w}from"./image-element.js";import{getCrop as Y}from"../utils/crop.js";import{___ as X,isCreditVisible as S}from"../utils/validate-key.js";import{getClientRect as k,getTotalClientRect as A}from"../utils/math.js";import{pxToUnitRounded as R,pxToUnitString as C}from"../utils/unit.js";import{flags as M}from"../utils/flags.js";import{isTouchDevice as O}from"../utils/screen.js";import{useColor as P}from"./use-color.js";import{isGradient as L}from"../utils/gradient.js";import{Html as T}from"react-konva-utils";const j=f.DD._drag;window.removeEventListener("mousemove",j),f.DD._drag=function(e){r(()=>{j.call(this,e)})},window.addEventListener("mousemove",f.DD._drag);const I=new f.Group,D=20;I.add(new f.Rect({width:D,height:D,fill:"white"})),I.add(new f.Path({scaleX:D/24,scaleY:D/24,data:"M4.98313549,11.0001422 C5.49589839,10.9914935 5.92501998,11.3703506 5.99116425,11.8666444 L5.99985778,11.9831355 L6.00348884,12.2068855 C6.11245031,15.4321748 8.76323537,17.9999971 11.9999971,17.9999971 C12.1869612,17.9999971 12.3726725,17.9914753 12.5567465,17.9745765 L12.2928932,17.7071068 C11.9023689,17.3165825 11.9023689,16.6834175 12.2928932,16.2928932 C12.6834175,15.9023689 13.3165825,15.9023689 13.7071068,16.2928932 L15.7071068,18.2928932 C16.0976311,18.6834175 16.0976311,19.3165825 15.7071068,19.7071068 L13.7071068,21.7071068 C13.3165825,22.0976311 12.6834175,22.0976311 12.2928932,21.7071068 C11.9023689,21.3165825 11.9023689,20.6834175 12.2928932,20.2928932 L12.6111505,19.9769552 C12.4086045,19.9922816 12.2047796,19.9999971 11.9999971,19.9999971 C7.7687005,19.9999971 4.28886152,16.7094374 4.01666425,12.5105203 L4.00420123,12.2575143 L4.00014222,12.0168645 C3.9908282,11.4646583 4.43092928,11.0094562 4.98313549,11.0001422 Z M11.7071068,2.29289322 C12.0675907,2.65337718 12.0953203,3.22060824 11.7902954,3.61289944 L11.7071068,3.70710678 L11.3891629,4.0230186 C11.5916051,4.00770767 11.7953244,4 12,4 C16.418278,4 20,7.581722 20,12 C20,12.5522847 19.5522847,13 19,13 C18.4477153,13 18,12.5522847 18,12 C18,8.6862915 15.3137085,6 12,6 C11.8129339,6 11.6271216,6.00853145 11.4429483,6.02544919 L11.7071068,6.29289322 C12.0976311,6.68341751 12.0976311,7.31658249 11.7071068,7.70710678 C11.3466228,8.06759074 10.7793918,8.09532028 10.3871006,7.79029539 L10.2928932,7.70710678 L8.29289322,5.70710678 C7.93240926,5.34662282 7.90467972,4.77939176 8.20970461,4.38710056 L8.29289322,4.29289322 L10.2928932,2.29289322 C10.6834175,1.90236893 11.3165825,1.90236893 11.7071068,2.29289322 Z",fill:"black"}));const W=I.toCanvas({pixelRatio:2,width:D,height:D});export const TRANSFORMER_STYLE={enabledAnchors:["top-left","top-center","top-right","middle-left","bottom-left","bottom-right","bottom-center","middle-right"],borderEnabled:!0,rotateEnabled:!0,rotationSnaps:[0,45,90,135,180,225,270,315],ignoreStroke:!0,flipEnabled:!1,anchorStrokeWidth:2,borderStrokeWidth:2,rotateAnchorOffset:30,anchorStyleFunc:e=>{if(e.hasName("rotater")){const t=20;e.setAttrs({width:t,height:t,cornerRadius:t/2,offsetX:t/2,offsetY:t/2,fillPatternImage:W,fillPatternScaleX:t/D/2,fillPatternScaleY:t/D/2,fillPriority:"pattern",fillPatternRepeat:"no-repeat"})}}};export const setTransformerStyle=e=>{Object.assign(TRANSFORMER_STYLE,e)};const F={text:{enabledAnchors:["top-left","top-right","middle-left","bottom-left","bottom-right","middle-right"]},svg:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},gif:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},line:{enabledAnchors:[],borderEnabled:!1,rotateEnabled:!1},image:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},many:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]},group:{enabledAnchors:["top-left","top-right","bottom-left","bottom-right"]}};export function registerTransformerAttrs(e,t){F[e]=F[e]||t,Object.assign(F[e],t)}const B=e=>t.createElement(m,Object.assign({},e,{preventDefault:!1})),_=n=>{var{url:i}=n,o=e(n,["url"]);const[r,l]=p(i,"anonymous"),s=r?Y(r,{width:o.width,height:o.height},"center-middle"):{};return w(l,i,"page background"),t.createElement(a,Object.assign({image:r},o,s))},G=e=>{const n=P({fill:e.fill,a:{width:e.width,height:e.height}});return t.createElement(m,Object.assign({},e,n))},N=n=>{const{background:i,scale:o,borderColor:r}=n,l=e(n,["background","scale","borderColor"]),a=t.useMemo(()=>!!f.Util.colorToRGBA(i)||L(i),[i]),s=t.useMemo(()=>{const e=document.createElement("canvas"),t=30;e.width=60,e.height=60;const n=e.getContext("2d");return n&&(n.fillStyle="black",n.fillRect(t,0,t,t),n.fillRect(0,t,t,t)),e},[]);return t.createElement(t.Fragment,null,t.createElement(m,Object.assign({fillPatternImage:s},l,{opacity:.1,hideInExport:!0})),a?t.createElement(G,Object.assign({fill:i},l)):t.createElement(_,Object.assign({url:i},l)))},V=n(({selection:e,fill:n="rgba(0, 161, 255, 0.3)",stroke:i="rgb(0, 161, 255)",strokeWidth:o=1})=>e.visible?t.createElement(m,{name:"selection",x:Math.min(e.x1,e.x2),y:Math.min(e.y1,e.y2),width:Math.abs(e.x1-e.x2),height:Math.abs(e.y1-e.y2),fill:n,stroke:i,strokeWidth:o}):null);function z(e){let t=180*e/Math.PI;return t%=360,t>180?t-=360:t<-180&&(t+=360),Math.round(t)}const H=n(({x:e,y:n,width:i,height:o,rotation:r,anchor:l,store:a,tagFill:c,textFill:d})=>{const m=k({x:e,y:n,width:i,height:o,rotation:f.Util.radToDeg(r)});if(void 0===l){return null}const h=(o/2+70)*Math.cos(r-Math.PI/2),x=(o/2+70)*Math.sin(r-Math.PI/2),p=R({unit:a.unit,dpi:a.dpi,px:i/a.scale,precious:"px"===a.unit?0:1})+" x "+R({unit:a.unit,dpi:a.dpi,px:o/a.scale,precious:"px"===a.unit?0:1})+("px"===a.unit?"":" "+a.unit);return t.createElement(t.Fragment,null,t.createElement(s,{x:(m.minX+m.maxX)/2+h,y:(m.minY+m.maxY)/2+x,offsetX:14,offsetY:14,visible:"rotater"===l},t.createElement(u,{cornerRadius:5,fill:c||"rgb(0, 161, 255)"}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:d||"white",padding:8,text:z(r).toString()+"°"})),t.createElement(s,{x:(m.minX+m.maxX)/2,y:m.maxY+20,visible:"rotater"!==l},t.createElement(u,{cornerRadius:5,fill:c||"rgb(0, 161, 255)",pointerDirection:"up",pointerHeight:0,pointerWidth:0}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:d||"white",padding:8,text:p})))}),Z=n(({elements:e,store:n})=>{const i=e.filter(e=>e.alwaysOnTop),o=e.filter(e=>!e.alwaysOnTop).concat(i);return t.createElement(t.Fragment,null,o.map(e=>t.createElement(b,{key:e.id,store:n,element:e,onClick:()=>{console.warn("Polotno warning: onClick callback is deprecated. Just stop using it. Polotno will do selection automatically.")}})))});export const useContextMenu=({store:e})=>{const[n,i]=t.useState(!1),[o,r]=t.useState({x:0,y:0}),l=t.useCallback(e=>{i(!0),r(e)},[]);return{open:l,close:t.useCallback(()=>{i(!1)},[]),props:{isOpen:n,offset:o,setIsOpen:i}}};let $=null;export const registerNextDomDrop=e=>{$=e};const K=atob("UG9sb3RubyBmcmVlIGxpY2Vuc2UgbGltaXRhdGlvbiBleGNlZWRlZCAtIFBsZWFzZSB1cGdyYWRlIHlvdXIgYWNjb3VudC4="),U=atob("cmVk"),J=atob("djAuOS4y"),q=e=>t.createElement(t.Fragment,null,t.createElement(s,{fill:U,height:200},t.createElement(u,{fill:U}),t.createElement(g,Object.assign({},e,{fill:"white",text:K,height:void 0,padding:10,fontSize:20}))));export default n(({store:e,page:n,width:r,height:a,pageControlsEnabled:p,backColor:b,pageBorderColor:w,activePageBorderColor:Y,components:R,bleedColor:P,altCloneEnabled:L,viewportSize:j,selectionRectFill:I,selectionRectStroke:D,selectionRectStrokeWidth:W,snapGuideStroke:_,snapGuideStrokeWidth:G,snapGuideDash:z,transformLabelFill:K,transformLabelTextFill:U,distanceGuideStroke:Q,distanceLabelFill:ee,distanceLabelTextFill:te,layout:ne="vertical",tooltipSafeArea:ie,transformerSafeArea:oe})=>{const re=e.bleedVisible?n.bleed:0,le=n.computedWidth+2*re,ae=n.computedHeight+2*re,se=(r-le*e.scale)/2,ce=(a-ae*e.scale)/2,de=t.useRef(null),me=t.useRef(null),he=t.useRef(null),ue=null==p||p,[ge,xe]=t.useState(null),[pe,fe]=t.useState({}),[be,ve]=t.useState(0),ye=useContextMenu({store:e}),Ee=e.selectedElements.find(e=>e._cropModeEnabled),we=e.selectedElements.find(e=>e.curveEnabled),Ye=e.selectedShapes.filter(e=>!e.resizable).length>0,Xe=e.selectedShapes.filter(e=>!e.draggable).length>0,Se=e.selectedElements.filter(e=>!e.visible).length>0;t.useLayoutEffect(()=>{var t,n,i;if(!de.current){return}const o=de.current.getStage(),r=e.selectedShapes.map(e=>e._cropModeEnabled?null:o.findOne("#"+e.id)).filter(e=>e),l=1===e.selectedElements.length,a=l&&(null===(t=e.selectedElements[0])||void 0===t?void 0:t.type)||"many";F[a]?(de.current.setAttrs(Object.assign(Object.assign({},TRANSFORMER_STYLE),F[a])),"svg"!==a&&"image"!==a&&"gif"!==a||e.selectedElements[0].keepRatio||de.current.setAttrs({enabledAnchors:TRANSFORMER_STYLE.enabledAnchors}),"text"===a&&M.textVerticalResizeEnabled&&de.current.setAttrs({enabledAnchors:null===(n=F.text.enabledAnchors)||void 0===n?void 0:n.concat(["bottom-center"])}),"text"===a&&l&&e.selectedElements[0].curveEnabled&&de.current.setAttrs({enabledAnchors:F.many.enabledAnchors})):de.current.setAttrs(TRANSFORMER_STYLE),Ye&&de.current.enabledAnchors([]),Xe&&de.current.rotateEnabled(!1),r.find(e=>null==e?void 0:e.isDragging())&&r.forEach(e=>{e.isDragging()||null==e||e.startDrag()}),de.current.nodes(r),y(),null===(i=de.current.getLayer())||void 0===i||i.batchDraw()},[e.selectedShapes,Ee,Ye,Se,Xe,we]);const ke=()=>{const e=de.current;if(!e){return}if(!e.isTransforming()){return void fe({})}if(!e.nodes().length||!e.isTransforming()){return}const t=e.__getNodeRect(),n=null==e?void 0:e.getActiveAnchor(),i=e.getStage();fe({anchor:n,x:t.x-i.x(),y:t.y-i.y(),rotation:t.rotation,width:t.width,height:t.height})},Ae=t.useCallback(()=>{var e;if(null===(e=de.current)||void 0===e?void 0:e.isTransforming()){return}const t=de.current;if(!t||!t.nodes().length){return void ve(0)}const n=t.getClientRect();if(!t.getStage()){return}const i=function(e,t,n,i=0){const o=e.x+e.width/2,r=e.y+e.height/2,l=e.width/2,a=e.height/2,s=i*Math.PI/180,c=e=>{const t=e*Math.PI/180,i=(e%360+360)%360;let c;c=0===i||180===i?a:l;const d=Math.sin(t)*(c+n),m=-Math.cos(t)*(c+n),h=d*Math.cos(s)-m*Math.sin(s),u=d*Math.sin(s)+m*Math.cos(s);return{x:o+h,y:r+u}},d=e=>e.x>=t.left&&e.x<=t.right&&e.y>=t.top&&e.y<=t.bottom;if(d(c(0))){return 0}for(const m of[180,270,90]){if(d(c(m))){return m}}return 0}(n,{top:(null==oe?void 0:oe.top)||0,bottom:a-((null==oe?void 0:oe.bottom)||0),left:(null==oe?void 0:oe.left)||0,right:r-((null==oe?void 0:oe.right)||0)},TRANSFORMER_STYLE.rotateAnchorOffset||30,t.rotation());ve(i)},[oe,r,a]);t.useEffect(()=>{var e;null===(e=de.current)||void 0===e||e.update(),ke(),Ae()},[e.scale,Ae]),t.useEffect(()=>{Ae()},[e.selectedShapes,Ae]);const Re=i(()=>({visible:!1,x1:0,y1:0,x2:0,y2:0})),Ce=t.useRef(!1),Me=O(),Oe=o(e=>{var t,n,i,o;if(Me){return}Ce.current=!1;const r=e.target.findAncestor(".elements-container"),l=e.target.findAncestor("Transformer"),a=e.target.findAncestor(".page-abs-container");if(r||l||a){return}const s=null===(t=e.target.getStage())||void 0===t?void 0:t.getPointerPosition();s.x-=null===(n=e.target.getStage())||void 0===n?void 0:n.x(),s.y-=null===(i=e.target.getStage())||void 0===i?void 0:i.y(),s&&(Re.visible=!0,Re.x1=s.x,Re.y1=s.y,Re.x2=s.x,Re.y2=s.y,(null===(o=e.target.getStage())||void 0===o?void 0:o.getPointersPositions().length)>=2&&(Re.visible=!1))});(({stageRef:e,containerRef:n,viewportSize:i})=>{t.useEffect(()=>{var t;const i=null===(t=n.current)||void 0===t?void 0:t.closest(".polotno-workspace-inner");function o(){var t;if(!e.current){return}const o=null===(t=n.current)||void 0===t?void 0:t.getBoundingClientRect(),r=null==i?void 0:i.getBoundingClientRect(),l=Math.max(0,r.left-o.left-100),a=Math.max(0,r.top-o.top-100);e.current.position({x:-l,y:-a}),e.current.container().style.transform=`translate(${l}px, ${a}px)`}return o(),i.addEventListener("scroll",o),()=>{i.removeEventListener("scroll",o)}},[i.width,i.height])})({stageRef:me,containerRef:he,viewportSize:j}),t.useEffect(()=>{const t=o(e=>{var t,n,i,o;if(!Re.visible){return}console.log("continueSelection"),null===(t=me.current)||void 0===t||t.setPointersPositions(e);let r=null===(n=me.current)||void 0===n?void 0:n.getPointerPosition();r?(r.x-=null===(i=me.current)||void 0===i?void 0:i.x(),r.y-=null===(o=me.current)||void 0===o?void 0:o.y()):r={x:Re.x2,y:Re.y2},Re.x2=r.x,Re.y2=r.y}),n=o(()=>{if(!Re.visible){return}if(!me.current){return}const t=me.current.findOne(".selection"),n=t?t.getClientRect({skipStroke:!0}):{width:0,height:0,x:0,y:0};if(n.width&&n.height){const t=[];me.current.find(".element").forEach(i=>{const o=i.getClientRect(),r=e.getElementById(i.id()),l=null==r?void 0:r.draggable,a=null==r?void 0:r.selectable;f.Util.haveIntersection(n,o)&&l&&a&&t.push(r.top.id)});const i=[...new Set(t)];Ce.current=!0,e.selectElements(i)}Re.visible=!1});return window.addEventListener("mousemove",t),window.addEventListener("touchmove",t),window.addEventListener("mouseup",n,{capture:!0}),window.addEventListener("touchend",n,{capture:!0}),()=>{window.removeEventListener("mousemove",t),window.removeEventListener("touchmove",t),window.removeEventListener("mouseup",n),window.removeEventListener("touchend",n)}},[]);const Pe=t.useCallback(t=>{if(!e.selectedElements[0]){return}if(t&&e.selectedElementsIds.includes(t)){return}const i=A(e.selectedShapes),o=t?e.getElementById(t):{x:0,y:0,width:n.computedWidth,height:n.computedHeight,rotation:0},r=k(o),l=[];i.minX>r.maxX&&l.push({distance:i.minX-r.maxX,box1:i,box2:r,points:[{x:i.minX,y:i.minY+i.height/2},{x:r.maxX,y:i.minY+i.height/2},{x:r.maxX,y:r.minY+r.height/2}]}),i.maxX<r.minX&&l.push({distance:r.minX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:i.minY+i.height/2},{x:r.minX,y:i.minY+i.height/2},{x:r.minX,y:r.minY+r.height/2}]}),i.minY>r.maxY&&l.push({box1:i,box2:r,distance:i.minY-r.maxY,points:[{x:i.minX+i.width/2,y:i.minY},{x:i.minX+i.width/2,y:r.maxY},{x:r.minX+r.width/2,y:r.maxY}]}),i.maxY<r.minY&&l.push({box1:i,box2:r,distance:r.minY-i.maxY,points:[{x:i.minX+i.width/2,y:i.maxY},{x:i.minX+i.width/2,y:r.minY},{x:r.minX+r.width/2,y:r.minY}]});const a=i.minX>=r.minX&&i.maxX<=r.maxX&&i.minY>=r.minY&&i.maxY<=r.maxY;if(a&&(l.push({distance:i.minX-r.minX,box1:i,box2:r,points:[{x:i.minX,y:i.minY+i.height/2},{x:r.minX,y:i.minY+i.height/2},{x:r.minX,y:r.minY+r.height/2}]}),l.push({distance:r.maxX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:i.minY+i.height/2},{x:r.maxX,y:i.minY+i.height/2},{x:r.maxX,y:r.minY+r.height/2}]}),l.push({box1:i,box2:r,distance:i.minY-r.minY,points:[{x:i.minX+i.width/2,y:i.minY},{x:i.minX+i.width/2,y:r.minY},{x:r.minX+r.width/2,y:r.minY}]}),l.push({box1:i,box2:r,distance:r.maxY-i.maxY,points:[{x:i.minX+i.width/2,y:i.maxY},{x:i.minX+i.width/2,y:r.maxY},{x:r.minX+r.width/2,y:r.maxY}]})),0===l.length&&!a){const e=i.minX<r.maxX&&i.maxX>r.minX,t=i.minY<r.maxY&&i.maxY>r.minY;if(e&&t){const e=(Math.max(i.minY,r.minY)+Math.min(i.maxY,r.maxY))/2,t=(Math.max(i.minX,r.minX)+Math.min(i.maxX,r.maxX))/2;i.minX<r.minX?l.push({distance:r.minX-i.minX,box1:i,box2:r,points:[{x:i.minX,y:e},{x:r.minX,y:e},{x:r.minX,y:e}]}):l.push({distance:i.minX-r.minX,box1:i,box2:r,points:[{x:i.minX,y:e},{x:r.minX,y:e},{x:r.minX,y:e}]}),i.maxX>r.maxX?l.push({distance:i.maxX-r.maxX,box1:i,box2:r,points:[{x:r.maxX,y:e},{x:i.maxX,y:e},{x:r.maxX,y:e}]}):l.push({distance:r.maxX-i.maxX,box1:i,box2:r,points:[{x:i.maxX,y:e},{x:r.maxX,y:e},{x:r.maxX,y:e}]}),i.minY<r.minY?l.push({box1:i,box2:r,distance:r.minY-i.minY,points:[{x:t,y:i.minY},{x:t,y:r.minY},{x:t,y:r.minY}]}):l.push({box1:i,box2:r,distance:i.minY-r.minY,points:[{x:t,y:i.minY},{x:t,y:r.minY},{x:t,y:r.minY}]}),i.maxY>r.maxY?l.push({box1:i,box2:r,distance:i.maxY-r.maxY,points:[{x:t,y:r.maxY},{x:t,y:i.maxY},{x:t,y:r.maxY}]}):l.push({box1:i,box2:r,distance:r.maxY-i.maxY,points:[{x:t,y:i.maxY},{x:t,y:r.maxY},{x:t,y:r.maxY}]})}}JSON.stringify(ge)!==JSON.stringify(l)&&xe(l)},[e,n]);t.useEffect(()=>{e.distanceGuidesVisible?Pe():ge&&xe(null)},[e.distanceGuidesVisible,Pe,e.selectedShapes.map(e=>`${e.x},${e.y},${e.width},${e.height},${e.rotation}`).join("|")]);const Le=t.useRef(!1);t.useEffect(()=>{var e;let t;const n=null===(e=he.current)||void 0===e?void 0:e.closest(".polotno-workspace-inner"),i=()=>{Le.current=!0,clearTimeout(t),t=setTimeout(()=>{Le.current=!1},300)};return n.addEventListener("scroll",i),()=>{clearTimeout(t),n.removeEventListener("scroll",i)}},[]);const Te=t=>{if(e.activePage!==n&&n.select(),Le.current){return}if(Ce.current){return}const i=t.evt.ctrlKey||t.evt.metaKey||t.evt.shiftKey,o=t.target.findAncestor(".elements-container"),r=t.target.findAncestor(".page-abs-container"),l=t.target.findAncestor("Transformer");if(!(i||o||l||r||Re.visible)){return void e.selectElements([])}const a=t.target.findAncestor(".element-container",!0),s=(null==a?void 0:a.findOne(".element"))||t.target.findAncestor(".element",!0),c=e.getElementById(null==s?void 0:s.id()),d=null==c?void 0:c.top,m=null==d?void 0:d.id,h=e.selectedElementsIds.indexOf(m)>=0,u=t.target.findAncestor(".page-container",!0);m&&i&&!h?e.selectElements(e.selectedElementsIds.concat([m])):m&&i&&h?e.selectElements(e.selectedElementsIds.filter(e=>e!==m)):!m||i||h?u?e.selectPages([n.id]):e.selectPages([]):e.selectElements([m])};E(de,e,{stroke:_,strokeWidth:G,dash:z});const je=e.activePage===n,Ie=e._selectedPagesIds.includes(n.id),De=null==R?void 0:R.PageControls,We=null==R?void 0:R.Tooltip,Fe=null==R?void 0:R.ContextMenu,Be=1/e.scale,_e=0/e.scale;return t.createElement("div",{ref:he,onDragOver:e=>e.preventDefault(),onDrop:t=>{if(t.preventDefault(),!me.current){return}me.current.setPointersPositions(t);const i=me.current.findOne(".elements-container").getRelativePointerPosition(),o=me.current.getPointerPosition(),r=me.current.getAllIntersections(o).map(e=>e.findAncestor(".element",!0)).filter(Boolean),l=[...new Set(r.reverse())].map(t=>e.getElementById(t.id())),a=l[0];$&&($(i,a,{elements:l,page:n}),$=null)},style:{position:"relative",width:r+"px",height:a+"px",overflow:"hidden",flexShrink:0},className:"polotno-page-container"+(je?" active-page":"")},t.createElement(h,{ref:me,width:Math.min(r,j.width+200),height:Math.min(j.height+200,a),onClick:Te,onTap:Te,onContextMenu:t=>{t.evt.preventDefault();const n=t.target.findAncestor(".element",!0),i=e.getElementById(null==n?void 0:n.id()),o=null==i?void 0:i.top,r=null==o?void 0:o.id;r?e.selectedElementsIds.indexOf(r)>=0||e.selectElements([r]):e.selectElements([]),ye.open({x:t.evt.clientX,y:t.evt.clientY})},onMouseDown:Oe,onMouseMove:t=>{if(!e.distanceGuidesVisible&&!t.evt.altKey){return void(ge&&xe(null))}const n=t.target.findAncestor(".element",!0),i=null==n?void 0:n.id();Pe(i)},onDragStart:t=>{var n;const i=t.target.findAncestor(".element",!0);if(i){const o=e.getElementById(null==i?void 0:i.id()),r=null==o?void 0:o.top,l=null==r?void 0:r.id;!(e.selectedElementsIds.indexOf(l)>=0)&&l&&(e.selectElements([l]),t.target.stopDrag(),t.target.startDrag(t),null===(n=de.current)||void 0===n||n.startDrag(t))}ge&&xe(null)},pageId:n.id,style:{position:"absolute",overflow:"hidden",top:0,left:0}},t.createElement(c,null,t.createElement(B,{width:r,height:a,fill:b}),t.createElement(l,{x:se,y:ce,scaleX:e.scale,scaleY:e.scale,name:"page-container"},t.createElement(l,{name:"page-container-2"},t.createElement(l,{name:"page-background-group",x:re,y:re},t.createElement(N,{x:-n.bleed,y:-n.bleed,width:n.computedWidth+2*n.bleed,height:n.computedHeight+2*n.bleed,background:n.background,name:"page-background",preventDefault:!1,scale:e.scale})),t.createElement(l,{x:re,y:re,name:"elements-container",listening:!e.isPlaying},t.createElement(m,{name:"elements-area",width:n.computedWidth,height:n.computedHeight,listening:!1}),t.createElement(Z,{elements:n.children,store:e})),t.createElement(m,{stroke:P,name:"bleed",strokeWidth:n.bleed,x:n.bleed/2,y:n.bleed/2,width:n.computedWidth+n.bleed,height:n.computedHeight+n.bleed,listening:!1,visible:n.bleed>0&&e.bleedVisible,hideInExport:!0}),X()===J&&t.createElement(q,{name:"hit-detection",x:-Be/2-_e,y:-Be/2-_e,width:le+Be+2*_e,height:ae+Be+2*_e}))),t.createElement(d,{name:"workspace-background",points:[0,0,r,0,r,a,0,a,0,0,se,ce,se,a-ce,r-se,a-ce,r-se,ce,se,ce],listening:!1,closed:!0,fill:b}),t.createElement(l,{x:se,y:ce,scaleX:e.scale,scaleY:e.scale},t.createElement(m,{name:"page-highlight",hideInExport:!0,x:-Be/2-_e,y:-Be/2-_e,width:le+Be+2*_e,height:ae+Be+2*_e,stroke:Ie?Y:w,strokeWidth:2,listening:!1,strokeScaleEnabled:!1})),t.createElement(l,{x:se+re*e.scale,y:ce+re*e.scale,scaleX:e.scale,scaleY:e.scale,name:"page-abs-container"},t.createElement(x,{ref:de,rotateAnchorAngle:be,onDragStart:t=>{var i;(null===(i=t.evt)||void 0===i?void 0:i.altKey)&&L&&e.selectedElements.forEach(e=>{const t=e.clone({},{skipSelect:!0}),i=n.children.indexOf(e);n.setElementZIndex(t.id,i)}),e.history.startTransaction()},onDragEnd:()=>{e.history.endTransaction(),Ae()},onTransformStart:()=>{e.history.startTransaction(),xe(null)},boundBoxFunc:(e,t)=>{const n=Math.abs(t.width)<1||Math.abs(t.height)<1,i=Math.abs(e.width)<1||Math.abs(e.height)<1;return n&&!i?e:t},onTransform:e=>{const t=de.current.nodes(),n=t[t.length-1];e.target===n&&setTimeout(()=>{ke()},0)},onTransformEnd:t=>{fe({}),e.history.endTransaction(),Ae()},visible:!e.isPlaying}),ge&&ge.map(({points:n,distance:i,box1:o,box2:r},a)=>t.createElement(l,{name:"distances-container",hideInExport:!0,key:a,listening:!1},t.createElement(m,Object.assign({},o,{stroke:Q,strokeWidth:1,strokeScaleEnabled:!1})),t.createElement(m,Object.assign({},r,{stroke:Q,strokeWidth:1,strokeScaleEnabled:!1})),t.createElement(d,{points:[n[0].x,n[0].y,n[1].x,n[1].y],stroke:Q,strokeWidth:1,strokeScaleEnabled:!1}),t.createElement(d,{points:[n[1].x,n[1].y,n[2].x,n[2].y],stroke:Q,strokeWidth:1,strokeScaleEnabled:!1}),t.createElement(s,{x:(n[0].x+n[1].x)/2,y:(n[0].y+n[1].y)/2,offsetY:-10,scaleX:1/e.scale,scaleY:1/e.scale},t.createElement(u,{cornerRadius:5,fill:ee,pointerDirection:"down"}),t.createElement(g,{align:"center",verticalAlign:"middle",fill:te,padding:5,text:C({unit:e.unit,dpi:e.dpi,px:i})})))),n._rendering&&t.createElement(l,null,t.createElement(m,{width:le,height:ae,fill:"rgba(255,255,255,0.9)"}),t.createElement(g,{text:"Rendering...",fontSize:60,width:le,height:ae,align:"center",verticalAlign:"middle"})),We&&t.createElement(We,{components:R,store:e,page:n,stageRef:me,tooltipSafeArea:ie}),Fe&&t.createElement(T,null,t.createElement(Fe,Object.assign({components:R,store:e},ye.props)))),t.createElement(v,{store:e,page:n,width:r,height:a,scale:e.scale,xPadding:se,yPadding:ce,bleed:re}),t.createElement(H,Object.assign({},pe,{store:e,tagFill:K,textFill:U})),t.createElement(V,{selection:Re,fill:I,stroke:D,strokeWidth:W}),S()&&t.createElement(g,{text:"Powered by polotno.com",fontSize:14,fill:"rgba(0,0,0,0.6)",x:r-170,y:a-18,onMouseEnter:e=>{e.target.getStage().container().style.cursor="pointer"},onMouseLeave:e=>{e.target.getStage().container().style.cursor=""},onTouchStart:e=>{e.cancelBubble=!0},onMouseDown:e=>{e.cancelBubble=!0},onClick:()=>{window.open("https://polotno.com")},onTap:()=>{window.open("https://polotno.com")}}),t.createElement(l,{name:"line-guides"}))),ue&&De&&t.createElement(De,{store:e,page:n,xPadding:se,yPadding:ce,layout:ne}))});
|
package/canvas/text-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"react";import{observer as e}from"mobx-react-lite";import{Group as n,Path as o,Text as r,TextPath as i}from"react-konva";import{Html as a}from"react-konva-utils";import{autorun as l}from"mobx";import s from"konva";import{parsePath as d,roundCommands as c}from"svg-round-corners";import{useColor as h}from"./use-color.js";import{incrementLoader as u}from"../utils/loader.js";import{isFontLoaded as f}from"../utils/fonts.js";import{flags as g}from"../utils/flags.js";import{removeTags as m}from"../utils/text.js";import{getDir as w,getCurvePath as x,resolveLineHeight as p}from"../utils/text-html.js";import{applyFilter as v}from"./apply-filters.js";import{useFadeIn as y}from"./use-fadein.js";import{isTouchDevice as S}from"../utils/screen.js";import{isAlive as E}from"mobx-state-tree";import{getLimitedFontSize as b}from"./text-element/max-font-size.js";import{getOptimalCaretColor as z}from"./text-element/caret-color.js";let O;function k(){return O||(O=document.getElementById("polotno-text-style"),O||(O=document.createElement("style"),O.id="polotno-text-style",document.head.appendChild(O)),O)}s._fixTextRendering=!0;const A={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};export{getDir}from"../utils/text-html.js";const L=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(A),s=e.current;t.useLayoutEffect(()=>{const t={};t.width=s.width()-2*s.padding()+"px",t.height=s.height()-2*s.padding()+s.fontSize()*s.lineHeight()+"px",t.fontSize=s.fontSize()+"px",t.lineHeight=s.lineHeight()+.01,t.fontFamily=s.fontFamily(),t.textAlign=s.align(),t.color=s.fill(),t.fontWeight=n.fontWeight,t.fontStyle=n.fontStyle,t.letterSpacing=n.letterSpacing+"em",t.opacity=Math.max(n.a.opacity,.2),t.textTransform=n.textTransform,t.caretColor=z(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=k();o.innerHTML="",o.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(a)&&l(t)});const d=t.useRef(null);if(t.useLayoutEffect(()=>{var t;const e=d.current;if(!e){return}null===(t=d.current)||void 0===t||t.focus();const n=i||e.value.length;e.selectionStart=e.selectionEnd=n,r&&(null==e||e.select(),document.execCommand("selectAll",!1,null))},[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=d.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]),!s){return null}let c=0;const h=s.textArr.length*s.lineHeight()*s.fontSize();"middle"===n.verticalAlign&&(c=(n.a.height-h)/2),"bottom"===n.verticalAlign&&(c=n.a.height-h);const u=m(n.text);return t.createElement("textarea",{className:"polotno-input",ref:d,dir:w(u),style:Object.assign(Object.assign(Object.assign({},A),a),{paddingTop:c+"px"}),value:u,onChange:t=>{const e=b({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),$=e=>t.createElement(a,null,t.createElement(L,Object.assign({},e)));export const useFontLoader=(e,n)=>{const[o,r]=t.useReducer(t=>t+1,0),i=t.useRef(f(n)),a=t.useRef(null);return t.useLayoutEffect(()=>{if(i.current=f(n),i.current){return}let t=!0;return(async()=>{i.current=!1,r();const o=u(`text ${n}`);await e.loadFont(n),t?(a.current=o,i.current=!0,r()):o()})(),()=>{a.current&&(a.current(),a.current=null),t=!1}},[n]),t.useEffect(()=>{i.current&&setTimeout(()=>{a.current&&(a.current(),a.current=null)})},[i.current]),[i.current]};export const getLineHeight=({fontLoaded:e,fontFamily:n,fontSize:o,lineHeight:r})=>t.useMemo(()=>p({fontFamily:n,fontSize:o,lineHeight:r}),[e,n,o,r]);export function usePrevious(e){const n=t.useRef(e),o=t.useRef(e);return t.useMemo(()=>{o.current=n.current,n.current=e},[e]),o.current}export{getCurvePath}from"../utils/text-html.js";export const TextElement=e(({element:e,store:a})=>{const s=t.useRef(null),f=t.useRef(null),p=t.useRef(null),{editorEnabled:b,selectAll:z}=(e=>{const[n,o]=t.useState(!1),r=t.useRef(!1);return t.useEffect(()=>{var t=!0;return setTimeout(()=>{t&&(e._editModeEnabled&&(r.current=!0),o(!0),setTimeout(()=>{r.current=!1},50))},50),()=>{t=!1}},[]),{editorEnabled:n&&e._editModeEnabled,selectAll:r.current}})(e),[O,k]=t.useState(!1),A=t.useRef(e.a.height),L=a.selectedShapes.indexOf(e)>=0&&e.selectable,F=usePrevious(L),{textVerticalResizeEnabled:M}=g,R=g.autoDeleteEmptyText,j=usePrevious(e.fontFamily),[T,C]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=s.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(T)&&C(n)}),t.useEffect(()=>{if(e.a.width){return}const t=s.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{F&&!L&&R&&""===e.text&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[R,e.placeholder,e.removable,e.text,L,F]),t.useLayoutEffect(()=>l(()=>{const t=s.current;v(t,e)}));const[H]=useFontLoader(a,e.fontFamily);let P=m(e.text);"uppercase"===e.textTransform&&(P=P.toUpperCase());const W=()=>{if(e.curveEnabled){const t=f.current;return t.getSelfRect().height||t.fontSize()}const t=s.current.clone({height:void 0}),n=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),n};t.useLayoutEffect(()=>{if(!H){return}const{textOverflow:t,textSplitAllowed:n}=g,o=(t,...n)=>{const o=u(`text ${e.id} before ignore`);a.history.ignore(t,...n).then(()=>{o()})};if(!e.a.height){const t=W();return void o(()=>{e.set({height:t})})}if(!a.isPlaying){if("change-font-size"!==t||O){if("resize"===t){const t=W();M&&e.a.height<t&&!O&&o(()=>{var n;E(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0),M||e.a.height===t||O||o(()=>{var n;E(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0)}}else{const t=function(t,e,n=!1){const o=t.fontSize(),r=t.height(),i=m(e.text);let a=e.a.fontSize;t.height(void 0);const l=Math.round(2*e.a.fontSize)-1;for(let s=1;s<l;s++){const o=e.a.height&&t.height()>e.a.height;let r=i.split("\n").join(" ").split(/[\s-]+/).reduce((t,e)=>(e=e.toLowerCase(),/[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFFEF\u4E00-\u9FAF\uAC00-\uD7AF]/.test(e)?t.concat(e.split("")):t.concat(e)),[]),l=t.textArr.map(t=>t.text.toLowerCase()).join(";");const s=r.find(t=>!l.includes(t)||(l=l.replace(t,""),!1));if(!(o||s&&!n)){break}a-=.5,t.fontSize(a)}return t.fontSize(o),t.height(r),a}(s.current,e,n);if(t!==e.a.fontSize){return void o(()=>{e.set({fontSize:t})},!1,!0)}const r=W();e.a.height===r||M||o(()=>{e.set({height:r})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(H&&e.curveEnabled){const n=null===(t=f.current)||void 0===t?void 0:t.getSelfRect().width;if(n){const t=n-e.a.width,o=e.a.rotation*Math.PI/180,r=-t/2*Math.cos(o),i=-t/2*Math.sin(o);e.set({width:n,x:e.a.x+r,y:e.a.y+i})}}},[H,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useLayoutEffect(()=>{const t=s.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),v(t,e))},[H]);const X=t.useRef(null),Y=t.useRef(0),B=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(Y.current=function(t){var e;const n=t.target,o=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var n=t.getStage().getPointerPosition();return e.point(n)}(n),r=n.textArr,i=Math.floor(o.y/(n.fontSize()*n.lineHeight())),a=r.slice(0,i).reduce((t,e)=>t+e.text.length,i),l=null!==(e=r[i])&&void 0!==e?e:r[0];let s=0;return"right"===n.align()?s=n.width()-l.width:"center"===n.align()&&(s=n.width()/2-l.width/2),a+Math.round((o.x-s)/l.width*l.text.length)}(t),e.toggleEditMode())},D=!P&&e.placeholder?.6:e.a.opacity;y(s,D);const N=getLineHeight({fontLoaded:H,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),I=e.selectable||"admin"===a.role,J=h(e),_=h(e,e.stroke,"stroke"),V=t.useMemo(()=>e.backgroundEnabled?e.curveEnabled?function({width:t,height:e,padding:n=0,cornerRadius:o=0}){const r=-n,i=-n,a=t+n,l=e+n,s=d(`M ${r} ${i} L ${a} ${i} L ${a} ${l} L ${r} ${l} Z`);return c(s,o).path}({width:e.a.width,height:e.a.height,cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*N*.5),padding:e.backgroundPadding*(e.a.fontSize*N*.5)}):function({lines:t,lineHeight:e,width:n,align:o="left",padding:r=0,cornerRadius:i=0}){var a;t.forEach((t,e)=>{t.cx=n/2,"right"===o?t.cx=n-t.width/2:"left"===o&&(t.cx=t.width/2),"justify"!==o||t.lastInParagraph||(t.width=n),"justify"===o&&(t.cx=t.width/2)});let l=`M ${null===(a=t[0])||void 0===a?void 0:a.cx} ${-r}`;t.forEach((n,o)=>{const{cx:i}=n,a=t[o-1];a&&a.width>n.width?l+=` L ${i+n.width/2+r} ${o*e+r}`:l+=` L ${i+n.width/2+r} ${o*e-r}`;const s=t[o+1];s&&s.width>n.width?l+=` L ${i+n.width/2+r} ${(o+1)*e-r}`:l+=` L ${i+n.width/2+r} ${(o+1)*e+r}`});for(var s=t.length-1;s>=0;s--){const n=t[s],{cx:o}=n,i=t[s+1];i&&i.width>n.width?l+=` L ${o-n.width/2-r} ${(s+1)*e-r}`:l+=` L ${o-n.width/2-r} ${(s+1)*e+r}`;const a=t[s-1];a&&a.width>n.width?l+=` L ${o-n.width/2-r} ${s*e+r}`:l+=` L ${o-n.width/2-r} ${s*e-r}`}l+=" Z";const h=d(l);return c(h,i).path}({lines:JSON.parse(JSON.stringify(T)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*N*.5),lineHeight:N*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*N*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.curveEnabled,e.backgroundCornerRadius,e.a.fontSize,e.a.height,N,e.backgroundPadding,e.a.width,e.align,T]),Z=S();let U=0;e.curveEnabled||("middle"===e.verticalAlign?U=(e.a.height-T.length*N*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(U=e.a.height-T.length*N*e.a.fontSize));const q=e.curveEnabled?x(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",G=H?'"'+e.fontFamily+'"':j===e.fontFamily?"Arial":'"'+j+'"';return t.createElement(t.Fragment,null,t.createElement(o,{ref:p,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*D,data:V,fill:e.backgroundColor,offsetY:-U}),t.createElement(o,{data:q,stroke:"red",strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:f,visible:e.curveEnabled,data:q,text:P||e.placeholder,listening:!1,align:"center",textBaseline:"middle"},J,_,{strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${j}"`,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration.trim(),letterSpacing:e.letterSpacing*e.a.fontSize,x:e.a.x,y:e.a.y,rotation:e.a.rotation,opacity:e._editModeEnabled?.3:D,hideInExport:!e.showInExport,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity})),t.createElement(r,Object.assign({ref:s,id:e.id,name:"element",hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled,x:e.a.x,y:e.a.y,rotation:e.a.rotation,width:e.a.width,height:e.a.height,text:P||e.placeholder,direction:w(P)},J,_,{lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:G,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:Z?e.draggable&&L:e.draggable,preventDefault:!Z||L,opacity:e.curveEnabled?0:D,visible:!e._editModeEnabled,ellipsis:"ellipsis"===g.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:N,letterSpacing:e.letterSpacing*e.a.fontSize,listening:I,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},onClick:B,onTap:B,onTransformStart:()=>{k(!0),A.current=s.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=p.current)||void 0===n||n.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(o=i.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),n=i.width()*t,o=e.a.fontSize;let r=n;n<o&&(r=o,X.current&&i.position(X.current)),i.width(r),i.scaleX(1),i.scaleY(1);const a=W();if("ellipsis"!==g.textOverflow){const t=Math.max(a,A.current);i.height(t),e.set({height:i.height()})}const l=g.textVerticalResizeEnabled?Math.max(a,A.current):W();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),v(i,e)}if("top-center"===a||"bottom-center"===a){let n="resize"===g.textOverflow?W():N*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}X.current=t.target.position();const l=t.target.scaleX();null===(r=p.current)||void 0===r||r.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.a.fontSize*l,width:t.target.width()*l,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*l,shadowBlur:e.shadowBlur*l,shadowOffsetX:e.shadowOffsetX*l,shadowOffsetY:e.shadowOffsetY*l,strokeWidth:e.strokeWidth*l})},onTransformEnd:t=>{var n;const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:Math.round(e.a.fontSize*o),width:Math.ceil(t.target.width()*o),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*o,shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o}),null===(n=p.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),k(!1)}})),b&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement($,{textNodeRef:s,element:e,selectAll:z,cursorPosition:Y.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
|
|
1
|
+
import t from"react";import{observer as e}from"mobx-react-lite";import{Group as n,Path as o,Text as r,TextPath as i}from"react-konva";import{Html as a}from"react-konva-utils";import{autorun as l}from"mobx";import s from"konva";import{parsePath as d,roundCommands as c}from"svg-round-corners";import{useColor as h}from"./use-color.js";import{incrementLoader as u}from"../utils/loader.js";import{isFontLoaded as f}from"../utils/fonts.js";import{flags as g}from"../utils/flags.js";import{removeTags as m}from"../utils/text.js";import{getDir as w,getCurvePath as x,resolveLineHeight as p}from"../utils/text-html.js";import{applyFilter as v}from"./apply-filters.js";import{useFadeIn as y}from"./use-fadein.js";import{isTouchDevice as S}from"../utils/screen.js";import{isAlive as E}from"mobx-state-tree";import{getLimitedFontSize as b}from"./text-element/max-font-size.js";import{getOptimalCaretColor as z}from"./text-element/caret-color.js";let O;function k(){return O||(O=document.getElementById("polotno-text-style"),O||(O=document.createElement("style"),O.id="polotno-text-style",document.head.appendChild(O)),O)}s._fixTextRendering=!0;const A={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};export{getDir}from"../utils/text-html.js";const L=e(({textNodeRef:e,element:n,onBlur:o,selectAll:r,cursorPosition:i})=>{const[a,l]=t.useState(A),s=e.current;t.useLayoutEffect(()=>{const t={};t.width=s.width()-2*s.padding()+"px",t.height=s.height()-2*s.padding()+s.fontSize()*s.lineHeight()+"px",t.fontSize=s.fontSize()+"px",t.lineHeight=s.lineHeight()+.01,t.fontFamily=s.fontFamily(),t.textAlign=s.align(),t.color=s.fill(),t.fontWeight=n.fontWeight,t.fontStyle=n.fontStyle,t.letterSpacing=n.letterSpacing+"em",t.opacity=Math.max(n.a.opacity,.2),t.textTransform=n.textTransform,t.caretColor=z(n);const e=`\n .polotno-input::placeholder {\n color: ${a.color};\n opacity: 0.6;\n }\n `,o=k();o.innerHTML="",o.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(a)&&l(t)});const d=t.useRef(null);if(t.useLayoutEffect(()=>{var t;const e=d.current;if(!e){return}null===(t=d.current)||void 0===t||t.focus();const n=i||e.value.length;e.selectionStart=e.selectionEnd=n,r&&(null==e||e.select(),document.execCommand("selectAll",!1,null))},[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=d.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]),!s){return null}let c=0;const h=s.textArr.length*s.lineHeight()*s.fontSize();"middle"===n.verticalAlign&&(c=(n.a.height-h)/2),"bottom"===n.verticalAlign&&(c=n.a.height-h);const u=m(n.text);return t.createElement("textarea",{className:"polotno-input",ref:d,dir:w(u),style:Object.assign(Object.assign(Object.assign({},A),a),{paddingTop:c+"px"}),value:u,onChange:t=>{const e=b({oldText:n.text,newText:t.target.value,element:n});n.set({text:t.target.value,fontSize:e})},placeholder:n.placeholder,onBlur:o})}),$=e=>t.createElement(a,null,t.createElement(L,Object.assign({},e)));export const useFontLoader=(e,n)=>{const[o,r]=t.useReducer(t=>t+1,0),i=t.useRef(f(n)),a=t.useRef(null);return t.useLayoutEffect(()=>{if(i.current=f(n),i.current){return}let t=!0;return(async()=>{i.current=!1,r();const o=u(`text ${n}`);await e.loadFont(n),t?(a.current=o,i.current=!0,r()):o()})(),()=>{a.current&&(a.current(),a.current=null),t=!1}},[n]),t.useEffect(()=>{i.current&&setTimeout(()=>{a.current&&(a.current(),a.current=null)})},[i.current]),[i.current]};export const getLineHeight=({fontLoaded:e,fontFamily:n,fontSize:o,lineHeight:r})=>t.useMemo(()=>p({fontFamily:n,fontSize:o,lineHeight:r}),[e,n,o,r]);export function usePrevious(e){const n=t.useRef(e),o=t.useRef(e);return t.useMemo(()=>{o.current=n.current,n.current=e},[e]),o.current}export{getCurvePath}from"../utils/text-html.js";export const TextElement=e(({element:e,store:a})=>{const s=t.useRef(null),f=t.useRef(null),p=t.useRef(null),{editorEnabled:b,selectAll:z}=(e=>{const[n,o]=t.useState(!1),r=t.useRef(!1);return t.useEffect(()=>{var t=!0;return setTimeout(()=>{t&&(e._editModeEnabled&&(r.current=!0),o(!0),setTimeout(()=>{r.current=!1},50))},50),()=>{t=!1}},[]),{editorEnabled:n&&e._editModeEnabled,selectAll:r.current}})(e),[O,k]=t.useState(!1),A=t.useRef(e.a.height),L=a.selectedShapes.indexOf(e)>=0&&e.selectable,F=usePrevious(L),{textVerticalResizeEnabled:M}=g,R=g.autoDeleteEmptyText,j=usePrevious(e.fontFamily),[T,C]=t.useState([]);t.useEffect(()=>{var t,e;const n=null!==(e=null===(t=s.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(n)!==JSON.stringify(T)&&C(n)}),t.useEffect(()=>{if(e.a.width){return}const t=s.current;t.width(600),e.set({width:1.4*t.getTextWidth()})},[]),t.useEffect(()=>{F&&!L&&R&&""===e.text&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[R,e.placeholder,e.removable,e.text,L,F]),t.useLayoutEffect(()=>l(()=>{const t=s.current;v(t,e)}));const[H]=useFontLoader(a,e.fontFamily);let P=m(e.text);"uppercase"===e.textTransform&&(P=P.toUpperCase());const W=()=>{if(e.curveEnabled){const t=f.current;return t.getSelfRect().height||t.fontSize()}const t=s.current.clone({height:void 0}),n=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),n};t.useLayoutEffect(()=>{if(!H){return}const{textOverflow:t,textSplitAllowed:n}=g,o=(t,...n)=>{const o=u(`text ${e.id} before ignore`);a.history.ignore(t,...n).then(()=>{o()})};if(!e.a.height){const t=W();return void o(()=>{e.set({height:t})})}if(!a.isPlaying){if("change-font-size"!==t||O){if("resize"===t){const t=W();M&&e.a.height<t&&!O&&o(()=>{var n;E(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0),M||e.a.height===t||O||o(()=>{var n;E(e)&&e.set({height:t}),null===(n=s.current)||void 0===n||n.height(t)},!1,!0)}}else{const t=function(t,e,n=!1){const o=t.fontSize(),r=t.height(),i=m(e.text);let a=e.a.fontSize;t.height(void 0);const l=Math.round(2*e.a.fontSize)-1;for(let s=1;s<l;s++){const o=e.a.height&&t.height()>e.a.height;let r=i.split("\n").join(" ").split(/[\s-]+/).reduce((t,e)=>(e=e.toLowerCase(),/[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFFEF\u4E00-\u9FAF\uAC00-\uD7AF]/.test(e)?t.concat(e.split("")):t.concat(e)),[]),l=t.textArr.map(t=>t.text.toLowerCase()).join(";");const s=r.find(t=>!l.includes(t)||(l=l.replace(t,""),!1));if(!(o||s&&!n)){break}a-=.5,t.fontSize(a)}return t.fontSize(o),t.height(r),a}(s.current,e,n);if(t!==e.a.fontSize){return void o(()=>{e.set({fontSize:t})},!1,!0)}const r=W();e.a.height===r||M||o(()=>{e.set({height:r})},!1,!0)}}}),t.useLayoutEffect(()=>{var t;if(H&&e.curveEnabled){const n=null===(t=f.current)||void 0===t?void 0:t.getSelfRect().width;if(n){const t=n-e.a.width,o=e.a.rotation*Math.PI/180,r=-t/2*Math.cos(o),i=-t/2*Math.sin(o);e.set({width:n,x:e.a.x+r,y:e.a.y+i})}}},[H,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useLayoutEffect(()=>{const t=s.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),v(t,e))},[H]);const X=t.useRef(null),Y=t.useRef(0),B=t=>{t.evt.preventDefault();const n=a.selectedShapes.find(t=>t===e);n&&e.contentEditable&&(Y.current=function(t){var e;const n=t.target,o=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var n=t.getStage().getPointerPosition();return e.point(n)}(n),r=n.textArr,i=Math.floor(o.y/(n.fontSize()*n.lineHeight())),a=r.slice(0,i).reduce((t,e)=>t+e.text.length,i),l=null!==(e=r[i])&&void 0!==e?e:r[0];let s=0;return"right"===n.align()?s=n.width()-l.width:"center"===n.align()&&(s=n.width()/2-l.width/2),a+Math.round((o.x-s)/l.width*l.text.length)}(t),e.toggleEditMode())},D=!P&&e.placeholder?.6:e.a.opacity;y(s,D);const N=getLineHeight({fontLoaded:H,fontFamily:e.fontFamily,fontSize:e.a.fontSize,lineHeight:e.lineHeight}),I=e.selectable||"admin"===a.role,J=h(e),_=h(e,e.stroke,"stroke"),V=t.useMemo(()=>e.backgroundEnabled?e.curveEnabled?function({width:t,height:e,padding:n=0,cornerRadius:o=0}){const r=-n,i=-n,a=t+n,l=e+n,s=d(`M ${r} ${i} L ${a} ${i} L ${a} ${l} L ${r} ${l} Z`);return c(s,o).path}({width:e.a.width,height:e.a.height,cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*N*.5),padding:e.backgroundPadding*(e.a.fontSize*N*.5)}):function({lines:t,lineHeight:e,width:n,align:o="left",padding:r=0,cornerRadius:i=0}){var a;t.forEach((t,e)=>{t.cx=n/2,"right"===o?t.cx=n-t.width/2:"left"===o&&(t.cx=t.width/2),"justify"!==o||t.lastInParagraph||(t.width=n),"justify"===o&&(t.cx=t.width/2)});let l=`M ${null===(a=t[0])||void 0===a?void 0:a.cx} ${-r}`;t.forEach((n,o)=>{const{cx:i}=n,a=t[o-1];a&&a.width>n.width?l+=` L ${i+n.width/2+r} ${o*e+r}`:l+=` L ${i+n.width/2+r} ${o*e-r}`;const s=t[o+1];s&&s.width>n.width?l+=` L ${i+n.width/2+r} ${(o+1)*e-r}`:l+=` L ${i+n.width/2+r} ${(o+1)*e+r}`});for(var s=t.length-1;s>=0;s--){const n=t[s],{cx:o}=n,i=t[s+1];i&&i.width>n.width?l+=` L ${o-n.width/2-r} ${(s+1)*e-r}`:l+=` L ${o-n.width/2-r} ${(s+1)*e+r}`;const a=t[s-1];a&&a.width>n.width?l+=` L ${o-n.width/2-r} ${s*e+r}`:l+=` L ${o-n.width/2-r} ${s*e-r}`}l+=" Z";const h=d(l);return c(h,i).path}({lines:JSON.parse(JSON.stringify(T)),cornerRadius:e.backgroundCornerRadius*(e.a.fontSize*N*.5),lineHeight:N*e.a.fontSize,padding:e.backgroundPadding*(e.a.fontSize*N*.5),width:e.a.width,align:e.align}):"",[e.backgroundEnabled,e.curveEnabled,e.backgroundCornerRadius,e.a.fontSize,e.a.height,N,e.backgroundPadding,e.a.width,e.align,T]),Z=S();let U=0;e.curveEnabled||("middle"===e.verticalAlign?U=(e.a.height-T.length*N*e.a.fontSize)/2:"bottom"===e.verticalAlign&&(U=e.a.height-T.length*N*e.a.fontSize));const q=e.curveEnabled?x(e.a.width,e.a.height,e.curvePower,e.a.fontSize):"",G=H?'"'+e.fontFamily+'"':j===e.fontFamily?"Arial":'"'+j+'"';return t.createElement(t.Fragment,null,t.createElement(o,{ref:p,x:e.a.x,y:e.a.y,rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*D,data:V,fill:e.backgroundColor,offsetY:-U}),t.createElement(o,{data:q,stroke:"red",strokeWidth:1,x:e.a.x,y:e.a.y,rotation:e.a.rotation,visible:!1}),t.createElement(i,Object.assign({ref:f,visible:e.curveEnabled,data:q,text:P||e.placeholder,listening:!1,align:"center",textBaseline:"middle"},J,_,{strokeWidth:e.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:`"${e.fontFamily}", "${j}"`,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration.trim(),letterSpacing:e.letterSpacing*e.a.fontSize,x:e.a.x,y:e.a.y,rotation:e.a.rotation,opacity:e._editModeEnabled?.3:D,hideInExport:!e.showInExport,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity})),t.createElement(r,Object.assign({ref:s,id:e.id,name:"element",hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled,x:e.a.x,y:e.a.y,rotation:e.a.rotation,width:e.a.width,height:e.a.height,text:P||e.placeholder,direction:w(P)},J,_,{lineJoin:"round",strokeWidth:e.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:e.a.fontSize,fontFamily:G,fontStyle:e.fontStyle+" "+e.fontWeight,textDecoration:e.textDecoration,align:e.align,verticalAlign:e.verticalAlign,draggable:Z?e.draggable&&L:e.draggable,preventDefault:!Z||L,opacity:e.curveEnabled?0:D,visible:!e._editModeEnabled,ellipsis:"ellipsis"===g.textOverflow,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,lineHeight:N,letterSpacing:e.letterSpacing*e.a.fontSize,listening:I,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},onClick:B,onTap:B,onTransformStart:()=>{k(!0),A.current=s.current.height()},onTransform:t=>{var n,o,r;const i=t.target;null===(n=p.current)||void 0===n||n.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(o=i.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),n=i.width()*t,o=e.a.fontSize;let r=n;n<o&&(r=o,X.current&&i.position(X.current)),i.width(r),i.scaleX(1),i.scaleY(1);let a=W();if("ellipsis"===g.textOverflow){a=A.current}else{const t=Math.max(a,A.current);i.height(t),e.set({height:i.height()})}const l=g.textVerticalResizeEnabled?Math.max(a,A.current):W();e.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:l}),v(i,e)}if("top-center"===a||"bottom-center"===a){let n="resize"===g.textOverflow?W():N*e.a.fontSize;t.target.height(Math.max(n,t.target.height()*t.target.scaleY())),t.target.scaleY(1)}X.current=t.target.position();const l=t.target.scaleX();null===(r=p.current)||void 0===r||r.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.a.fontSize*l,width:t.target.width()*l,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*l,shadowBlur:e.shadowBlur*l,shadowOffsetX:e.shadowOffsetX*l,shadowOffsetY:e.shadowOffsetY*l,strokeWidth:e.strokeWidth*l})},onTransformEnd:t=>{var n;const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:Math.round(e.a.fontSize*o),width:Math.ceil(t.target.width()*o),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*o,shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o}),null===(n=p.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),k(!1)}})),b&&t.createElement(n,{x:e.a.x,y:e.a.y,rotation:e.a.rotation},t.createElement($,{textNodeRef:s,element:e,selectAll:z,cursorPosition:Y.current,onBlur:()=>{e.toggleEditMode(!1)}})))});
|
package/canvas/tooltip.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{observer as t}from"mobx-react-lite";import{Html as n}from"react-konva-utils";import{Navbar as o,NavbarGroup as l}from"@blueprintjs/core";import{getTotalClientRect as r}from"../utils/math.js";import{extendToolbar as i}from"../toolbar/element-container.js";import{TextAiWrite as s}from"../toolbar/text-ai-write.js";import{flags as a}from"../utils/flags.js";import{DuplicateButton as u}from"../toolbar/duplicate-button.js";import{RemoveButton as c}from"../toolbar/remove-button.js";import{PositionPicker as d}from"../toolbar/position-picker.js";import{GroupButton as m}from"../toolbar/group-button.js";function f(e,t){return e.classList.contains(t)?e:e.parentElement?f(e.parentElement,t):null}const p=()=>null;export const Tooltip=t(({store:t,page:v,components:h,stageRef:g,tooltipSafeArea:E})=>{var b,k,w;const x=t.selectedShapes.every(e=>e.page===v),y=e.useRef(null),[C,j]=e.useState(!1),I=t._hasCroppedImages;t.selectedElements.length,e.useEffect(()=>{var e,t,n;const o=()=>{j(!0)},l=()=>{j(!1)};null===(e=null==g?void 0:g.current)||void 0===e||e.on("dragstart",o),null===(t=null==g?void 0:g.current)||void 0===t||t.on("dragend",l);const r=null===(n=null==g?void 0:g.current)||void 0===n?void 0:n.findOne("Transformer");return null==r||r.on("transformstart",o),null==r||r.on("transformend",l),()=>{var e,t;null===(e=null==g?void 0:g.current)||void 0===e||e.off("dragstart",o),null===(t=null==g?void 0:g.current)||void 0===t||t.off("dragend",l),null==r||r.off("transformstart",o),null==r||r.off("transformend",l)}},[]);const[N,T]=e.useState({fit:!0,needCalculate:!1,token:Math.random()});function O(){if(!y.current){return}if(!N.needCalculate){return}const e=f(y.current,"polotno-workspace-container");if(!e){return}const t=e.getBoundingClientRect(),n=y.current.getBoundingClientRect(),o=(n.right,t.left,n.top-t.top),l=(n.left,t.left,n.bottom-t.top),r=(null==E?void 0:E.top)||0,i=(null==E?void 0:E.bottom)||0;o<20+r&&N.fit?T({fit:!1,needCalculate:!1,token:N.token}):l-t.height>-20-i&&!N.fit?T({fit:!0,needCalculate:!1,token:N.token}):T({fit:N.fit,needCalculate:!1,token:N.token})}if(e.useEffect(()=>{0!==t.selectedElements.length&&T({fit:!0,needCalculate:!0,token:Math.random()})},[t.selectedElements,C]),e.useLayoutEffect(()=>{const e=setTimeout(()=>{O()},100);return()=>{clearTimeout(e)}},[N.needCalculate,y.current,N.token]),e.useEffect(()=>{if(!g.current){return}const e=f(g.current.content,"polotno-workspace-inner");if(!e){return}const n=()=>{t.selectedElements.length&&T({fit:!0,needCalculate:!0,token:Math.random()})};return null==e||e.addEventListener("scroll",n),()=>{null==e||e.removeEventListener("scroll",n)}},[]),0===t.selectedShapes.length){return null}if(C){return null}if(!x){return null}if(t.activePage!==v){return null}if(I){return null}const S=r(t.selectedShapes),R=(null==h?void 0:h.Position)||d,M=(null==h?void 0:h.Duplicate)||u,Y=(null==h?void 0:h.Remove)||c,B=(null==h?void 0:h.Group)||m,F=(null==h?void 0:h.Lock)||p,L=null===(b=t.selectedElements[0])||void 0===b?void 0:b.type,P=Object.assign(Object.assign({},a.aiTextEnabled?{TextAiWrite:s}:{}),h||{}),X=i({components:P,type:L,usedItems:[]}),_=(null===(w=null===(k=null==g?void 0:g.current)||void 0===k?void 0:k.findOne("Transformer"))||void 0===w?void 0:w.rotation())||0;let A=
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import{Html as n}from"react-konva-utils";import{Navbar as o,NavbarGroup as l}from"@blueprintjs/core";import{getTotalClientRect as r}from"../utils/math.js";import{extendToolbar as i}from"../toolbar/element-container.js";import{TextAiWrite as s}from"../toolbar/text-ai-write.js";import{flags as a}from"../utils/flags.js";import{DuplicateButton as u}from"../toolbar/duplicate-button.js";import{RemoveButton as c}from"../toolbar/remove-button.js";import{PositionPicker as d}from"../toolbar/position-picker.js";import{GroupButton as m}from"../toolbar/group-button.js";function f(e,t){return e.classList.contains(t)?e:e.parentElement?f(e.parentElement,t):null}const p=()=>null;export const Tooltip=t(({store:t,page:v,components:h,stageRef:g,tooltipSafeArea:E})=>{var b,k,w;const x=t.selectedShapes.every(e=>e.page===v),y=e.useRef(null),[C,j]=e.useState(!1),I=t._hasCroppedImages;t.selectedElements.length,e.useEffect(()=>{var e,t,n;const o=()=>{j(!0)},l=()=>{j(!1)};null===(e=null==g?void 0:g.current)||void 0===e||e.on("dragstart",o),null===(t=null==g?void 0:g.current)||void 0===t||t.on("dragend",l);const r=null===(n=null==g?void 0:g.current)||void 0===n?void 0:n.findOne("Transformer");return null==r||r.on("transformstart",o),null==r||r.on("transformend",l),()=>{var e,t;null===(e=null==g?void 0:g.current)||void 0===e||e.off("dragstart",o),null===(t=null==g?void 0:g.current)||void 0===t||t.off("dragend",l),null==r||r.off("transformstart",o),null==r||r.off("transformend",l)}},[]);const[N,T]=e.useState({fit:!0,needCalculate:!1,token:Math.random()});function O(){if(!y.current){return}if(!N.needCalculate){return}const e=f(y.current,"polotno-workspace-container");if(!e){return}const t=e.getBoundingClientRect(),n=y.current.getBoundingClientRect(),o=(n.right,t.left,n.top-t.top),l=(n.left,t.left,n.bottom-t.top),r=(null==E?void 0:E.top)||0,i=(null==E?void 0:E.bottom)||0;o<20+r&&N.fit?T({fit:!1,needCalculate:!1,token:N.token}):l-t.height>-20-i&&!N.fit?T({fit:!0,needCalculate:!1,token:N.token}):T({fit:N.fit,needCalculate:!1,token:N.token})}if(e.useEffect(()=>{0!==t.selectedElements.length&&T({fit:!0,needCalculate:!0,token:Math.random()})},[t.selectedElements,C]),e.useLayoutEffect(()=>{const e=setTimeout(()=>{O()},100);return()=>{clearTimeout(e)}},[N.needCalculate,y.current,N.token]),e.useEffect(()=>{if(!g.current){return}const e=f(g.current.content,"polotno-workspace-inner");if(!e){return}const n=()=>{t.selectedElements.length&&T({fit:!0,needCalculate:!0,token:Math.random()})};return null==e||e.addEventListener("scroll",n),()=>{null==e||e.removeEventListener("scroll",n)}},[]),0===t.selectedShapes.length){return null}if(C){return null}if(!x){return null}if(t.activePage!==v){return null}if(I){return null}const S=r(t.selectedShapes),R=(null==h?void 0:h.Position)||d,M=(null==h?void 0:h.Duplicate)||u,Y=(null==h?void 0:h.Remove)||c,B=(null==h?void 0:h.Group)||m,F=(null==h?void 0:h.Lock)||p,L=null===(b=t.selectedElements[0])||void 0===b?void 0:b.type,P=Object.assign(Object.assign({},a.aiTextEnabled?{TextAiWrite:s}:{}),h||{}),X=i({components:P,type:L,usedItems:[]}),_=(null===(w=null===(k=null==g?void 0:g.current)||void 0===k?void 0:k.findOne("Transformer"))||void 0===w?void 0:w.rotation())||0;let A=80;return Math.abs(_)<30&&N.fit&&(A=80),Math.abs(_)>140&&!N.fit&&(A=80),e.createElement(n,{parentNodeFunc:({stage:e})=>{var t,n;return(null===(t=null==e?void 0:e.container())||void 0===t?void 0:t.closest(".polotno-workspace-container"))||(null===(n=null==e?void 0:e.container())||void 0===n?void 0:n.parentNode)},transformFunc:e=>{var t;const n=S.x+S.width/2,o=N.fit?S.y*e.scaleY-A:S.y*e.scaleY+S.height*e.scaleY+A,l=null===(t=null==g?void 0:g.current)||void 0===t?void 0:t.container(),r=(null==l?void 0:l.getBoundingClientRect())||{left:0,top:0,width:0,height:0,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},i=null==l?void 0:l.closest(".polotno-workspace-container"),s=(null==i?void 0:i.getBoundingClientRect())||{left:0,top:0,width:Number.POSITIVE_INFINITY,height:Number.POSITIVE_INFINITY,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},a=r.left-s.left,u=r.top-s.top;let c=a+e.x+n*e.scaleX,d=c-S.width*e.scaleX/2,m=c+S.width*e.scaleX/2;const f=Math.min(50,S.width/2*e.scaleX),p=m>=f&&d<=s.width-f,v=y.current?y.current.getBoundingClientRect().width:0,h=(null==E?void 0:E.left)||0,b=(null==E?void 0:E.right)||0;if(Number.isFinite(s.width)&&v>0&&p){const e=8+v/2+h,t=s.width-8-v/2-b;t>=e&&(c=Math.max(e,Math.min(c,t)))}return m<f&&(c-=v+8),d>s.width-f&&(c+=v+8),Object.assign(Object.assign({},e),{x:c,y:u+e.y+o,scaleX:1,scaleY:1})},divProps:{style:{pointerEvents:"none",position:"absolute",visibility:N.needCalculate?"hidden":"visible",zIndex:9}}},e.createElement("div",{ref:e=>{y.current=e,!y.current&&e&&O()},style:{pointerEvents:"none"}},e.createElement(o,{style:{padding:"2px",borderRadius:"5px",height:"34px",transform:"translate(-50%, -50%)",pointerEvents:"auto"}},e.createElement(l,{style:{height:"30px"}},X.map(n=>{const o=P[n];return e.createElement(o,{elements:t.selectedElements,element:t.selectedElements[0],store:t,key:n})}),e.createElement(B,{store:t}),e.createElement(F,{store:t}),e.createElement(M,{store:t}),e.createElement(Y,{store:t}),e.createElement(R,{store:t})))))});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{observer as t}from"mobx-react-lite";import r from"./page.js";import{TopRules as n}from"./rules.js";import{AudioElement as o}from"./audio.js";import{handleHotkey as
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import r from"./page.js";import{TopRules as n}from"./rules.js";import{AudioElement as o}from"./audio.js";import{handleHotkey as l}from"./hotkeys.js";import{t as i}from"../utils/l10n.js";const a=({store:t})=>e.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},e.createElement("p",null,i("workspace.noPages")),e.createElement("button",{onClick:()=>{t.addPage()}},i("workspace.addPage"))),s=({width:t,height:r,xPadding:n,yPadding:o,backgroundColor:l})=>e.createElement("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:n+"px",paddingRight:n+"px",paddingTop:o+"px",paddingBottom:o+"px",flexShrink:0}},e.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}})),c=[4,6];export const WorkspaceCanvas=t(({store:t,layout:i="vertical",pageControlsEnabled:u,backgroundColor:d,pageBorderColor:h,activePageBorderColor:g,bleedColor:f,snapGuideStroke:p,snapGuideStrokeWidth:m,snapGuideDash:v,selectionRectFill:w,selectionRectStroke:b,selectionRectStrokeWidth:x,transformLabelFill:k,transformLabelTextFill:y,distanceGuideStroke:E,distanceLabelFill:T,distanceLabelTextFill:L,components:P,onKeyDown:M,paddingX:R,paddingY:S,altCloneEnabled:C=!0,visiblePagesOffset:F,renderOnlyActivePage:W,tooltipSafeArea:O})=>{var _;const j="horizontal"===i,z=null!=R?R:20,G=null!=S?S:55,[B,D]=e.useState({width:100,height:100}),H=e.useRef(B),N=e.useRef(null),A=e.useRef(null),Y=t.bleedVisible?Math.max(0,...t.pages.map(e=>e.bleed)):0,I=Math.max(...t.pages.map(e=>e.computedWidth)),K=Math.max(...t.pages.map(e=>e.computedHeight)),V=(null===(_=t.activePage)||void 0===_?void 0:_.computedHeight)||0,X=I+2*Y,q=(W?V:K)+2*Y,J=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===N.current){return}const r=N.current.getBoundingClientRect();0!==r.width&&0!==r.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(N.current));const n=A.current.clientWidth||r.width,o={width:n,height:r.height};(H.current.width!==o.width||H.current.height!==o.height)&&(D(o),H.current=o);const l=(n-2*z)/X,i=t.pages.length>1?3.1:2,a=(r.height-G*i)/q,s=t.pages.length>1?3.1:2,c=(n-z*s)/X,u=(r.height-2*G)/q,d=t.pages.length?Math.max(Math.min(j?c:l,j?u:a),.01):1;t.scaleToFit!==d&&(t.setScale(d),t._setScaleToFit(d))};e.useLayoutEffect(()=>{J({skipTimeout:!0})},[]),e.useEffect(()=>{J()},[X,q,S,R]),e.useLayoutEffect(()=>{J({skipTimeout:!0})},[t.openedSidePanel]),e.useEffect(()=>{t.__()},[]),e.useEffect(()=>{const e=N.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{J({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{J({skipTimeout:!0})},100);return()=>clearInterval(e)}},[X,q]);const Q=W?1:t.pages.length;let U,Z;if(j){const e=X*t.scale*Q;U=Math.max(z,(B.width-e)/Q/2),Z=Math.max(G,(B.height-q*t.scale)/2)}else{U=Math.max(z,(B.width-X*t.scale)/2);const e=q*t.scale*Q;Z=Math.max(G,(B.height-e)/Q/2)}e.useEffect(()=>{const e=e=>{(M||l)(e,t)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),e.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const l=Math.max(5,t.scaleToFit);let i=Math.min(.1,t.scaleToFit);j&&X>0&&Number.isFinite(X)&&(i=Math.max(i,300/X)),i=Math.max(i,.01);const a=.03,s=(r=e.deltaY<0?t.scale*(1+a):t.scale/(1+a),n=i,o=l,Math.max(n,Math.min(o,r)));return void t.setScale(s)}var r,n,o},r=A.current;return null==r||r.addEventListener("wheel",e),()=>null==r?void 0:r.removeEventListener("wheel",e)},[j,X,t]);const $=e.useRef(!1);((t,r,n,o,l,i)=>{const a=e.useRef({width:r,height:n}),s=e.useRef({top:0,left:0}),c=e.useRef(!1),u=e.useRef(l.pages.length);c.current=u.current!==l.pages.length,u.current=l.pages.length,e.useEffect(()=>{const e=t.current,r=t=>{s.current={top:e.scrollTop,left:e.scrollLeft}};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[]),e.useLayoutEffect(()=>{if(!t.current){return}if(c.current){return}const e=t.current,o=(s.current.left+e.offsetWidth/2)/a.current.width,l=(s.current.top+e.offsetHeight/2)/a.current.height;i.current=!0,e.scrollLeft=o*r-e.offsetWidth/2,e.scrollTop=l*n-e.offsetHeight/2,a.current={width:r,height:n}},[o,r,n])})(A,X*t.scale+2*U,q*t.scale+2*Z,t.scale,t,$);const ee=j?X*t.scale+2*U:q*t.scale+2*Z,{handleScroll:te}=((t,r,n,o,l,i,a)=>{const s=e.useRef(!1),c=e.useRef(null),u=e.useRef(!1),d="horizontal"===a;e.useEffect(()=>{const e=t.current,r=()=>{l.current};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[]);const h=n.pages.indexOf(n.activePage);return e.useLayoutEffect(()=>{if(i){return}if(!n.activePage){return}if(!t.current){return}if(s.current){return}const e=t.current,o=n.pages.indexOf(n.activePage)*r,l=d?e.scrollLeft:e.scrollTop;let a=()=>{};return(Math.abs(o-l)>.5*r||u.current)&&(u.current=!0,a=(({element:e,scrollTop:t,scrollLeft:r,duration:n=300,onFinish:o=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,a=l?t:r,s=a-i;let c=0,u=!1;if(0===n){return l?e.scrollTop=a:e.scrollLeft=a,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,s,n);l?e.scrollTop=t:e.scrollLeft=t,c<n?setTimeout(d,20):o()},h=(e,t,r,n)=>(e/=n/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:e},d?{scrollLeft:o}:{scrollTop:o}),{onFinish:()=>{u.current=!1},duration:n.isPlaying?0:300}))),a},[n.activePage,h,n.isPlaying,i,a]),{handleScroll:e=>{if(i){return}if(u.current){return}s.current=!0,clearTimeout(c.current),c.current=setTimeout(()=>{s.current=!1},300);const t=e.currentTarget.childNodes[0];if(!t){return}const r=d?t.offsetWidth:t.offsetHeight;if(!r){return}const l=d?e.currentTarget.scrollLeft:e.currentTarget.scrollTop,a=d?o.width:o.height,h=Math.floor((l+a/3)/r),g=n.pages[h];g&&n.activePage!==g&&g.select()}}})(A,ee,t,B,$,W,i),re=B.width>=X*t.scale+2*U,ne=B.height>=q*t.scale+2*Z,oe=d||"rgba(232, 232, 232, 0.9)",le=(null==P?void 0:P.NoPages)||a,ie=j?X*t.scale+2*U:q*t.scale+2*Z,ae=j?B.width:B.height,se=A.current?j?A.current.scrollLeft:A.current.scrollTop:0,ce=Math.max(0,Math.floor(se/ie)),ue=Math.min(t.pages.length-1,Math.ceil((se+ae)/ie)),de=null!=F?F:1,he=Math.max(0,ce-de),ge=Math.min(t.pages.length-1,ue+de);return e.createElement("div",{ref:N,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:oe,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container"},e.createElement("div",{ref:A,onScroll:te,style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:j?"row":"column",overflow:"auto",overflowX:j?"auto":re?"hidden":"auto",overflowY:j&&ne?"hidden":"auto"},className:"polotno-workspace-inner"},t.pages.map((n,o)=>{const l=n===t.activePage;if(W&&!l&&!n._exportingOrRendering&&!n._forceMount){return null}if(!(o>=he&&o<=ge||n._exportingOrRendering||n._forceMount)){return e.createElement("div",{key:n.id,style:{flexShrink:0}},e.createElement(s,{width:X*t.scale+2*U,height:q*t.scale+2*Z,backgroundColor:oe,xPadding:U,yPadding:Z}))}const a=e.createElement(r,{key:n.id,page:n,xPadding:U,yPadding:Z,width:X*t.scale+2*U,height:q*t.scale+2*Z,store:t,pageControlsEnabled:u,backColor:oe,pageBorderColor:h||"lightgrey",activePageBorderColor:g||"rgb(0, 161, 255)",altCloneEnabled:C,bleedColor:f||"rgba(255, 0, 0, 0.1)",selectionRectFill:w,selectionRectStroke:b,selectionRectStrokeWidth:x,snapGuideStroke:p||"rgb(0, 161, 255)",snapGuideStrokeWidth:m||1,snapGuideDash:v||c,transformLabelFill:k,transformLabelTextFill:y,distanceGuideStroke:E||"rgb(0, 161, 255)",distanceLabelFill:T||"rgb(0, 161, 255)",distanceLabelTextFill:L||"white",components:P,viewportSize:B,layout:i,tooltipSafeArea:O});return(n._exportingOrRendering||n._forceMount)&&!l&&W?e.createElement("div",{style:{display:"none",flexShrink:0},key:n.id},a):a}),t.rulesVisible&&e.createElement(n,{store:t,xPadding:U,yPadding:Z,width:X*t.scale+2*U,height:q*t.scale+2*Z,layout:i}),0===t.pages.length&&e.createElement(le,{store:t}),t.audios.map(r=>e.createElement(o,{key:r.id,audio:r,store:t}))))});export default WorkspaceCanvas;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polotno",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.35.0",
|
|
4
4
|
"description": "Design Editor Framework",
|
|
5
5
|
"author": "Anton Lavrenov",
|
|
6
6
|
"keywords": [
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
"functions-have-names": "^1.2.3",
|
|
68
68
|
"gifuct-js": "^2.1.2",
|
|
69
69
|
"gradient-parser": "^1.1.1",
|
|
70
|
+
"konva": "^10.2.0",
|
|
70
71
|
"mediabunny": "^1.24.1",
|
|
71
|
-
"konva": "^10.0.12",
|
|
72
72
|
"mensch": "^0.3.4",
|
|
73
73
|
"mobx": "6.15.0",
|
|
74
74
|
"mobx-react-lite": "^4.1.1",
|
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
],
|
|
115
115
|
"devDependencies": {
|
|
116
116
|
"@canvas/image": "^2.0.0",
|
|
117
|
+
"@polotno/video-export": "^0.0.9",
|
|
117
118
|
"@size-limit/preset-big-lib": "^11.2.0",
|
|
118
119
|
"@testing-library/dom": "^10.4.1",
|
|
119
120
|
"@testing-library/jest-dom": "^6.9.1",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{observer as t}from"mobx-react-lite";import{Button as n,Menu as o,MenuItem as i,Popover as a,Position as s}from"@blueprintjs/core";import{More as r,Trash as l}from"@blueprintjs/icons";import{t as m}from"../utils/l10n.js";import{Spinner as c}from"./spinner.js";import{useWaveformData as d,useWaveformPath as p}from"./waveform.js";import{TrackWrapper as u,TrackContainer as h,TrackMenu as x,TrackHandleLeft as f,TrackHandleRight as v}from"./track-styles.js";export const AUDIO_ROW_HEIGHT=28;export const AUDIO_TRACK_HEIGHT=24;const
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import{Button as n,Menu as o,MenuItem as i,Popover as a,Position as s}from"@blueprintjs/core";import{More as r,Trash as l}from"@blueprintjs/icons";import{t as m}from"../utils/l10n.js";import{Spinner as c}from"./spinner.js";import{useWaveformData as d,useWaveformPath as p}from"./waveform.js";import{TrackWrapper as u,TrackContainer as h,TrackMenu as x,TrackHandleLeft as f,TrackHandleRight as M,WaveformSvg as v}from"./track-styles.js";export const AUDIO_ROW_HEIGHT=28;export const AUDIO_TRACK_HEIGHT=24;const T=({position:e,store:t,scale:n})=>{const o=t.pages;for(const i of o){const t=i.startTime,o=i.startTime+i.duration;if(Math.abs(e-t)<10/n){return t}if(Math.abs(e-o)<10/n){return o}}return null};export const AudioTrack=t(({audio:t,scale:E,store:w,index:y})=>{const g=(e=t.startTime,n=t.endTime)=>Math.max(0,(n-e)*(t.duration||0)),I=e=>Math.max(0,w.duration-e),b=(e,t=g())=>Math.min(Math.max(0,e),I(t)),D=g(),L=w.duration*E-t.delay*E,j=Math.min(D*E,L),N=t.delay*E,{data:A,isLoading:O}=d(t.src),P=(t.endTime-t.startTime)*t.duration*E,_=p(A,20).path,k=(e,n)=>{e.stopPropagation(),e.preventDefault();const o=e.clientX,i=N,a=j,s=t.endTime,r=t.startTime,l=t.delay,m=t.duration||1,c=e=>{e.preventDefault();const c=(e.clientX-o)/E;if("start"===n){if(c>=0){const e=c,n=Math.max(0,s-.1-r)*m,o=Math.min(e,n);if(o<=0){return}let i=r+o/m;const a=(t.endTime-i)*m,d=l+o,p=I(a);let u=Math.min(Math.max(0,d),p);const h=T({position:u,store:w,scale:E});u=Math.min(Math.max(0,null!=h?h:u),p);const x=u-d;i=Math.min(t.endTime-.1,Math.max(0,i+x/m)),t.set({delay:u,startTime:i})}else{const e=-c,n=r*m,o=Math.min(e,n);if(o<=0){return}const i=o/m;let a=Math.max(0,r-i);const s=(t.endTime-a)*m,d=l-o,p=I(s);let u=Math.min(Math.max(0,d),p);const h=T({position:u,store:w,scale:E});u=Math.min(Math.max(0,null!=h?h:u),p);const x=u-d;a=Math.max(0,Math.min(t.endTime-.1,a+x/m)),t.set({delay:u,startTime:a})}}else{const e=i/E+a/E;let n=e+c;const o=T({position:n,store:w,scale:E});n=null!=o?o:n;const r=(n-e)/t.duration,l=Math.min(1,Math.max(t.startTime+.1,s+r));t.set({endTime:l})}},d=()=>{if(window.removeEventListener("mousemove",c),window.removeEventListener("mouseup",d),"start"===n){const e=T({position:t.delay,store:w,scale:E});if(null!=e&&e!==t.delay){const n=g(t.startTime,t.endTime),o=b(e,n),i=o-t.delay,a=Math.max(0,Math.min(t.endTime-.1,t.startTime+i/m));t.set({delay:o,startTime:a})}}};window.addEventListener("mousemove",c),window.addEventListener("mouseup",d)};return e.createElement(u,{style:{left:`${N}px`,top:28*y+"px",width:`${j}px`,height:"24px"},className:"polotno-audio-container"},e.createElement(h,{style:{width:"100%",height:"100%",color:"var(--polotno-timeline-audio-color, rgba(0, 161, 255, 0.85))"},onMouseDown:e=>{const n=e.clientX,o=N;e.preventDefault();const i=e=>{e.preventDefault();const i=(e.clientX-n)/E;let a=o/E+i;const s=a+D,r=T({position:a,store:w,scale:E}),l=T({position:s,store:w,scale:E}),m=null!==r?Math.abs(a-r):Number.POSITIVE_INFINITY,c=null!==l?Math.abs(s-l):Number.POSITIVE_INFINITY;let d;d=b(null!==r&&m<c?r:null!==l?l-D:a),t.set({delay:b(d)})},a=()=>{window.removeEventListener("mousemove",i),window.removeEventListener("mouseup",a)};window.addEventListener("mousemove",i),window.addEventListener("mouseup",a)}},e.createElement("div",{style:{position:"absolute",inset:"0 0 0 0",display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"}},e.createElement("div",{style:{display:"flex",alignItems:"center",width:"100%",height:"100%",gap:"8px"}},_&&e.createElement("div",{style:{flex:1,height:"14px",overflow:"hidden"}},e.createElement(v,{width:P,height:"14",viewBox:`0 0 ${P} 20`,preserveAspectRatio:"none",style:{width:P+"px",height:"14px",transform:`translateX(-${t.startTime*P}px)`}},e.createElement("path",{d:_}))),O&&e.createElement("div",{style:{flex:1,display:"flex",justifyContent:"center",alignItems:"center"}},e.createElement(c,null)))),e.createElement(f,{onMouseDown:e=>k(e,"start")}),e.createElement(M,{onMouseDown:e=>k(e,"end")}),e.createElement(x,{className:"polotno-track-menu",onClick:e=>{e.stopPropagation()},onMouseDown:e=>e.stopPropagation()},e.createElement(a,{content:e.createElement(o,{style:{width:"100px"}},e.createElement(i,{icon:e.createElement(l,null),text:m("pagesTimeline.removeAudio"),onClick:()=>{w.removeAudio(t.id)}})),position:s.TOP},e.createElement(n,{icon:e.createElement(r,null),style:{minHeight:"20px",borderRadius:"10px",padding:"0px"}})))))});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{observer as t}from"mobx-react-lite";import{Button as n,Menu as o,MenuItem as
|
|
1
|
+
import e from"react";import{observer as t}from"mobx-react-lite";import{Button as n,Menu as o,MenuItem as l,Popover as i,Position as r}from"@blueprintjs/core";import{Duplicate as a,More as s,Trash as m}from"@blueprintjs/icons";import{t as c}from"../utils/l10n.js";import{TrackWrapper as p,TrackContainer as u,TrackMenu as d,TrackHandleLeft as E,TrackHandleRight as v,TrackLabel as w}from"./track-styles.js";import{duplicateElements as x}from"../utils/duplicate.js";export const ELEMENT_ROW_HEIGHT=26;const f=100,y=(e,t,n)=>Math.min(n,Math.max(t,e)),h=(e,t)=>{const n=e.animations.find(e=>e.type===t);n?n.enabled||e.setAnimation(t,{enabled:!0}):e.setAnimation(t,{})},b=(e,t,n,o)=>{const l=y(n,0,t-f),i=y(o,l+f,t);h(e,"enter"),h(e,"exit"),e.setAnimation("enter",{delay:l}),e.setAnimation("exit",{delay:Math.max(0,t-i)})};export const ElementTrack=t(({element:t,page:h,store:g,scale:L,row:M})=>{const D=h.duration,k=h.startTime,j=k+D,P=y((e=>{var t;const n=e.animations.find(e=>"enter"===e.type);return null!==(t=null==n?void 0:n.delay)&&void 0!==t?t:0})(t),0,D),T=y(D-(e=>{var t;const n=e.animations.find(e=>"exit"===e.type);return null!==(t=null==n?void 0:n.delay)&&void 0!==t?t:0})(t),P+f,D),A=Math.max(T-P,f)*L,X=(k+P)*L,C=t.name||t.type||c("toolbar.element"),[H,N]=e.useState(null),O=null!=H?H:M,R=()=>{N(e=>null===e?M:e)},$=()=>{N(null)},_=(e,n)=>{e.preventDefault(),e.stopPropagation(),R();const o=e.clientX,l=P,i=T,r=e=>{e.preventDefault();const r=(e.clientX-o)/L;if("start"===n){const e=y(k+l+r,k,k+i-f);b(t,D,e-k,i)}else{const e=y(k+i+r,k+l+f,j);b(t,D,l,e-k)}},a=()=>{window.removeEventListener("mousemove",r),window.removeEventListener("mouseup",a),$()};window.addEventListener("mousemove",r),window.addEventListener("mouseup",a)};return e.createElement(p,{style:{left:`${X}px`,top:26*O+"px",width:`${A}px`,height:"22px"}},e.createElement(u,{style:{width:"100%",height:"100%",color:"var(--polotno-timeline-element-color, rgba(255, 153, 0, 0.85))"},onMouseDown:e=>{e.preventDefault(),e.stopPropagation(),R();const n=e.clientX,o=P,l=T-o,i=e=>{e.preventDefault();const i=(e.clientX-n)/L,r=y(k+o+i,k,j-l)-k;b(t,D,r,r+l)},r=()=>{window.removeEventListener("mousemove",i),window.removeEventListener("mouseup",r),$()};window.addEventListener("mousemove",i),window.addEventListener("mouseup",r)}},e.createElement(w,null,C),e.createElement(E,{onMouseDown:e=>_(e,"start")}),e.createElement(v,{onMouseDown:e=>_(e,"end")}),e.createElement(d,{className:"polotno-track-menu",onMouseDown:e=>e.stopPropagation(),onClick:e=>e.stopPropagation()},e.createElement(i,{content:e.createElement(o,{style:{width:"140px"}},e.createElement(l,{icon:e.createElement(a,null),text:c("toolbar.duplicateElements"),onClick:()=>{x([t],g)}}),e.createElement(l,{icon:e.createElement(m,null),text:c("toolbar.removeElements"),onClick:()=>{g.deleteElements([t.id])}})),position:r.TOP},e.createElement(n,{icon:e.createElement(s,null),style:{minHeight:"20px",borderRadius:"10px",padding:"0px"}})))))});
|
|
@@ -1,4 +1,29 @@
|
|
|
1
|
-
import o from"../utils/styled.js";export const
|
|
1
|
+
import o from"../utils/styled.js";export const TrackLabel=o("div")`
|
|
2
|
+
position: absolute;
|
|
3
|
+
inset: 0 0 0 0;
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
padding: 0 12px;
|
|
7
|
+
pointer-events: none;
|
|
8
|
+
font-size: 11px;
|
|
9
|
+
font-weight: 500;
|
|
10
|
+
color: rgba(0, 0, 0, 0.75);
|
|
11
|
+
white-space: nowrap;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
text-overflow: ellipsis;
|
|
14
|
+
|
|
15
|
+
.bp5-dark & {
|
|
16
|
+
color: rgba(255, 255, 255, 0.92);
|
|
17
|
+
}
|
|
18
|
+
`;export const WaveformSvg=o("svg")`
|
|
19
|
+
& path {
|
|
20
|
+
fill: rgba(0, 0, 0, 0.5);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.bp5-dark & path {
|
|
24
|
+
fill: rgba(255, 255, 255, 0.7);
|
|
25
|
+
}
|
|
26
|
+
`;export const TrackWrapper=o("div")`
|
|
2
27
|
position: absolute;
|
|
3
28
|
|
|
4
29
|
&:hover {
|
|
@@ -28,7 +53,7 @@ import o from"../utils/styled.js";export const TrackWrapper=o("div")`
|
|
|
28
53
|
opacity: 0;
|
|
29
54
|
pointer-events: none;
|
|
30
55
|
transform: translateY(-50%);
|
|
31
|
-
`;const
|
|
56
|
+
`;const e=o("div")`
|
|
32
57
|
position: absolute;
|
|
33
58
|
top: 1px;
|
|
34
59
|
width: 12px;
|
|
@@ -47,8 +72,8 @@ import o from"../utils/styled.js";export const TrackWrapper=o("div")`
|
|
|
47
72
|
border: 1px solid rgba(255, 255, 255, 0.6);
|
|
48
73
|
background-color: rgba(0, 0, 0, 0.6);
|
|
49
74
|
}
|
|
50
|
-
`;export const TrackHandleLeft=o(
|
|
75
|
+
`;export const TrackHandleLeft=o(e)`
|
|
51
76
|
left: 0;
|
|
52
|
-
`;export const TrackHandleRight=o(
|
|
77
|
+
`;export const TrackHandleRight=o(e)`
|
|
53
78
|
right: 0;
|
|
54
79
|
`;
|