polotno 2.2.4 → 2.2.5

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.
@@ -1 +1 @@
1
- "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,a,r){void 0===r&&(r=a);var o=Object.getOwnPropertyDescriptor(t,a);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[a]}}),Object.defineProperty(e,r,o)}:function(e,t,a,r){void 0===r&&(r=a),e[r]=t[a]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var a in e)"default"!==a&&Object.prototype.hasOwnProperty.call(e,a)&&__createBinding(t,e,a);return __setModuleDefault(t,e),t},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ImageElement=exports.useImageLoader=exports.setImageLoaderHook=void 0;const react_1=__importDefault(require("react")),mobx_react_lite_1=require("mobx-react-lite"),mobx_1=require("mobx"),react_konva_1=require("react-konva"),use_image_1=__importDefault(require("use-image")),konva_1=__importDefault(require("konva")),react_konva_utils_1=require("react-konva-utils"),highlighter_1=require("./highlighter"),loader_1=require("../utils/loader"),svg=__importStar(require("../utils/svg")),flags_1=require("../utils/flags"),apply_filters_1=require("./apply-filters"),use_fadein_1=require("./use-fadein"),screen_1=require("../utils/screen");function createCanvas(){return document.createElement("canvas")}async function getFixedUrl(e){if(!(e.indexOf("data:image/svg+xml")>=0||e.indexOf(".svg")>=0))return e;const t=await svg.urlToString(e),a=svg.fixSize(t);return svg.svgToURL(a)}const useSizeFixer=e=>{const[t,a]=react_1.default.useState(e);return react_1.default.useEffect((()=>{(async()=>{const r=await getFixedUrl(e);r!==t&&a(r)})()}),[e]),t},useFlip=(e,t,a)=>{const r=react_1.default.useMemo((()=>{var r,o;const{flipX:i,flipY:n}=e,h="svg"===e.type||e.src.indexOf("data:image/svg+xml")>=0||e.src.indexOf(".svg")>=0,d=navigator.userAgent.toLowerCase().indexOf("firefox")>-1&&h||e.maskSrc;if(!i&&!n&&!d)return t;if(!t||!t.width||!t.height)return null;const c=createCanvas();let l=1;"svg"===e.type&&(l=Math.max(e.a.width/t.width*a,e.a.height/t.height*a)),c.width=Math.max(t.width*l,1),c.height=Math.max(t.height*l,1);let s=i?-c.width:0,u=n?-c.height:0;return null===(r=c.getContext("2d"))||void 0===r||r.scale(i?-1:1,n?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(t,s,u,c.width,c.height),c}),[e.maskSrc,e.flipX,e.flipY,t,e.a.width,e.a.height,a]);return react_1.default.useEffect((()=>()=>{r&&"CANVAS"===r.nodeName&&konva_1.default.Util.releaseCanvas(r)}),[r]),r};function getCrop(e,t){const a=t.width/t.height;let r,o;a>=e.width/e.height?(r=e.width,o=e.width/a):(r=e.height*a,o=e.height);return{x:(e.width-r)/2,y:(e.height-o)/2,width:r,height:o}}function downsample(e,t,a,r,o,i,n){for(var h=new ImageData(t,a),d=new Int32Array(e.data.buffer),c=e.width,l=new Int32Array(h.data.buffer),s=h.width,u=t/i,g=a/n,f=Math.round(1/u),_=Math.round(1/g),m=f*_,p=0;p<h.height;p++)for(var w=0;w<s;w++){for(var x=r+Math.round(w/u)+(o+Math.round(p/g))*c,v=0,M=0,y=0,b=0,E=0;E<_;E++)for(var k=0;k<f;k++){var I=d[x+k+E*c];v+=I<<24>>>24,M+=I<<16>>>24,y+=I<<8>>>24,b+=I>>>24}v=Math.round(v/m),M=Math.round(M/m),y=Math.round(y/m),b=Math.round(b/m),l[w+p*s]=b<<24|y<<16|M<<8|v}return h}function downScaleCanvas(e,t){var a,r;const o=createCanvas();o.width=e.width,o.height=e.height,null===(a=o.getContext("2d"))||void 0===a||a.drawImage(e,0,0,o.width,o.height);const i=downsample(o.getContext("2d").getImageData(0,0,o.width,o.height),Math.floor(o.width*t),Math.floor(o.height*t),0,0,o.width,o.height);return o.width=Math.floor(o.width*t),o.height=Math.floor(o.height*t),null===(r=o.getContext("2d"))||void 0===r||r.putImageData(i,0,0),o}const useMask=(e,t)=>{const[a,r]=useImageHook(e.maskSrc,"anonymous"),o=e.maskSrc?r:"loaded";return(0,exports.useImageLoader)(o,e.id+"-mask"),react_1.default.useMemo((()=>{if(!a)return t;if(!t||!t.width||!t.height)return t;const r=createCanvas();r.width=Math.max(t.width,1),r.height=Math.max(t.height,1);const o=r.getContext("2d");if(!o)return t;o.drawImage(t,0,0),o.globalCompositeOperation="source-in";const i=getCrop(a,e);return o.drawImage(a,i.x,i.y,i.width,i.height,0,0,t.width,t.height),r}),[t,a,e.a.width,e.a.height])},useCornerRadiusAndCrop=(e,t,a,r,o=0,i=!1)=>{const n=Math.floor(Math.max(e.a.width*r,1)),h=Math.floor(Math.max(e.a.height*r,1)),d=Math.min(o*r,n/2,h/2),c=Math.max(e.a.width/a.width,e.a.height/a.height)*r,l=e.page._exporting&&flags_1.flags.imageDownScalingEnabled&&c<1&&!i,s=0===a.x&&0===a.y&&a.width===(null==t?void 0:t.width)&&a.height===(null==t?void 0:t.height),u=react_1.default.useMemo((()=>{if(!t||!t.width||!t.height)return;return s&&0===d&&!l?void 0:createCanvas()}),[t,d,l,s]);return react_1.default.useLayoutEffect((()=>{if(!u||!t)return;u.width=n,u.height=h;const e=u.getContext("2d");if(!e)return;d&&(e.beginPath(),e.moveTo(d,0),e.lineTo(n-d,0),e.arc(n-d,d,d,3*Math.PI/2,0,!1),e.lineTo(n,h-d),e.arc(n-d,h-d,d,0,Math.PI/2,!1),e.lineTo(d,h),e.arc(d,h-d,d,Math.PI/2,Math.PI,!1),e.lineTo(0,d),e.arc(d,d,d,Math.PI,3*Math.PI/2,!1),e.clip());const r=l?downScaleCanvas(t,c):t,o=l?{x:Math.floor(a.x*c),y:Math.floor(a.y*c),width:Math.floor(a.width*c),height:Math.floor(a.height*c)}:a;e.drawImage(r,o.x,o.y,o.width,o.height,0,0,u.width,u.height)}),[u,e.a.width,e.a.height,a.x,a.y,a.width,a.height,o,r,i,e.page._exporting,l]),react_1.default.useEffect((()=>()=>{u&&"CANVAS"===u.nodeName&&konva_1.default.Util.releaseCanvas(u)}),[u]),u||t},useClip=(e,t,a,r)=>{const o=useSizeFixer(e.clipSrc||""),[i,n]=useImageHook(o,"anonymous"),h=e.clipSrc?n:"loaded";(0,exports.useImageLoader)(h,e.id+"-clip");const d=react_1.default.useMemo((()=>{if(t&&i)return createCanvas()}),[t,i]);react_1.default.useLayoutEffect((()=>{var r;if(!i)return;if(!t||!t.width||!t.height)return;if(!i||!i.width||!i.height)return;if(!d)return;const o=createCanvas(),n=Math.max(e.a.width/i.width*a,e.a.height/i.height*a);o.width=i.width*n,o.height=i.height*n,null===(r=o.getContext("2d"))||void 0===r||r.drawImage(i,0,0,o.width,o.height),d.width=Math.max(t.width,1),d.height=Math.max(t.height,1);const h=d.getContext("2d");h&&(h.save(),h.drawImage(o,0,0,t.width,t.height),konva_1.default.Util.releaseCanvas(o),h.globalCompositeOperation="source-in",h.drawImage(t,0,0,d.width,d.height),h.restore())}),[d,t,i,e.a.width,e.a.height,a,...r]);return e.clipSrc&&i?d:t},PLACEHOLDER_CANVAS=createCanvas(),LoadingPlaceholder=(0,mobx_react_lite_1.observer)((({element:e})=>{const t=Math.min(30,e.a.width/4,e.a.height/4),a=react_1.default.useRef(null);return react_1.default.useEffect((()=>{const e=a.current;if(!e)return;const t=new konva_1.default.Animation((t=>{e.rotate(((null==t?void 0:t.timeDiff)||0)/2)}),e.getLayer());return t.start(),()=>{t.stop()}})),react_1.default.createElement(react_konva_1.Group,{x:e.x,y:e.y,rotation:e.rotation,listening:!1,opacity:e.a.opacity,hideInExport:!e.showInExport},react_1.default.createElement(react_konva_1.Rect,{width:e.a.width,height:e.a.height,fill:"rgba(124, 173, 212, 0.8)"}),react_1.default.createElement(react_konva_1.Arc,{ref:a,x:e.a.width/2,y:e.a.height/2,fill:"white",outerRadius:Math.abs(t),innerRadius:Math.max(1,t-5),angle:270}))})),ErrorPlaceholder=(0,mobx_react_lite_1.observer)((({element:e})=>{const t="Can not load the image...",a=Math.max(10,Math.min(30,e.a.width/25));return react_1.default.createElement(react_konva_1.Group,{x:e.x,y:e.y,rotation:e.rotation,listening:!1,opacity:e.a.opacity,hideInExport:!e.showInExport},react_1.default.createElement(react_konva_1.Rect,{width:e.a.width,height:e.a.height,fill:"rgba(223, 102, 102, 0.8)"}),react_1.default.createElement(react_konva_1.Text,{text:t,fontSize:a,width:e.a.width,height:e.a.height,align:"center",fill:"white",verticalAlign:"middle",padding:5}))}));let useImageHook=use_image_1.default;const setImageLoaderHook=e=>{useImageHook=e};exports.setImageLoaderHook=setImageLoaderHook;const useImageLoader=(e,t)=>{const a=react_1.default.useRef(),r=()=>{var e;null===(e=a.current)||void 0===e||e.call(a),a.current=void 0};react_1.default.useEffect((()=>r),[]),react_1.default.useLayoutEffect((()=>{"loading"!==e||a.current||(a.current=(0,loader_1.incrementLoader)(`image ${t}`)),"loading"!==e&&r(),"failed"===e&&(0,loader_1.triggerLoadError)(`image ${t}`)}),[e])};exports.useImageLoader=useImageLoader;const usePreviousImage=({image:e,status:t,type:a})=>{const r=react_1.default.useRef();react_1.default.useEffect((()=>{r.current=e||r.current}),[e]);return"failed"!==t||"failed"!==t&&"svg"===a?r.current:void 0},useImageSource=e=>{const[t,a]=react_1.default.useReducer((e=>e+1),0),r=react_1.default.useRef("loading"),o=react_1.default.useRef(e.src),i=react_1.default.useRef(e.src);return i.current!==e.src&&(i.current=e.src,r.current="loading"),react_1.default.useEffect((()=>{if("svg"!==e.type)return;if(!e.src)return;let t=!1;return(async()=>{r.current="loading",a();const i=await svg.urlToString(e.src),n=svg.fixSize(i),h=svg.replaceColors(n,e.colorsReplace);t||(o.current=h,r.current="loaded",a())})(),()=>{t=!0}}),[e.src,JSON.stringify(e.colorsReplace)]),"svg"!==e.type?[e.src,"loaded"]:[o.current,r.current]};exports.ImageElement=(0,mobx_react_lite_1.observer)((({element:e,store:t})=>{var a;const[r,o]=react_1.default.useState(!1),i=react_1.default.useRef(null),n=react_1.default.useRef(null),[h,d]=react_1.default.useState(!1),c=t.selectedElements.indexOf(e)>=0,[l,s]=useImageSource(e),[u,g]=useImageHook(l,"anonymous"),f="svg"!==e.type||"loaded"===s?g:"loading";(0,exports.useImageLoader)(f,e.id);const _=usePreviousImage({image:u,status:g,type:e.type}),m=useMask(e,useFlip(e,u||_,t._elementsPixelRatio))||PLACEHOLDER_CANVAS;let{cropX:p,cropY:w,cropWidth:x,cropHeight:v}=e;"loaded"!==g&&(p=w=0,x=v=1);const M=m.width*x,y=m.height*v,b=e.a.width/e.a.height;let E,k;const I=M/y,C="svg"===e.type;C?(E=M,k=y):b>=I?(E=M,k=M/b):(E=y*b,k=y);const S={x:m.width*p,y:m.height*w,width:E,height:k},R=null!==(a=e.cornerRadius)&&void 0!==a?a:0;let L=useClip(e,useCornerRadiusAndCrop(e,m,S,t._elementsPixelRatio,R,r||e._cropModeEnabled||"svg"===e.type),t._elementsPixelRatio,[S,R,t._elementsPixelRatio]);const O=Math.max(e.a.width/E,e.a.height/k);react_1.default.useEffect((()=>{var t;if(!e._cropModeEnabled)return;const a=null===(t=i.current)||void 0===t?void 0:t.getStage();function r(t){e._cropModeEnabled&&t.target!==n.current&&e.toggleCropMode(!1)}function o(t){e._cropModeEnabled&&t.target.parentNode!==a.content&&e.toggleCropMode(!1)}return document.body.addEventListener("click",o),null==a||a.on("click",r),null==a||a.on("tap",r),()=>{document.body.removeEventListener("click",o),document.body.removeEventListener("touchstart",o),null==a||a.off("click",r),null==a||a.off("click",r)}}),[e._cropModeEnabled]),react_1.default.useLayoutEffect((()=>{if(r||e._cropModeEnabled)return;(0,apply_filters_1.applyFilter)(i.current,e);return(0,mobx_1.autorun)((()=>{(0,apply_filters_1.applyFilter)(i.current,e)}),{delay:100})}),[m,r,x,v,e._cropModeEnabled]),react_1.default.useLayoutEffect((()=>{var t;r||e._cropModeEnabled?null===(t=i.current)||void 0===t||t.clearCache():(0,apply_filters_1.applyFilter)(i.current,e)}),[r,e.a.width,e.a.height,e._cropModeEnabled]),react_1.default.useEffect((()=>{(0,apply_filters_1.applyFilter)(i.current,e)}),[e.shadowEnabled,e.shadowBlur,e.cornerRadius,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]);const P=react_1.default.useRef(null),X=react_1.default.useRef(null),Y=react_1.default.useRef(null);react_1.default.useLayoutEffect((()=>{e._cropModeEnabled&&(X.current.nodes([P.current]),Y.current.nodes([n.current]))}),[e._cropModeEnabled]);const H=t=>{Math.round(t.target.x())>0&&(t.target.x(0),t.target.scaleX(1)),Math.round(t.target.y())>0&&(t.target.y(0),t.target.scaleY(1));const a=t.target.width()*t.target.scaleX(),r=t.target.height()*t.target.scaleY(),o=Math.min(1,E/a),i=Math.min(1,k/r),n=1-o,h=Math.min(n,Math.max(0,Math.round(-t.target.x())/a)),d=1-i,c=Math.min(d,Math.max(0,Math.round(-t.target.y())/r));t.target.setAttrs({x:-h*m.width,y:-c*m.height,scaleX:1,scaleY:1}),e.set({cropX:h,cropY:c,cropWidth:o,cropHeight:i})},A=()=>{"svg"!==e.type&&e.contentEditable&&setTimeout((()=>{e.toggleCropMode(!0)}))},D="svg"===e.type&&_,W="loading"===g&&!D,T="failed"===g,F=!W&&!T,q=react_1.default.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),z=F?e.a.opacity:0;(0,use_fadein_1.useFadeIn)(i,z);const B=e.selectable||"admin"===t.role,N=(0,screen_1.useMobile)();return react_1.default.createElement(react_1.default.Fragment,null,W&&react_1.default.createElement(LoadingPlaceholder,{element:e}),T&&react_1.default.createElement(ErrorPlaceholder,{element:e}),react_1.default.createElement(react_konva_1.Image,{ref:i,name:"element",id:e.id,image:L,x:e.a.x,y:e.a.y,width:e.a.width||1,height:e.a.height||1,rotation:e.rotation,opacity:z,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,customCrop:S,listening:B,draggable:N?e.draggable&&c:e.draggable,preventDefault:!N||c,hideInExport:!e.showInExport,onMouseEnter:()=>{d(!0)},onMouseLeave:()=>{d(!1)},onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDblClick:A,onDblTap:A,onTransformStart:()=>{o(!0),q.current={cropX:e.cropX,cropY:e.cropY,cropWidth:e.cropWidth,cropHeight:e.cropHeight}},onTransform:t=>{var a;const r=t.currentTarget,o=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),i=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const n=null===(a=t.target.getStage())||void 0===a?void 0:a.findOne("Transformer"),h=1-E/m.width,d=Math.min(h,Math.max(0,e.cropX)),c=1-k/m.height,l=Math.min(c,Math.max(0,e.cropY)),s=n.getActiveAnchor(),u=!(s.indexOf("middle")>=0||s.indexOf("center")>=0),g=!u&&o<1&&q.current.cropHeight>k/m.height;let f=u?e.cropWidth:e.cropWidth*o;g&&(f=e.cropWidth);const _=!u&&i<1&&q.current.cropWidth>E/m.width;let p=u?e.cropHeight:e.cropHeight*i;_&&(p=e.cropHeight),C&&(f=e.cropWidth,p=e.cropHeight),e.set({cropX:d,cropY:l,x:r.x(),y:r.y(),width:r.width()*o,height:r.height()*i,rotation:t.target.rotation(),cropWidth:Math.min(f,1-d),cropHeight:Math.min(p,1-l)})},onTransformEnd:t=>{const a=t.currentTarget;e.set({width:a.width(),height:a.height(),x:a.x(),y:a.y(),rotation:t.target.rotation(),cropWidth:E/m.width,cropHeight:k/m.height}),o(!1)}}),react_1.default.createElement(react_konva_1.Rect,{x:e.x,y:e.y,width:Math.max(e.a.width-e.borderSize,0),height:Math.max(e.a.height-e.borderSize,0),opacity:z,offsetX:-e.borderSize/2,offsetY:-e.borderSize/2,stroke:e.borderColor,strokeWidth:e.borderSize,listening:!1,visible:!!e.borderSize,rotation:e.rotation,cornerRadius:Math.max(0,R-e.borderSize),hideInExport:!e.showInExport}),e._cropModeEnabled&&react_1.default.createElement(react_konva_utils_1.Portal,{selector:".page-abs-container",enabled:!0},react_1.default.createElement(react_konva_1.Rect,{x:-window.innerWidth/t.scale,y:-window.innerWidth/t.scale,width:window.innerWidth/t.scale*3,height:window.innerWidth/t.scale*3,fill:"rgba(0,0,0,0.3)"}),react_1.default.createElement(react_konva_1.Image,{listening:!1,image:L,x:e.x,y:e.y,width:e.a.width,height:e.a.height,rotation:e.rotation,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur}),react_1.default.createElement(react_konva_1.Group,{x:e.x,y:e.y,rotation:e.rotation,scaleX:O,scaleY:O},react_1.default.createElement(react_konva_1.Image,{image:m,ref:n,opacity:.4,draggable:!0,x:-e.cropX*m.width,y:-e.cropY*m.height,onDragMove:H,onTransform:H}),react_1.default.createElement(react_konva_1.Transformer,{ref:Y,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),react_1.default.createElement(react_konva_1.Rect,{width:E,height:k,ref:P,listening:!1,onTransform:t=>{t.target.x()<-e.cropX*m.width-1e-9&&(t.target.x(-e.cropX*m.width),t.target.scaleX(1)),t.target.y()<-e.cropY*m.height-1e-9&&(t.target.y(-e.cropY*m.height),t.target.scaleY(1));const a=Math.min(1,Math.max(0,e.cropX+t.target.x()/m.width)),r=Math.min(1,Math.max(0,t.target.y()/m.height+e.cropY)),o=t.target.width()*t.target.scaleX(),i=t.target.height()*t.target.scaleY(),n=Math.min(1-a,o/m.width),h=Math.min(1-r,i/m.height),d=t.target.getAbsolutePosition(t.target.getParent().getParent());t.target.scale({x:1,y:1}),t.target.position({x:0,y:0}),e.set({x:d.x,y:d.y,cropX:a,cropY:r,cropWidth:n,cropHeight:h,width:Math.min(o*O,m.width*(1-a)*O),height:Math.min(i*O,m.height*(1-r)*O)})}}),react_1.default.createElement(react_konva_1.Transformer,{ref:X,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2}))),(h||c)&&react_1.default.createElement(highlighter_1.Highlighter,{element:e}))}));
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,a,r){void 0===r&&(r=a);var o=Object.getOwnPropertyDescriptor(t,a);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[a]}}),Object.defineProperty(e,r,o)}:function(e,t,a,r){void 0===r&&(r=a),e[r]=t[a]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var a in e)"default"!==a&&Object.prototype.hasOwnProperty.call(e,a)&&__createBinding(t,e,a);return __setModuleDefault(t,e),t},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ImageElement=exports.useImageLoader=exports.setImageLoaderHook=void 0;const react_1=__importDefault(require("react")),mobx_react_lite_1=require("mobx-react-lite"),mobx_1=require("mobx"),react_konva_1=require("react-konva"),use_image_1=__importDefault(require("use-image")),konva_1=__importDefault(require("konva")),react_konva_utils_1=require("react-konva-utils"),highlighter_1=require("./highlighter"),loader_1=require("../utils/loader"),svg=__importStar(require("../utils/svg")),flags_1=require("../utils/flags"),apply_filters_1=require("./apply-filters"),use_fadein_1=require("./use-fadein"),screen_1=require("../utils/screen");function createCanvas(){return document.createElement("canvas")}async function getFixedUrl(e){if(!(e.indexOf("data:image/svg+xml")>=0||e.indexOf(".svg")>=0))return e;const t=await svg.urlToString(e),a=svg.fixSize(t);return svg.svgToURL(a)}const useSizeFixer=e=>{const[t,a]=react_1.default.useState(e);return react_1.default.useEffect((()=>{(async()=>{const r=await getFixedUrl(e);r!==t&&a(r)})()}),[e]),t},useFlip=(e,t,a)=>{const r=react_1.default.useMemo((()=>{var r,o;const{flipX:i,flipY:n}=e,h="svg"===e.type||e.src.indexOf("data:image/svg+xml")>=0||e.src.indexOf(".svg")>=0,d=navigator.userAgent.toLowerCase().indexOf("firefox")>-1&&h||e.maskSrc;if(!i&&!n&&!d)return t;if(!t||!t.width||!t.height)return null;const c=createCanvas();let l=1;"svg"===e.type&&(l=Math.max(e.a.width/t.width*a,e.a.height/t.height*a)),c.width=Math.max(t.width*l,1),c.height=Math.max(t.height*l,1);let s=i?-c.width:0,u=n?-c.height:0;return null===(r=c.getContext("2d"))||void 0===r||r.scale(i?-1:1,n?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(t,s,u,c.width,c.height),c}),[e.maskSrc,e.flipX,e.flipY,t,e.a.width,e.a.height,a]);return react_1.default.useEffect((()=>()=>{r&&"CANVAS"===r.nodeName&&konva_1.default.Util.releaseCanvas(r)}),[r]),r};function getCrop(e,t){const a=t.width/t.height;let r,o;a>=e.width/e.height?(r=e.width,o=e.width/a):(r=e.height*a,o=e.height);return{x:(e.width-r)/2,y:(e.height-o)/2,width:r,height:o}}function downsample(e,t,a,r,o,i,n){for(var h=new ImageData(t,a),d=new Int32Array(e.data.buffer),c=e.width,l=new Int32Array(h.data.buffer),s=h.width,u=t/i,g=a/n,f=Math.round(1/u),_=Math.round(1/g),m=f*_,p=0;p<h.height;p++)for(var w=0;w<s;w++){for(var x=r+Math.round(w/u)+(o+Math.round(p/g))*c,v=0,M=0,y=0,b=0,E=0;E<_;E++)for(var k=0;k<f;k++){var I=d[x+k+E*c];v+=I<<24>>>24,M+=I<<16>>>24,y+=I<<8>>>24,b+=I>>>24}v=Math.round(v/m),M=Math.round(M/m),y=Math.round(y/m),b=Math.round(b/m),l[w+p*s]=b<<24|y<<16|M<<8|v}return h}function downScaleCanvas(e,t){var a,r;const o=createCanvas();o.width=e.width,o.height=e.height,null===(a=o.getContext("2d"))||void 0===a||a.drawImage(e,0,0,o.width,o.height);const i=downsample(o.getContext("2d").getImageData(0,0,o.width,o.height),Math.floor(o.width*t),Math.floor(o.height*t),0,0,o.width,o.height);return o.width=Math.floor(o.width*t),o.height=Math.floor(o.height*t),null===(r=o.getContext("2d"))||void 0===r||r.putImageData(i,0,0),o}const useMask=(e,t)=>{const[a,r]=useImageHook(e.maskSrc,"anonymous"),o=e.maskSrc?r:"loaded";return(0,exports.useImageLoader)(o,e.id+"-mask"),react_1.default.useMemo((()=>{if(!a)return t;if(!t||!t.width||!t.height)return t;const r=createCanvas();r.width=Math.max(t.width,1),r.height=Math.max(t.height,1);const o=r.getContext("2d");if(!o)return t;o.drawImage(t,0,0),o.globalCompositeOperation="source-in";const i=getCrop(a,e);return o.drawImage(a,i.x,i.y,i.width,i.height,0,0,t.width,t.height),r}),[t,a,e.a.width,e.a.height])},useCornerRadiusAndCrop=(e,t,a,r,o=0,i=!1)=>{const n=Math.floor(Math.max(e.a.width*r,1)),h=Math.floor(Math.max(e.a.height*r,1)),d=Math.min(o*r,n/2,h/2),c=Math.max(e.a.width/a.width,e.a.height/a.height)*r,l=e.page._exporting&&flags_1.flags.imageDownScalingEnabled&&c<1&&!i,s=0===a.x&&0===a.y&&a.width===(null==t?void 0:t.width)&&a.height===(null==t?void 0:t.height),u=react_1.default.useMemo((()=>{if(!t||!t.width||!t.height)return;return s&&0===d&&!l?void 0:createCanvas()}),[t,d,l,s]);return react_1.default.useLayoutEffect((()=>{if(!u||!t)return;u.width=n,u.height=h;const e=u.getContext("2d");if(!e)return;d&&(e.beginPath(),e.moveTo(d,0),e.lineTo(n-d,0),e.arc(n-d,d,d,3*Math.PI/2,0,!1),e.lineTo(n,h-d),e.arc(n-d,h-d,d,0,Math.PI/2,!1),e.lineTo(d,h),e.arc(d,h-d,d,Math.PI/2,Math.PI,!1),e.lineTo(0,d),e.arc(d,d,d,Math.PI,3*Math.PI/2,!1),e.clip());const r=l?downScaleCanvas(t,c):t,o=l?{x:Math.floor(a.x*c),y:Math.floor(a.y*c),width:Math.floor(a.width*c),height:Math.floor(a.height*c)}:a;e.drawImage(r,o.x,o.y,o.width,o.height,0,0,u.width,u.height)}),[u,e.a.width,e.a.height,a.x,a.y,a.width,a.height,o,r,i,e.page._exporting,l]),react_1.default.useEffect((()=>()=>{u&&"CANVAS"===u.nodeName&&konva_1.default.Util.releaseCanvas(u)}),[u]),u||t},useClip=(e,t,a,r)=>{const o=useSizeFixer(e.clipSrc||""),[i,n]=useImageHook(o,"anonymous"),h=e.clipSrc?n:"loaded";(0,exports.useImageLoader)(h,e.id+"-clip");const d=react_1.default.useMemo((()=>{if(t&&i)return createCanvas()}),[t,i]);react_1.default.useLayoutEffect((()=>{var r;if(!i)return;if(!t||!t.width||!t.height)return;if(!i||!i.width||!i.height)return;if(!d)return;const o=createCanvas(),n=Math.max(e.a.width/i.width*a,e.a.height/i.height*a);o.width=i.width*n,o.height=i.height*n,null===(r=o.getContext("2d"))||void 0===r||r.drawImage(i,0,0,o.width,o.height),d.width=Math.max(t.width,1),d.height=Math.max(t.height,1);const h=d.getContext("2d");h&&(h.save(),h.drawImage(o,0,0,t.width,t.height),konva_1.default.Util.releaseCanvas(o),h.globalCompositeOperation="source-in",h.drawImage(t,0,0,d.width,d.height),h.restore())}),[d,t,i,e.a.width,e.a.height,a,...r]);return e.clipSrc&&i?d:t},PLACEHOLDER_CANVAS=createCanvas(),LoadingPlaceholder=(0,mobx_react_lite_1.observer)((({element:e})=>{const t=Math.min(30,e.a.width/4,e.a.height/4),a=react_1.default.useRef(null);return react_1.default.useEffect((()=>{const e=a.current;if(!e)return;const t=new konva_1.default.Animation((t=>{e.rotate(((null==t?void 0:t.timeDiff)||0)/2)}),e.getLayer());return t.start(),()=>{t.stop()}})),react_1.default.createElement(react_konva_1.Group,{x:e.x,y:e.y,rotation:e.rotation,listening:!1,opacity:e.a.opacity,hideInExport:!e.showInExport},react_1.default.createElement(react_konva_1.Rect,{width:e.a.width,height:e.a.height,fill:"rgba(124, 173, 212, 0.8)"}),react_1.default.createElement(react_konva_1.Arc,{ref:a,x:e.a.width/2,y:e.a.height/2,fill:"white",outerRadius:Math.abs(t),innerRadius:Math.max(1,t-5),angle:270}))})),ErrorPlaceholder=(0,mobx_react_lite_1.observer)((({element:e})=>{const t="Can not load the image...",a=Math.max(10,Math.min(30,e.a.width/25));return react_1.default.createElement(react_konva_1.Group,{x:e.x,y:e.y,rotation:e.rotation,listening:!1,opacity:e.a.opacity,hideInExport:!e.showInExport},react_1.default.createElement(react_konva_1.Rect,{width:e.a.width,height:e.a.height,fill:"rgba(223, 102, 102, 0.8)"}),react_1.default.createElement(react_konva_1.Text,{text:t,fontSize:a,width:e.a.width,height:e.a.height,align:"center",fill:"white",verticalAlign:"middle",padding:5}))}));let useImageHook=use_image_1.default;const setImageLoaderHook=e=>{useImageHook=e};exports.setImageLoaderHook=setImageLoaderHook;const useImageLoader=(e,t)=>{const a=react_1.default.useRef(),r=()=>{var e;null===(e=a.current)||void 0===e||e.call(a),a.current=void 0};react_1.default.useEffect((()=>r),[]),react_1.default.useLayoutEffect((()=>{"loading"!==e||a.current||(a.current=(0,loader_1.incrementLoader)(`image ${t}`)),"loading"!==e&&r(),"failed"===e&&(0,loader_1.triggerLoadError)(`image ${t}`)}),[e])};exports.useImageLoader=useImageLoader;const usePreviousImage=({image:e,status:t,type:a})=>{const r=react_1.default.useRef();react_1.default.useEffect((()=>{r.current=e||r.current}),[e]);return"failed"!==t||"failed"!==t&&"svg"===a?r.current:void 0},useImageSource=e=>{const[t,a]=react_1.default.useReducer((e=>e+1),0),r=react_1.default.useRef("loading"),o=react_1.default.useRef(e.src),i=react_1.default.useRef(e.src);return i.current!==e.src&&(i.current=e.src,r.current="loading"),react_1.default.useEffect((()=>{if("svg"!==e.type)return;if(!e.src)return;let t=!1;return(async()=>{r.current="loading",a();const i=await svg.urlToString(e.src),n=svg.fixSize(i),h=svg.replaceColors(n,e.colorsReplace);t||(o.current=h,r.current="loaded",a())})(),()=>{t=!0}}),[e.src,JSON.stringify(e.colorsReplace)]),"svg"!==e.type?[e.src,"loaded"]:[o.current,r.current]};exports.ImageElement=(0,mobx_react_lite_1.observer)((({element:e,store:t})=>{var a;const[r,o]=react_1.default.useState(!1),i=react_1.default.useRef(null),n=react_1.default.useRef(null),[h,d]=react_1.default.useState(!1),c=t.selectedElements.indexOf(e)>=0,[l,s]=useImageSource(e),[u,g]=useImageHook(l,"anonymous"),f="svg"!==e.type||"loaded"===s?g:"loading";(0,exports.useImageLoader)(f,e.id);const _=usePreviousImage({image:u,status:g,type:e.type}),m=useMask(e,useFlip(e,u||_,t._elementsPixelRatio))||PLACEHOLDER_CANVAS;let{cropX:p,cropY:w,cropWidth:x,cropHeight:v}=e;"loaded"!==g&&(p=w=0,x=v=1);const M=m.width*x,y=m.height*v,b=e.a.width/e.a.height;let E,k;const I=M/y,C="svg"===e.type;C?(E=M,k=y):b>=I?(E=M,k=M/b):(E=y*b,k=y);const S={x:m.width*p,y:m.height*w,width:E,height:k},R=null!==(a=e.cornerRadius)&&void 0!==a?a:0;let L=useClip(e,useCornerRadiusAndCrop(e,m,S,t._elementsPixelRatio,R,r||e._cropModeEnabled||"svg"===e.type),t._elementsPixelRatio,[S,R,t._elementsPixelRatio]);const O=Math.max(e.a.width/E,e.a.height/k);react_1.default.useEffect((()=>{var t;if(!e._cropModeEnabled)return;const a=null===(t=i.current)||void 0===t?void 0:t.getStage();function r(t){e._cropModeEnabled&&t.target!==n.current&&e.toggleCropMode(!1)}function o(t){e._cropModeEnabled&&t.target.parentNode!==a.content&&e.toggleCropMode(!1)}return document.body.addEventListener("click",o),null==a||a.on("click",r),null==a||a.on("tap",r),()=>{document.body.removeEventListener("click",o),document.body.removeEventListener("touchstart",o),null==a||a.off("click",r),null==a||a.off("click",r)}}),[e._cropModeEnabled]),react_1.default.useLayoutEffect((()=>{if(r||e._cropModeEnabled)return;(0,apply_filters_1.applyFilter)(i.current,e);return(0,mobx_1.autorun)((()=>{(0,apply_filters_1.applyFilter)(i.current,e)}),{delay:100})}),[m,r,x,v,e._cropModeEnabled]),react_1.default.useLayoutEffect((()=>{var t;r||e._cropModeEnabled?null===(t=i.current)||void 0===t||t.clearCache():(0,apply_filters_1.applyFilter)(i.current,e)}),[r,e.a.width,e.a.height,e._cropModeEnabled]),react_1.default.useEffect((()=>{(0,apply_filters_1.applyFilter)(i.current,e)}),[e.shadowEnabled,e.shadowBlur,e.cornerRadius,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]);const P=react_1.default.useRef(null),X=react_1.default.useRef(null),Y=react_1.default.useRef(null);react_1.default.useLayoutEffect((()=>{e._cropModeEnabled&&(X.current.nodes([P.current]),Y.current.nodes([n.current]))}),[e._cropModeEnabled]);const H=t=>{Math.round(t.target.x())>0&&(t.target.x(0),t.target.scaleX(1)),Math.round(t.target.y())>0&&(t.target.y(0),t.target.scaleY(1));const a=t.target.width()*t.target.scaleX(),r=t.target.height()*t.target.scaleY(),o=Math.min(1,E/a),i=Math.min(1,k/r),n=1-o,h=Math.min(n,Math.max(0,Math.round(-t.target.x())/a)),d=1-i,c=Math.min(d,Math.max(0,Math.round(-t.target.y())/r));t.target.setAttrs({x:-h*m.width,y:-c*m.height,scaleX:1,scaleY:1}),e.set({cropX:h,cropY:c,cropWidth:o,cropHeight:i})},A=()=>{"svg"!==e.type&&e.contentEditable&&setTimeout((()=>{e.toggleCropMode(!0)}))},D="svg"===e.type&&_,W="loading"===g&&!D,T="failed"===g,F=!W&&!T,q=react_1.default.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),z=F?e.a.opacity:0;(0,use_fadein_1.useFadeIn)(i,z);const B=e.selectable||"admin"===t.role,N=(0,screen_1.useMobile)();return react_1.default.createElement(react_1.default.Fragment,null,W&&react_1.default.createElement(LoadingPlaceholder,{element:e}),T&&react_1.default.createElement(ErrorPlaceholder,{element:e}),react_1.default.createElement(react_konva_1.Image,{ref:i,name:"element",id:e.id,image:L,x:e.a.x,y:e.a.y,width:e.a.width||1,height:e.a.height||1,rotation:e.rotation,opacity:z,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,customCrop:S,listening:B,draggable:N?e.draggable&&c:e.draggable,preventDefault:!N||c,hideInExport:!e.showInExport,onMouseEnter:()=>{d(!0)},onMouseLeave:()=>{d(!1)},onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDblClick:A,onDblTap:A,onTransformStart:()=>{o(!0),q.current={cropX:e.cropX,cropY:e.cropY,cropWidth:e.cropWidth,cropHeight:e.cropHeight}},onTransform:t=>{var a;const r=t.currentTarget,o=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),i=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const n=null===(a=t.target.getStage())||void 0===a?void 0:a.findOne("Transformer"),h=1-E/m.width,d=Math.min(h,Math.max(0,e.cropX)),c=1-k/m.height,l=Math.min(c,Math.max(0,e.cropY)),s=n.getActiveAnchor(),u=!(s.indexOf("middle")>=0||s.indexOf("center")>=0),g=!u&&o<1&&q.current.cropHeight>k/m.height;let f=u?e.cropWidth:e.cropWidth*o;g&&(f=e.cropWidth);const _=!u&&i<1&&q.current.cropWidth>E/m.width;let p=u?e.cropHeight:e.cropHeight*i;_&&(p=e.cropHeight),C&&(f=e.cropWidth,p=e.cropHeight),e.set({cropX:d,cropY:l,x:r.x(),y:r.y(),width:r.width()*o,height:r.height()*i,rotation:t.target.rotation(),cropWidth:Math.min(f,1-d),cropHeight:Math.min(p,1-l)})},onTransformEnd:t=>{const a=t.currentTarget;e.set({width:a.width(),height:a.height(),x:a.x(),y:a.y(),rotation:t.target.rotation(),cropWidth:E/m.width,cropHeight:k/m.height}),o(!1)}}),react_1.default.createElement(react_konva_1.Rect,{x:e.x,y:e.y,width:Math.max(e.a.width-e.borderSize,0),height:Math.max(e.a.height-e.borderSize,0),opacity:z,offsetX:-e.borderSize/2,offsetY:-e.borderSize/2,stroke:e.borderColor,strokeWidth:e.borderSize,listening:!1,visible:!!e.borderSize,rotation:e.rotation,cornerRadius:Math.max(0,R-e.borderSize),hideInExport:!e.showInExport}),e._cropModeEnabled&&react_1.default.createElement(react_konva_utils_1.Portal,{selector:".page-abs-container",enabled:!0},react_1.default.createElement(react_konva_1.Rect,{x:-window.innerWidth/t.scale,y:-window.innerWidth/t.scale,width:window.innerWidth/t.scale*3,height:window.innerWidth/t.scale*3,fill:"rgba(0,0,0,0.3)"}),react_1.default.createElement(react_konva_1.Image,{listening:!1,image:L,x:e.x,y:e.y,width:e.a.width,height:e.a.height,rotation:e.rotation,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur}),react_1.default.createElement(react_konva_1.Group,{x:e.x,y:e.y,rotation:e.rotation,scaleX:O,scaleY:O},react_1.default.createElement(react_konva_1.Image,{image:m,ref:n,opacity:.4,draggable:!0,x:-e.cropX*m.width,y:-e.cropY*m.height,onDragMove:H,onTransform:H}),react_1.default.createElement(react_konva_1.Transformer,{ref:Y,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),react_1.default.createElement(react_konva_1.Rect,{width:E,height:k,ref:P,listening:!1,onTransform:t=>{t.target.x()<-e.cropX*m.width-1e-9&&(t.target.x(-e.cropX*m.width),t.target.scaleX(1)),t.target.y()<-e.cropY*m.height-1e-9&&(t.target.y(-e.cropY*m.height),t.target.scaleY(1));const a=Math.min(1,Math.max(0,e.cropX+t.target.x()/m.width)),r=Math.min(1,Math.max(0,t.target.y()/m.height+e.cropY)),o=t.target.width()*t.target.scaleX(),i=t.target.height()*t.target.scaleY(),n=Math.min(1-a,o/m.width),h=Math.min(1-r,i/m.height),d=t.target.getAbsolutePosition(t.target.getParent().getParent());t.target.scale({x:1,y:1}),t.target.position({x:0,y:0}),e.set({x:d.x,y:d.y,cropX:a,cropY:r,cropWidth:n,cropHeight:h,width:Math.min(o*O,m.width*(1-a)*O),height:Math.min(i*O,m.height*(1-r)*O)})}}),react_1.default.createElement(react_konva_1.Transformer,{ref:X,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,visible:e.resizable,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2}))),(h||c)&&react_1.default.createElement(highlighter_1.Highlighter,{element:e}))}));
@@ -1 +1 @@
1
- "use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkspaceCanvas=void 0;const react_1=__importDefault(require("react")),mobx_react_lite_1=require("mobx-react-lite"),page_1=__importDefault(require("./page")),rules_1=require("./rules"),hotkeys_1=require("./hotkeys"),l10n_1=require("../utils/l10n"),limit=(e,t,r)=>Math.max(t,Math.min(r,e)),ZERO_SIZE_WARNING="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:",useSaveScrollOnScaleChange=(e,t,r,a,n,l)=>{const o=react_1.default.useRef({width:t,height:r}),c=react_1.default.useRef({top:0,left:0}),s=react_1.default.useRef(!1),i=react_1.default.useRef(n.pages.length);s.current=i.current!==n.pages.length,i.current=n.pages.length,react_1.default.useEffect((()=>{const t=e.current,r=e=>{c.current={top:t.scrollTop,left:t.scrollLeft}};return t.addEventListener("scroll",r),()=>{t.removeEventListener("scroll",r)}}),[]),react_1.default.useLayoutEffect((()=>{if(!e.current)return;if(s.current)return;const a=e.current,n=(c.current.left+a.offsetWidth/2)/o.current.width,i=(c.current.top+a.offsetHeight/2)/o.current.height;l.current=!0,a.scrollLeft=n*t-a.offsetWidth/2,a.scrollTop=i*r-a.offsetHeight/2,o.current={width:t,height:r}}),[a,t,r])},useScrollOnActiveChange=(e,t,r,a,n)=>{const l=react_1.default.useRef(!1),o=react_1.default.useRef(null);react_1.default.useEffect((()=>{const t=e.current,r=()=>{n.current};return t.addEventListener("scroll",r),()=>{t.removeEventListener("scroll",r)}}),[]);const c=r.pages.indexOf(r.activePage);react_1.default.useLayoutEffect((()=>{if(!r.activePage)return;if(!e.current)return;if(l.current)return;const a=e.current,o=r.pages.indexOf(r.activePage)*t;Math.abs(o-a.scrollTop)>.5*t&&(n.current=!0,a.scrollTop=o)}),[r.activePage,c]);return{handleScroll:e=>{if(n.current)return void(n.current=!1);l.current=!0,clearTimeout(o.current),o.current=setTimeout((()=>{l.current=!1}),300);const t=e.currentTarget.childNodes[0].offsetHeight,c=e.currentTarget.scrollTop,s=Math.floor((c+a.height/3)/t),i=r.pages[s];i&&i.select()}}},NoPages=({store:e})=>react_1.default.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},react_1.default.createElement("p",null,(0,l10n_1.t)("workspace.noPages")),react_1.default.createElement("button",{onClick:()=>{e.addPage()}},(0,l10n_1.t)("workspace.addPage"))),PagePlaceholder=({width:e,height:t,xPadding:r,yPadding:a,backgroundColor:n})=>react_1.default.createElement("div",{style:{width:e+"px",height:t+"px",backgroundColor:n,paddingLeft:r+"px",paddingRight:r+"px",paddingTop:a+"px",paddingBottom:a+"px"}},react_1.default.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}}));exports.WorkspaceCanvas=(0,mobx_react_lite_1.observer)((({store:e,pageControlsEnabled:t,backgroundColor:r,pageBorderColor:a,activePageBorderColor:n,bleedColor:l,components:o,onKeyDown:c,paddingX:s,paddingY:i})=>{const u=null!=s?s:20,d=null!=i?i:55,[h,g]=react_1.default.useState({width:100,height:100}),f=react_1.default.useRef(h),p=react_1.default.useRef(null),_=react_1.default.useRef(null),m=e.bleedVisible?Math.max(0,...e.pages.map((e=>e.bleed))):0,v=Math.max(...e.pages.map((e=>e.computedWidth))),w=Math.max(...e.pages.map((e=>e.computedHeight))),b=v+2*m,x=w+2*m,E=()=>{if(null===p.current)return;const t=p.current.getBoundingClientRect();0!==t.width&&0!==t.height||(console.warn(ZERO_SIZE_WARNING),console.log(p.current));const r=_.current.clientWidth||t.width,a={width:r,height:t.height};(f.current.width!==a.width||f.current.height!==a.height)&&(g(a),f.current=a);const n=(r-2*u)/b,l=(t.height-2*d)/x,o=Math.max(Math.min(n,l),.01);e.scaleToFit!==o&&(e.setScale(o),e._setScaleToFit(o))};react_1.default.useEffect(E,[b,x]),react_1.default.useEffect((()=>{const e=p.current;if(window.ResizeObserver){const t=new ResizeObserver(E);return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(E,100);return()=>clearInterval(e)}}),[b,x]);const y=Math.max(u,(h.width-b*e.scale)/2),P=x*e.scale*e.pages.length,k=Math.max(d,(h.height-P)/e.pages.length/2);react_1.default.useEffect((()=>{const t=t=>{(c||hotkeys_1.handleHotkey)(t,e)};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)}),[]),react_1.default.useEffect((()=>{var t;const r=t=>{if(t.ctrlKey||t.metaKey){t.preventDefault();const l=Math.max(3,e.scaleToFit),o=Math.min(.1,e.scaleToFit),c=(r=t.deltaY<0?1.05*e.scale:e.scale/1.05,a=o,n=l,Math.max(a,Math.min(n,r)));e.setScale(c)}else var r,a,n};return null===(t=_.current)||void 0===t||t.addEventListener("wheel",r),()=>{var e;return null===(e=_.current)||void 0===e?void 0:e.removeEventListener("wheel",r)}}),[]);const C=react_1.default.useRef(!1);useSaveScrollOnScaleChange(_,b*e.scale+2*y,x*e.scale+2*k,e.scale,e,C);const{handleScroll:R}=useScrollOnActiveChange(_,x*e.scale+2*k,e,h,C),M=h.width>=b*e.scale+2*y,S=r||"rgba(232, 232, 232, 0.9)",T=e.pages.indexOf(e.activePage),L=(null==o?void 0:o.NoPages)||NoPages;return react_1.default.createElement("div",{ref:p,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:S},tabIndex:0,className:"polotno-workspace-container"},react_1.default.createElement("div",{ref:_,onScroll:R,style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",overflow:"auto",overflowX:M?"hidden":"auto"},className:"polotno-workspace-inner"},e.pages.map(((r,c)=>Math.abs(c-T)<=1||r._exporting?react_1.default.createElement(page_1.default,{key:r.id,page:r,xPadding:y,yPadding:k,width:b*e.scale+2*y,height:x*e.scale+2*k,store:e,pageControlsEnabled:t,backColor:S,pageBorderColor:a||"lightgrey",activePageBorderColor:n||"rgb(0, 161, 255)",bleedColor:l||"rgba(255, 0, 0, 0.1)",components:o}):react_1.default.createElement(PagePlaceholder,{key:r.id,width:b*e.scale+2*y,height:x*e.scale+2*k,backgroundColor:S,xPadding:y,yPadding:k}))),e.rulesVisible&&react_1.default.createElement(rules_1.TopRules,{store:e,xPadding:y,yPadding:k,width:b*e.scale+2*y,height:x*e.scale+2*k}),0===e.pages.length&&react_1.default.createElement(L,{store:e})))})),exports.default=exports.WorkspaceCanvas;
1
+ "use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkspaceCanvas=void 0;const react_1=__importDefault(require("react")),mobx_react_lite_1=require("mobx-react-lite"),page_1=__importDefault(require("./page")),rules_1=require("./rules"),hotkeys_1=require("./hotkeys"),l10n_1=require("../utils/l10n"),limit=(e,t,r)=>Math.max(t,Math.min(r,e)),ZERO_SIZE_WARNING="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:",useSaveScrollOnScaleChange=(e,t,r,a,n,l)=>{const o=react_1.default.useRef({width:t,height:r}),c=react_1.default.useRef({top:0,left:0}),s=react_1.default.useRef(!1),i=react_1.default.useRef(n.pages.length);s.current=i.current!==n.pages.length,i.current=n.pages.length,react_1.default.useEffect((()=>{const t=e.current,r=e=>{c.current={top:t.scrollTop,left:t.scrollLeft}};return t.addEventListener("scroll",r),()=>{t.removeEventListener("scroll",r)}}),[]),react_1.default.useLayoutEffect((()=>{if(!e.current)return;if(s.current)return;const a=e.current,n=(c.current.left+a.offsetWidth/2)/o.current.width,i=(c.current.top+a.offsetHeight/2)/o.current.height;l.current=!0,a.scrollLeft=n*t-a.offsetWidth/2,a.scrollTop=i*r-a.offsetHeight/2,o.current={width:t,height:r}}),[a,t,r])},useScrollOnActiveChange=(e,t,r,a,n)=>{const l=react_1.default.useRef(!1),o=react_1.default.useRef(null);react_1.default.useEffect((()=>{const t=e.current,r=()=>{n.current};return t.addEventListener("scroll",r),()=>{t.removeEventListener("scroll",r)}}),[]);const c=r.pages.indexOf(r.activePage);react_1.default.useLayoutEffect((()=>{if(!r.activePage)return;if(!e.current)return;if(l.current)return;const a=e.current,o=r.pages.indexOf(r.activePage)*t;Math.abs(o-a.scrollTop)>.5*t&&(n.current=!0,a.scrollTop=o)}),[r.activePage,c]);return{handleScroll:e=>{if(n.current)return void(n.current=!1);l.current=!0,clearTimeout(o.current),o.current=setTimeout((()=>{l.current=!1}),300);const t=e.currentTarget.childNodes[0].offsetHeight,c=e.currentTarget.scrollTop,s=Math.floor((c+a.height/3)/t),i=r.pages[s];i&&i.select()}}},NoPages=({store:e})=>react_1.default.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},react_1.default.createElement("p",null,(0,l10n_1.t)("workspace.noPages")),react_1.default.createElement("button",{onClick:()=>{e.addPage()}},(0,l10n_1.t)("workspace.addPage"))),PagePlaceholder=({width:e,height:t,xPadding:r,yPadding:a,backgroundColor:n})=>react_1.default.createElement("div",{style:{width:e+"px",height:t+"px",backgroundColor:n,paddingLeft:r+"px",paddingRight:r+"px",paddingTop:a+"px",paddingBottom:a+"px"}},react_1.default.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}}));exports.WorkspaceCanvas=(0,mobx_react_lite_1.observer)((({store:e,pageControlsEnabled:t,backgroundColor:r,pageBorderColor:a,activePageBorderColor:n,bleedColor:l,components:o,onKeyDown:c,paddingX:s,paddingY:i})=>{const u=null!=s?s:20,d=null!=i?i:55,[h,g]=react_1.default.useState({width:100,height:100}),f=react_1.default.useRef(h),p=react_1.default.useRef(null),_=react_1.default.useRef(null),m=e.bleedVisible?Math.max(0,...e.pages.map((e=>e.bleed))):0,v=Math.max(...e.pages.map((e=>e.computedWidth))),w=Math.max(...e.pages.map((e=>e.computedHeight))),b=v+2*m,x=w+2*m,E=async()=>{if(await new Promise((e=>setTimeout(e,50))),null===p.current)return;const t=p.current.getBoundingClientRect();0!==t.width&&0!==t.height||(console.warn(ZERO_SIZE_WARNING),console.log(p.current));const r=_.current.clientWidth||t.width,a={width:r,height:t.height};(f.current.width!==a.width||f.current.height!==a.height)&&(g(a),f.current=a);const n=(r-2*u)/b,l=(t.height-2*d)/x,o=Math.max(Math.min(n,l),.01);e.scaleToFit!==o&&(e.setScale(o),e._setScaleToFit(o))};react_1.default.useEffect((()=>{E()}),[b,x]),react_1.default.useEffect((()=>{const e=p.current;if(window.ResizeObserver){const t=new ResizeObserver(E);return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(E,100);return()=>clearInterval(e)}}),[b,x]);const y=Math.max(u,(h.width-b*e.scale)/2),P=x*e.scale*e.pages.length,k=Math.max(d,(h.height-P)/e.pages.length/2);react_1.default.useEffect((()=>{const t=t=>{(c||hotkeys_1.handleHotkey)(t,e)};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)}),[]),react_1.default.useEffect((()=>{var t;const r=t=>{if(t.ctrlKey||t.metaKey){t.preventDefault();const l=Math.max(3,e.scaleToFit),o=Math.min(.1,e.scaleToFit),c=(r=t.deltaY<0?1.05*e.scale:e.scale/1.05,a=o,n=l,Math.max(a,Math.min(n,r)));e.setScale(c)}else var r,a,n};return null===(t=_.current)||void 0===t||t.addEventListener("wheel",r),()=>{var e;return null===(e=_.current)||void 0===e?void 0:e.removeEventListener("wheel",r)}}),[]);const C=react_1.default.useRef(!1);useSaveScrollOnScaleChange(_,b*e.scale+2*y,x*e.scale+2*k,e.scale,e,C);const{handleScroll:R}=useScrollOnActiveChange(_,x*e.scale+2*k,e,h,C),M=h.width>=b*e.scale+2*y,S=r||"rgba(232, 232, 232, 0.9)",T=e.pages.indexOf(e.activePage),L=(null==o?void 0:o.NoPages)||NoPages;return react_1.default.createElement("div",{ref:p,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:S},tabIndex:0,className:"polotno-workspace-container"},react_1.default.createElement("div",{ref:_,onScroll:R,style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",overflow:"auto",overflowX:M?"hidden":"auto"},className:"polotno-workspace-inner"},e.pages.map(((r,c)=>Math.abs(c-T)<=1||r._exporting?react_1.default.createElement(page_1.default,{key:r.id,page:r,xPadding:y,yPadding:k,width:b*e.scale+2*y,height:x*e.scale+2*k,store:e,pageControlsEnabled:t,backColor:S,pageBorderColor:a||"lightgrey",activePageBorderColor:n||"rgb(0, 161, 255)",bleedColor:l||"rgba(255, 0, 0, 0.1)",components:o}):react_1.default.createElement(PagePlaceholder,{key:r.id,width:b*e.scale+2*y,height:x*e.scale+2*k,backgroundColor:S,xPadding:y,yPadding:k}))),e.rulesVisible&&react_1.default.createElement(rules_1.TopRules,{store:e,xPadding:y,yPadding:k,width:b*e.scale+2*y,height:x*e.scale+2*k}),0===e.pages.length&&react_1.default.createElement(L,{store:e})))})),exports.default=exports.WorkspaceCanvas;
@@ -1 +1 @@
1
- "use strict";var __rest=this&&this.__rest||function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var l=0;for(o=Object.getOwnPropertySymbols(e);l<o.length;l++)t.indexOf(o[l])<0&&Object.prototype.propertyIsEnumerable.call(e,o[l])&&(r[o[l]]=e[o[l]])}return r};Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerShapeModel=exports.TYPES_MAP=exports.GroupElement=exports.ElementTypes=exports.forEveryChild=void 0;const mobx_state_tree_1=require("mobx-state-tree"),node_model_1=require("./node-model"),shape_model_1=require("./shape-model"),text_model_1=require("./text-model"),image_model_1=require("./image-model"),video_model_1=require("./video-model"),line_model_1=require("./line-model"),svg_model_1=require("./svg-model"),figure_model_1=require("./figure-model"),forEveryChild=(e,t)=>{e.children&&e.children.forEach((e=>{t(e),(0,exports.forEveryChild)(e,t)}))};exports.forEveryChild=forEveryChild;const additionalTypesUnion=[...new Array(20)].map(((e,t)=>mobx_state_tree_1.types.late((()=>ADDITIONAL_TYPES[t]))));exports.ElementTypes=mobx_state_tree_1.types.union({dispatcher:e=>{const t=exports.TYPES_MAP[e.type];if(!t)throw new Error(`Unknown element type: "${e.type}"`);return t}},svg_model_1.SVGElement,text_model_1.TextElement,image_model_1.ImageElement,line_model_1.LineElement,video_model_1.VideoElement,figure_model_1.FigureElement,mobx_state_tree_1.types.late((()=>exports.GroupElement)),...additionalTypesUnion),exports.GroupElement=node_model_1.Node.named("Group").props({type:"group",children:mobx_state_tree_1.types.array(exports.ElementTypes)}).views((e=>({get draggable(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.draggable||(t=!1)})),t},get resizable(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.resizable||(t=!1)})),t},get contentEditable(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.contentEditable||(t=!1)})),t},get styleEditable(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.styleEditable||(t=!1)})),t},get locked(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.locked||(t=!1)})),t}}))).actions((e=>({set(t){var{draggable:r,contentEditable:o,styleEditable:l,resizable:i}=t,s=__rest(t,["draggable","contentEditable","styleEditable","resizable"]);void 0!==r&&(0,exports.forEveryChild)(e,(e=>{e.set({draggable:r})})),void 0!==o&&(0,exports.forEveryChild)(e,(e=>{e.set({contentEditable:o})})),void 0!==l&&(0,exports.forEveryChild)(e,(e=>{e.set({styleEditable:l})})),void 0!==i&&(0,exports.forEveryChild)(e,(e=>{e.set({resizable:i})})),Object.assign(e,s)}})));const ADDITIONAL_TYPES=[];function registerShapeModel(e,t){const r=e.type;if(!r)throw new Error('You must pass "type" attribute to custom model.');let o=shape_model_1.Shape.named(r).props(e);t&&(o=t(o)),exports.TYPES_MAP[r]=o,ADDITIONAL_TYPES.push(o)}exports.TYPES_MAP={svg:svg_model_1.SVGElement,text:text_model_1.TextElement,image:image_model_1.ImageElement,group:exports.GroupElement,line:line_model_1.LineElement,video:video_model_1.VideoElement,figure:figure_model_1.FigureElement},exports.registerShapeModel=registerShapeModel;
1
+ "use strict";var __rest=this&&this.__rest||function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var l=0;for(o=Object.getOwnPropertySymbols(e);l<o.length;l++)t.indexOf(o[l])<0&&Object.prototype.propertyIsEnumerable.call(e,o[l])&&(r[o[l]]=e[o[l]])}return r};Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerShapeModel=exports.TYPES_MAP=exports.GroupElement=exports.ElementTypes=exports.forEveryChild=void 0;const mobx_state_tree_1=require("mobx-state-tree"),node_model_1=require("./node-model"),shape_model_1=require("./shape-model"),text_model_1=require("./text-model"),image_model_1=require("./image-model"),video_model_1=require("./video-model"),line_model_1=require("./line-model"),svg_model_1=require("./svg-model"),figure_model_1=require("./figure-model"),forEveryChild=(e,t)=>{if(e.children)for(const r of e.children){if(t(r))break;(0,exports.forEveryChild)(r,t)}};exports.forEveryChild=forEveryChild;const additionalTypesUnion=[...new Array(20)].map(((e,t)=>mobx_state_tree_1.types.late((()=>ADDITIONAL_TYPES[t]))));exports.ElementTypes=mobx_state_tree_1.types.union({dispatcher:e=>{const t=exports.TYPES_MAP[e.type];if(!t)throw new Error(`Unknown element type: "${e.type}"`);return t}},svg_model_1.SVGElement,text_model_1.TextElement,image_model_1.ImageElement,line_model_1.LineElement,video_model_1.VideoElement,figure_model_1.FigureElement,mobx_state_tree_1.types.late((()=>exports.GroupElement)),...additionalTypesUnion),exports.GroupElement=node_model_1.Node.named("Group").props({type:"group",children:mobx_state_tree_1.types.array(exports.ElementTypes)}).views((e=>({get draggable(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.draggable||(t=!1)})),t},get resizable(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.resizable||(t=!1)})),t},get contentEditable(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.contentEditable||(t=!1)})),t},get styleEditable(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.styleEditable||(t=!1)})),t},get locked(){let t=!0;return(0,exports.forEveryChild)(e,(e=>{e.locked||(t=!1)})),t}}))).actions((e=>({set(t){var{draggable:r,contentEditable:o,styleEditable:l,resizable:i}=t,s=__rest(t,["draggable","contentEditable","styleEditable","resizable"]);void 0!==r&&(0,exports.forEveryChild)(e,(e=>{e.set({draggable:r})})),void 0!==o&&(0,exports.forEveryChild)(e,(e=>{e.set({contentEditable:o})})),void 0!==l&&(0,exports.forEveryChild)(e,(e=>{e.set({styleEditable:l})})),void 0!==i&&(0,exports.forEveryChild)(e,(e=>{e.set({resizable:i})})),Object.assign(e,s)}})));const ADDITIONAL_TYPES=[];function registerShapeModel(e,t){const r=e.type;if(!r)throw new Error('You must pass "type" attribute to custom model.');let o=shape_model_1.Shape.named(r).props(e);t&&(o=t(o)),exports.TYPES_MAP[r]=o,ADDITIONAL_TYPES.push(o)}exports.TYPES_MAP={svg:svg_model_1.SVGElement,text:text_model_1.TextElement,image:image_model_1.ImageElement,group:exports.GroupElement,line:line_model_1.LineElement,video:video_model_1.VideoElement,figure:figure_model_1.FigureElement},exports.registerShapeModel=registerShapeModel;
package/model/history.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.UndoManager=void 0;const mobx_state_tree_1=require("mobx-state-tree"),deep_equal_1=require("../utils/deep-equal");Object.assign(mobx_state_tree_1.types),exports.UndoManager=mobx_state_tree_1.types.model("UndoManager",{history:mobx_state_tree_1.types.array(mobx_state_tree_1.types.frozen()),undoIdx:-1,targetPath:""}).views((e=>({get canUndo(){return e.undoIdx>0},get canRedo(){return e.undoIdx<e.history.length-1}}))).actions((e=>{let t,o,a=!1,r=null,n=0,s=0;const d=()=>s>0;function i(){const e=(0,mobx_state_tree_1.getSnapshot)(t);return{pages:e.pages,width:e.width,height:e.height}}function h(e){(0,mobx_state_tree_1.applySnapshot)(t.pages,e.pages),t.setSize(e.width,e.height)}return{startTransaction(){s++},endTransaction(e){s--,e||this.requestAddState(i())},async ignore(t,o=!1,a=!1){a&&await new Promise((e=>setTimeout(e,10))),n&&e.addUndoState();let r=d();e.startTransaction();let i=s;try{await t()}catch(e){setTimeout((()=>{throw e}))}const h=i!==s,u=!h;e.endTransaction(u),o||r||e.replaceState(),h||(clearTimeout(n),n=0)},async transaction(t){await e.ignore(t,!0),this.addUndoState()},requestAddState(e){r=e,n||d()||(a?a=!1:n=setTimeout((()=>{n=0,clearTimeout(n),d()||this.addUndoState()}),100))},addUndoState(){if(a)return void(a=!1);const t=e.history[e.undoIdx];!(0,deep_equal_1.deepEqual)(r,t)&&(clearTimeout(n),n=0,e.history.splice(e.undoIdx+1),e.history.push(r),e.undoIdx=e.history.length-1)},afterCreate(){if(t=(0,mobx_state_tree_1.resolvePath)(e,".."),!t)throw new Error("Failed to find target store for UndoManager. Please provide `targetPath` property, or a `targetStore` in the environment");o=(0,mobx_state_tree_1.onSnapshot)(t,(()=>{this.requestAddState(i())})),0===e.history.length&&this.requestAddState(i())},clear(){clearTimeout(n),n=0,e.history.splice(0,e.history.length),e.undoIdx=-1,e.addUndoState(i())},beforeDestroy(){o()},undo(){n&&this.addUndoState(),e.canUndo?(e.undoIdx--,a=!0,h(e.history[e.undoIdx])):console.warn("No undo history. Please check `store.history.canUndo` before calling undo action.")},redo(){n&&this.addUndoState(),e.canRedo?(e.undoIdx++,a=!0,h(e.history[e.undoIdx])):console.warn("No redo history. Please check `store.history.canRedo` before calling redo action.")},replaceState(){e.history[e.undoIdx]=i()}}})),exports.default=exports.UndoManager;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.UndoManager=void 0;const mobx_state_tree_1=require("mobx-state-tree"),deep_equal_1=require("../utils/deep-equal");Object.assign(mobx_state_tree_1.types),exports.UndoManager=mobx_state_tree_1.types.model("UndoManager",{history:mobx_state_tree_1.types.array(mobx_state_tree_1.types.frozen()),undoIdx:-1,targetPath:""}).views((e=>({get canUndo(){return e.undoIdx>0},get canRedo(){return e.undoIdx<e.history.length-1}}))).actions((e=>{let t,o,a=!1,r=null,n=0,s=0;const d=()=>s>0;function i(){const e=(0,mobx_state_tree_1.getSnapshot)(t);return{pages:e.pages,width:e.width,height:e.height}}function h(e){const o=t.pages.map((e=>e.id)),a=e.pages.map((e=>e.id));!(0,deep_equal_1.deepEqual)(o,a)?(0,mobx_state_tree_1.applySnapshot)(t.pages,e.pages):t.pages.forEach(((t,o)=>{(0,mobx_state_tree_1.applySnapshot)(t,e.pages[o])})),t.setSize(e.width,e.height)}return{startTransaction(){s++},endTransaction(e){s--,e||this.requestAddState(i())},async ignore(t,o=!1,a=!1){a&&await new Promise((e=>setTimeout(e,10))),n&&e.addUndoState();let r=d();e.startTransaction();let i=s;try{await t()}catch(e){setTimeout((()=>{throw e}))}const h=i!==s,u=!h;e.endTransaction(u),o||r||e.replaceState(),h||(clearTimeout(n),n=0)},async transaction(t){await e.ignore(t,!0),this.addUndoState()},requestAddState(e){r=e,n||d()||(a?a=!1:n=setTimeout((()=>{n=0,clearTimeout(n),d()||this.addUndoState()}),100))},addUndoState(){if(a)return void(a=!1);const t=e.history[e.undoIdx];!(0,deep_equal_1.deepEqual)(r,t)&&(clearTimeout(n),n=0,e.history.splice(e.undoIdx+1),e.history.push(r),e.undoIdx=e.history.length-1)},afterCreate(){if(t=(0,mobx_state_tree_1.resolvePath)(e,".."),!t)throw new Error("Failed to find target store for UndoManager. Please provide `targetPath` property, or a `targetStore` in the environment");o=(0,mobx_state_tree_1.onSnapshot)(t,(()=>{this.requestAddState(i())})),0===e.history.length&&this.requestAddState(i())},clear(){clearTimeout(n),n=0,e.history.splice(0,e.history.length),e.undoIdx=-1,e.addUndoState(i())},beforeDestroy(){o()},undo(){n&&this.addUndoState(),e.canUndo?(e.undoIdx--,a=!0,h(e.history[e.undoIdx])):console.warn("No undo history. Please check `store.history.canUndo` before calling undo action.")},redo(){n&&this.addUndoState(),e.canRedo?(e.undoIdx++,a=!0,h(e.history[e.undoIdx])):console.warn("No redo history. Please check `store.history.canRedo` before calling redo action.")},replaceState(){e.history[e.undoIdx]=i()}}})),exports.default=exports.UndoManager;
package/model/store.js CHANGED
@@ -1 +1 @@
1
- "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,a,i){void 0===i&&(i=a);var o=Object.getOwnPropertyDescriptor(t,a);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[a]}}),Object.defineProperty(e,i,o)}:function(e,t,a,i){void 0===i&&(i=a),e[i]=t[a]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var a in e)"default"!==a&&Object.prototype.hasOwnProperty.call(e,a)&&__createBinding(t,e,a);return __setModuleDefault(t,e),t},__rest=this&&this.__rest||function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(a[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])&&(a[i[o]]=e[i[o]])}return a},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.createStore=exports.Store=exports.Font=void 0;const mobx_state_tree_1=require("mobx-state-tree"),history_1=require("./history"),nanoid_1=require("nanoid"),konva_1=__importDefault(require("konva")),download_1=require("../utils/download"),pdf_1=require("../utils/pdf"),gif_lib_1=require("../utils/gif-lib"),validate_key_1=require("../utils/validate-key"),fonts=__importStar(require("../utils/fonts")),loader_1=require("../utils/loader"),unit_1=require("../utils/unit"),deep_equal_1=require("../utils/deep-equal"),wait_1=require("../utils/wait"),html_1=require("../utils/html"),to_svg_1=require("../utils/to-svg"),page_model_1=require("./page-model"),group_model_1=require("./group-model");function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){const a=exports.Store.create();return(0,validate_key_1.validateKey)(e,t),a}(0,mobx_state_tree_1.setLivelinessChecking)("ignore"),exports.Font=mobx_state_tree_1.types.model("Font",{fontFamily:mobx_state_tree_1.types.string,url:mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string,""),styles:mobx_state_tree_1.types.frozen()}).preProcessSnapshot((e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}))),exports.Store=mobx_state_tree_1.types.model("Store",{role:"",pages:mobx_state_tree_1.types.array(page_model_1.Page),fonts:mobx_state_tree_1.types.array(exports.Font),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:"px",dpi:72,bleedVisible:!1,rulesVisible:!1,openedSidePanel:"",selectedElementsIds:mobx_state_tree_1.types.array(mobx_state_tree_1.types.string),animatedElementsIds:mobx_state_tree_1.types.array(mobx_state_tree_1.types.string),history:mobx_state_tree_1.types.optional(history_1.UndoManager,{targetPath:"../pages"}),_elementsPixelRatio:2,_activePageId:""}).views((e=>({get _bleedVisible(){return console.warn("store._bleedVisible is deprecated. Please use store.bleedVisible instead."),e.bleedVisible},get selectedElements(){return e.selectedElementsIds.map((t=>{for(const a of e.pages)for(const e of a.children)if(e.id===t)return e})).filter((e=>!!e))},get children(){return e.pages},get selectedShapes(){const t=[];return e.selectedElementsIds.forEach((a=>{for(const i of e.pages)for(const e of i.children)e.id===a&&"group"!==e.type&&t.push(e),"group"===e.type&&e.id===a&&t.push(...e.children)})),t},get activePage(){return e.pages.slice().find((t=>t.id===e._activePageId))||(e.pages.length?e.pages[0]:null)},get duration(){let t=0;return e.pages.forEach((e=>{t+=e.duration})),t}}))).actions((e=>{let t=0;return{afterCreate(){e.history.canUndo},setCurrentTime(t){e.currentTime=t},play({animatedElementsIds:a=[],currentTime:i=0}={}){e.animatedElementsIds=(0,mobx_state_tree_1.cast)(a),e.currentTime=i,e.isPlaying=!0,t=Date.now(),requestAnimationFrame(e.seek)},seek(){if(!e.isPlaying)return;const a=Date.now(),i=a-t;t=a,e.currentTime+=i;let o=0;for(const t of e.pages){if(e.currentTime>=t.startTime&&e.currentTime<t.startTime+t.duration){e.selectPage(t.id);break}o+=t.duration}e.isPlaying&&e.currentTime<e.duration?requestAnimationFrame(e.seek):e.stop()},stop(){e.isPlaying=!1,e.currentTime=0,e.animatedElementsIds=(0,mobx_state_tree_1.cast)([])}}})).actions((e=>({setUnit({unit:t,dpi:a}){e.unit=t||e.unit,e.dpi=a||e.dpi},setRole(t){e.role=t},find(t){let a;return(0,group_model_1.forEveryChild)({children:e.pages},(e=>{!a&&t(e)&&(a=e)})),a},getElementById:t=>e.find((e=>e.id===t)),addPage(t){const a=page_model_1.Page.create(Object.assign({id:(0,nanoid_1.nanoid)(10)},t));return e.pages.push(a),e._activePageId=a.id,a},selectPage(t){e._activePageId=t},selectElements(t){const a=t.map((t=>e.getElementById(t))).sort(((e,t)=>e.page.children.indexOf(e)-e.page.children.indexOf(t))).filter((e=>!!e)).map((e=>e.id));e.selectedElementsIds=(0,mobx_state_tree_1.cast)(a)},toggleBleed(t){e.bleedVisible=null!=t?t:!e.bleedVisible},toggleRulers(t){e.rulesVisible=null!=t?t:!e.rulesVisible},openSidePanel(t){e.openedSidePanel=t},setScale(t){e.scale=t},_setScaleToFit(t){e.scaleToFit=t},setElementsPixelRatio(t){e._elementsPixelRatio=t},setSize(t,a,i){e.pages.forEach((e=>{e.setSize({width:t,height:a,useMagic:i,softChange:!0})})),e.width=t,e.height=a},setPageZIndex(t,a){const i=e.pages.find((e=>e.id===t));i&&((0,mobx_state_tree_1.detach)(i),e.pages.remove(i),e.pages.splice(a,0,i))},deletePages(t){const a=e.pages.indexOf(e.activePage);t.forEach((t=>{const a=e.pages.find((e=>e.id===t));(0,mobx_state_tree_1.destroy)(a)}));const i=Math.min(e.pages.length-1,a),o=e.pages[i];o&&(e._activePageId=o.id),e.selectedElementsIds=(0,mobx_state_tree_1.cast)(e.selectedElementsIds.filter((t=>e.getElementById(t))))},groupElements(t){const a=t.map((t=>e.getElementById(t)));a.forEach((e=>{e&&(0,mobx_state_tree_1.detach)(e)}));const i=e.activePage,o={id:(0,nanoid_1.nanoid)(10),children:a,type:"group"};return i.children.push(o),e.selectedElementsIds=(0,mobx_state_tree_1.cast)([o.id]),o},ungroupElements(t){const a=t.map((t=>e.getElementById(t))),i=[];a.forEach((e=>{if(e&&"group"===e.type){const t=e.page,a=t.children.indexOf(e);e.children.forEach((e=>{i.push(e.id)})),e.children.forEach((e=>{(0,mobx_state_tree_1.detach)(e),t.children.push(e)})),t.children.splice(a,1)}})),e.selectedElementsIds=(0,mobx_state_tree_1.cast)(i)},deleteElements(t){t.forEach((t=>{e.pages.forEach((e=>{const a=e.children.find((e=>e.id===t));a&&(0,mobx_state_tree_1.destroy)(a)}))})),e.selectedElementsIds=(0,mobx_state_tree_1.cast)(e.selectedElementsIds.filter((t=>e.getElementById(t))))},on(t,a){if("change"===t){let t=e.toJSON();return(0,mobx_state_tree_1.onSnapshot)(e,(i=>{const o=e.toJSON();!(0,deep_equal_1.deepEqual)(t,o)&&(t=o,a(o))}))}},async _toCanvas({pixelRatio:t,ignoreBackground:a,pageId:i,mimeType:o,includeBleed:n}={}){var s;const r=t||1;i=i||(null===(s=e.pages[0])||void 0===s?void 0:s.id);const l=e.pages.find((e=>e.id===i));if(!l)throw new Error(`No page for export with id ${i}`);null==l||l.set({_exporting:!0});const d=await(0,wait_1.waitTillAvailable)((()=>konva_1.default.stages.find((e=>e.getAttr("pageId")===i))));if(!d)throw new Error(`Export is failed. Can not find stage for page ${i}. Looks like <Workspace /> component is not mounted, but it is required in order to process the export.`);const c=!!d.findOne(".page-container");await e.waitLoading();const p=d.findOne(".page-container");if(!p)throw new Error(`Export is failed. Can't find page container. ${c}`);d.find("Transformer").forEach((e=>e.visible(!1))),p.find(".page-background").forEach((e=>e.shadowEnabled(!1))),p.find(".page-background").forEach((e=>e.strokeEnabled(!1))),p.find(".highlighter").forEach((e=>e.visible(!1)));const g=p.findOne(".page-background-group"),u=g.clip();g.clip({x:null,y:null,width:null,height:null});const _=p.findOne(".elements-container"),m=_.clip();_.clip({x:null,y:null,width:null,height:null});const f=p.find((e=>e.getAttr("hideInExport")));f.forEach((e=>{e.setAttr("oldVisible",e.visible()),e.hide()}));const h=p.find((e=>!e.visible()&&e.getAttr("editModeEnabled")));h.forEach((e=>{e.setAttr("oldVisible",e.visible()),e.show()})),a&&p.find(".page-background").forEach((e=>e.hide()));const b=n?l.bleed:0;let y=b;!e.bleedVisible&&n||(e.bleedVisible||n?e.bleedVisible&&n?y=0:e.bleedVisible&&!n&&(y=-l.bleed):y=0);const x=document.createElement("canvas");x.width=Math.round((l.computedWidth+2*b)*r),x.height=Math.round((l.computedHeight+2*b)*r);const w=x.getContext("2d");"image/jpeg"===o&&(w.fillStyle="white",w.fillRect(0,0,x.width,x.height));const v=p.scale();p.scale({x:1,y:1});const E=p.toCanvas({x:p.x()-y,y:p.y()-y,width:l.computedWidth+2*b,height:l.computedHeight+2*b,pixelRatio:r});return p.scale(v),w.drawImage(E,0,0,x.width,x.height),konva_1.default.Util.releaseCanvas(E),a&&p.find(".page-background").forEach((e=>e.show())),f.forEach((e=>{e.visible(e.getAttr("oldVisible"))})),h.forEach((e=>{e.visible(e.getAttr("oldVisible"))})),p.find(".page-background").forEach((e=>e.shadowEnabled(!0))),p.find(".page-background").forEach((e=>e.strokeEnabled(!0))),d.find("Transformer").forEach((e=>e.visible(!0))),p.find(".highlighter").forEach((e=>e.visible(!0))),g.clip(u),_.clip(m),null==l||l.set({_exporting:!1}),x},async toDataURL({pixelRatio:t,ignoreBackground:a,pageId:i,mimeType:o,includeBleed:n,quality:s}={}){const r=await e._toCanvas({pixelRatio:t,ignoreBackground:a,pageId:i,mimeType:o,includeBleed:n}),l=r.toDataURL(o,s);return konva_1.default.Util.releaseCanvas(r),l},async toBlob({pixelRatio:t,ignoreBackground:a,pageId:i,mimeType:o,includeBleed:n,quality:s}={}){const r=await e._toCanvas({pixelRatio:t,ignoreBackground:a,pageId:i,mimeType:o,includeBleed:n}),l=new Promise((e=>{r.toBlob(e,o,s)}));return konva_1.default.Util.releaseCanvas(r),l},async saveAsImage(t={}){var{fileName:a}=t,i=__rest(t,["fileName"]);const o=i.mimeType||"image/png",n=o.split("/")[1];(0,download_1.downloadFile)(await e.toDataURL(i),a||"polotno."+n,o)},async _toPDF(t){const a=t.dpi||e.dpi,i=t.parallel||1,o=t.unit||("px"===e.unit?"mm":e.unit),n=t.pixelRatio||1,s=t.pageIds||e.pages.map((e=>e.id)),r=e.pages.filter((e=>s.includes(e.id))),l=await(0,pdf_1.getJsPDF)(),d=e=>(0,unit_1.pxToUnit)({px:e,unit:o,dpi:a}),c=d(t.cropMarkSize||0),p=r[0]||{},g=t.includeBleed?p.bleed:0,u=d(p.computedWidth+2*g)+2*c,_=d(p.computedHeight+2*g)+2*c;var m=new l({unit:o,orientation:u>_?"landscape":"portrait",format:[u,_],compress:!0,putOnlyUsedFonts:!0});m.deletePage(1);const f=e._elementsPixelRatio;e.setElementsPixelRatio(n),await new Promise((e=>setTimeout(e)));const h=((e,t)=>{for(var a=[],i=0;i<e.length;i+=t)a.push(e.slice(i,i+t));return a})(r,i);for(const a of h){const i=a.map((async a=>{const i=t.includeBleed?a.bleed:0,o=d(a.computedWidth+2*i)+2*c,s=d(a.computedHeight+2*i)+2*c;let r=0,l=n;for(;r<10;){r+=1,2===r&&console.error("Polotno can not export PDF with current settings. Quality is automatically reduced.");const i=await e.toDataURL(Object.assign(Object.assign({},t),{pageId:a.id,pixelRatio:l}));if(i.length>20)return{url:i,width:o,height:s};l*=.8}}));(await Promise.all(i)).forEach((({url:e,width:t,height:a})=>{m.addPage([t,a],t>a?"landscape":"portrait"),c&&(m.setLineWidth(d(1)),m.line(2*c,0,2*c,c),m.line(0,2*c,c,2*c),m.line(t-2*c,0,t-2*c,c),m.line(t,2*c,t-c,2*c),m.line(0,a-2*c,c,a-2*c),m.line(2*c,a,2*c,a-c),m.line(t,a-2*c,t-c,a-2*c),m.line(t-2*c,a,t-2*c,a-c)),m.addImage(e,c,c,t-2*c,a-2*c,void 0,"FAST")}))}return e.setElementsPixelRatio(f),m},toPDFDataURL:async t=>(await e._toPDF(Object.assign({mimeType:"image/jpeg"},t))).output("datauristring"),async toGIFDataURL(t={}){const a=t.pixelRatio||1,i=await(0,gif_lib_1.createGIF)({width:e.width*a,height:e.height*a}),o=1e3/(t.fps||10),n=e.duration/o;for(let t=0;t<n-1;t++){const n=t*o||1;e.setCurrentTime(n);let s=0,r="";for(const t of e.pages)if(s+=t.duration,t.set({_rendering:s>n}),s>n){r=t.id;break}const l=await e._toCanvas({pixelRatio:a,pageId:r});i.addFrame(l.getContext("2d"),{delay:o,copy:!0})}for(const t of e.pages)t.set({_rendering:!1});e.stop(),i.render();return new Promise((e=>{i.on("finished",(function(t){!function(e,t){var a=new FileReader;a.onload=function(e){t(e.target.result)},a.readAsDataURL(e)}(t,e)}))}))},async saveAsGIF(t={}){var{fileName:a}=t,i=__rest(t,["fileName"]);const o=await e.toGIFDataURL(i);(0,download_1.downloadFile)(o,a||"polotno.gif")},async toHTML(){const t=e.toJSON();return(0,html_1.jsonToHTML)({json:t})},async saveAsHTML({fileName:t}={}){const a=await e.toHTML(),i="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(a)));(0,download_1.downloadFile)(i,t||"polotno.html")},async toSVG(){const t=e.toJSON();return(0,to_svg_1.jsonToSVG)({json:t})},async saveAsSVG({fileName:t}={}){const a=await e.toSVG(),i="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(a)));(0,download_1.downloadFile)(i,t||"polotno.svg")},async saveAsPDF(t={}){var{fileName:a}=t,i=__rest(t,["fileName"]);(await e._toPDF(Object.assign({mimeType:"image/jpeg"},i))).save(a||"polotno.pdf")},async waitLoading(){await new Promise((e=>setTimeout(e,50))),await(0,loader_1.whenLoaded)()},toJSON:()=>({width:e.width,height:e.height,fonts:(0,mobx_state_tree_1.getSnapshot)(e.fonts),pages:(0,mobx_state_tree_1.getSnapshot)(e.pages),unit:e.unit,dpi:e.dpi}),loadJSON(t,a=!1){var i;const o=Object.assign({},t),n=e.pages.indexOf(e.activePage);let s=null===(i=o.pages[n]||o.pages[0])||void 0===i?void 0:i.id;o._activePageId=s;const r=Object.assign({},(0,mobx_state_tree_1.getSnapshot)(e));Object.assign(r,o),r.history=a?e.history.toJSON():{history:[],undoIdx:-1},(0,mobx_state_tree_1.applySnapshot)(e,r)},clear({keepHistory:t=!1}={}){const a=e.pages.map((e=>e.id));e.deletePages(a),t||e.history.clear()},addFont(t){e.removeFont(t.fontFamily),e.fonts.push(t),e.loadFont(t.fontFamily)},removeFont(t){e.fonts.filter((e=>e.fontFamily===t)).forEach((e=>(0,mobx_state_tree_1.destroy)(e)))},async loadFont(t){const a=e.fonts.find((e=>e.fontFamily===t))||fonts.globalFonts.find((e=>e.fontFamily===t));a?fonts.injectCustomFont(a):fonts.injectGoogleFont(t),await fonts.loadFont(t)},validate:e=>exports.Store.validate(e,[{path:"",type:exports.Store}]).map((e=>({path:"store"+e.context.map((e=>e.path)).join("."),message:e.message})))}))),exports.createStore=createStore,exports.default=createStore;
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,i,a){void 0===a&&(a=i);var o=Object.getOwnPropertyDescriptor(t,i);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,a,o)}:function(e,t,i,a){void 0===a&&(a=i),e[a]=t[i]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&__createBinding(t,e,i);return __setModuleDefault(t,e),t},__rest=this&&this.__rest||function(e,t){var i={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&t.indexOf(a)<0&&(i[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(a=Object.getOwnPropertySymbols(e);o<a.length;o++)t.indexOf(a[o])<0&&Object.prototype.propertyIsEnumerable.call(e,a[o])&&(i[a[o]]=e[a[o]])}return i},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.createStore=exports.Store=exports.Font=void 0;const mobx_state_tree_1=require("mobx-state-tree"),history_1=require("./history"),nanoid_1=require("nanoid"),konva_1=__importDefault(require("konva")),download_1=require("../utils/download"),pdf_1=require("../utils/pdf"),gif_lib_1=require("../utils/gif-lib"),validate_key_1=require("../utils/validate-key"),fonts=__importStar(require("../utils/fonts")),loader_1=require("../utils/loader"),unit_1=require("../utils/unit"),deep_equal_1=require("../utils/deep-equal"),wait_1=require("../utils/wait"),html_1=require("../utils/html"),to_svg_1=require("../utils/to-svg"),page_model_1=require("./page-model"),group_model_1=require("./group-model");function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){const i=exports.Store.create();return(0,validate_key_1.validateKey)(e,t),i}(0,mobx_state_tree_1.setLivelinessChecking)("ignore"),exports.Font=mobx_state_tree_1.types.model("Font",{fontFamily:mobx_state_tree_1.types.string,url:mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string,""),styles:mobx_state_tree_1.types.frozen()}).preProcessSnapshot((e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}))),exports.Store=mobx_state_tree_1.types.model("Store",{role:"",pages:mobx_state_tree_1.types.array(page_model_1.Page),fonts:mobx_state_tree_1.types.array(exports.Font),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:"px",dpi:72,bleedVisible:!1,rulesVisible:!1,openedSidePanel:"",selectedElementsIds:mobx_state_tree_1.types.array(mobx_state_tree_1.types.string),animatedElementsIds:mobx_state_tree_1.types.array(mobx_state_tree_1.types.string),history:mobx_state_tree_1.types.optional(history_1.UndoManager,{targetPath:"../pages"}),_elementsPixelRatio:2,_activePageId:""}).views((e=>({get _bleedVisible(){return console.warn("store._bleedVisible is deprecated. Please use store.bleedVisible instead."),e.bleedVisible},get selectedElements(){return e.selectedElementsIds.map((t=>{for(const i of e.pages)for(const e of i.children)if(e.id===t)return e})).filter((e=>!!e))},get children(){return e.pages},get selectedShapes(){const t=[];return e.selectedElementsIds.forEach((i=>{for(const a of e.pages)for(const e of a.children)e.id===i&&"group"!==e.type&&t.push(e),"group"===e.type&&e.id===i&&t.push(...e.children)})),t},get activePage(){return e.pages.slice().find((t=>t.id===e._activePageId))||(e.pages.length?e.pages[0]:null)},get duration(){let t=0;return e.pages.forEach((e=>{t+=e.duration})),t}}))).actions((e=>{let t=0;return{afterCreate(){e.history.canUndo},setCurrentTime(t){e.currentTime=t},play({animatedElementsIds:i=[],currentTime:a=0}={}){e.animatedElementsIds=(0,mobx_state_tree_1.cast)(i),e.currentTime=a,e.isPlaying=!0,t=Date.now(),requestAnimationFrame(e.seek)},seek(){if(!e.isPlaying)return;const i=Date.now(),a=i-t;t=i,e.currentTime+=a;let o=0;for(const t of e.pages){if(e.currentTime>=t.startTime&&e.currentTime<t.startTime+t.duration){e.selectPage(t.id);break}o+=t.duration}e.isPlaying&&e.currentTime<e.duration?requestAnimationFrame(e.seek):e.stop()},stop(){e.isPlaying=!1,e.currentTime=0,e.animatedElementsIds=(0,mobx_state_tree_1.cast)([])}}})).actions((e=>({setUnit({unit:t,dpi:i}){e.unit=t||e.unit,e.dpi=i||e.dpi},setRole(t){e.role=t},find(t){let i;return(0,group_model_1.forEveryChild)({children:e.pages},(e=>{if(!i&&t(e))return i=e,!0})),i},getElementById:t=>e.find((e=>e.id===t)),addPage(t){const i=page_model_1.Page.create(Object.assign({id:(0,nanoid_1.nanoid)(10)},t));return e.pages.push(i),e._activePageId=i.id,i},selectPage(t){e._activePageId=t},selectElements(t){const i=t.map((t=>e.getElementById(t))).sort(((e,t)=>e.page.children.indexOf(e)-e.page.children.indexOf(t))).filter((e=>!!e)).map((e=>e.id));e.selectedElementsIds=(0,mobx_state_tree_1.cast)(i)},toggleBleed(t){e.bleedVisible=null!=t?t:!e.bleedVisible},toggleRulers(t){e.rulesVisible=null!=t?t:!e.rulesVisible},openSidePanel(t){e.openedSidePanel=t},setScale(t){e.scale=t},_setScaleToFit(t){e.scaleToFit=t},setElementsPixelRatio(t){e._elementsPixelRatio=t},setSize(t,i,a){e.pages.forEach((e=>{e.setSize({width:t,height:i,useMagic:a,softChange:!0})})),e.width=t,e.height=i},setPageZIndex(t,i){const a=e.pages.find((e=>e.id===t));a&&((0,mobx_state_tree_1.detach)(a),e.pages.remove(a),e.pages.splice(i,0,a))},deletePages(t){const i=e.pages.indexOf(e.activePage);t.forEach((t=>{const i=e.pages.find((e=>e.id===t));(0,mobx_state_tree_1.destroy)(i)}));const a=Math.min(e.pages.length-1,i),o=e.pages[a];o&&(e._activePageId=o.id),e.selectedElementsIds=(0,mobx_state_tree_1.cast)(e.selectedElementsIds.filter((t=>e.getElementById(t))))},groupElements(t){const i=t.map((t=>e.getElementById(t)));i.forEach((e=>{e&&(0,mobx_state_tree_1.detach)(e)}));const a=e.activePage,o={id:(0,nanoid_1.nanoid)(10),children:i,type:"group"};return a.children.push(o),e.selectedElementsIds=(0,mobx_state_tree_1.cast)([o.id]),o},ungroupElements(t){const i=t.map((t=>e.getElementById(t))),a=[];i.forEach((e=>{if(e&&"group"===e.type){const t=e.page,i=t.children.indexOf(e);e.children.forEach((e=>{a.push(e.id)})),e.children.forEach((e=>{(0,mobx_state_tree_1.detach)(e),t.children.push(e)})),t.children.splice(i,1)}})),e.selectedElementsIds=(0,mobx_state_tree_1.cast)(a)},deleteElements(t){t.forEach((t=>{e.pages.forEach((e=>{const i=e.children.find((e=>e.id===t));i&&(0,mobx_state_tree_1.destroy)(i)}))})),e.selectedElementsIds=(0,mobx_state_tree_1.cast)(e.selectedElementsIds.filter((t=>e.getElementById(t))))},on(t,i){if("change"===t){let t=e.toJSON();return(0,mobx_state_tree_1.onSnapshot)(e,(a=>{const o=e.toJSON();!(0,deep_equal_1.deepEqual)(t,o)&&(t=o,i(o))}))}},async _toCanvas({pixelRatio:t,ignoreBackground:i,pageId:a,mimeType:o,includeBleed:n}={}){var s;const r=t||1;a=a||(null===(s=e.pages[0])||void 0===s?void 0:s.id);const l=e.pages.find((e=>e.id===a));if(!l)throw new Error(`No page for export with id ${a}`);null==l||l.set({_exporting:!0});const d=await(0,wait_1.waitTillAvailable)((()=>konva_1.default.stages.find((e=>e.getAttr("pageId")===a))));if(!d)throw new Error(`Export is failed. Can not find stage for page ${a}. Looks like <Workspace /> component is not mounted, but it is required in order to process the export.`);const c=!!d.findOne(".page-container");await e.waitLoading();const p=d.findOne(".page-container");if(!p)throw new Error(`Export is failed. Can't find page container. ${c}`);d.find("Transformer").forEach((e=>e.visible(!1))),p.find(".page-background").forEach((e=>e.shadowEnabled(!1))),p.find(".page-background").forEach((e=>e.strokeEnabled(!1))),p.find(".highlighter").forEach((e=>e.visible(!1)));const g=p.findOne(".page-background-group"),u=g.clip();g.clip({x:null,y:null,width:null,height:null});const _=p.findOne(".elements-container"),m=_.clip();_.clip({x:null,y:null,width:null,height:null});const f=p.find((e=>e.getAttr("hideInExport")));f.forEach((e=>{e.setAttr("oldVisible",e.visible()),e.hide()}));const h=p.find((e=>!e.visible()&&e.getAttr("editModeEnabled")));h.forEach((e=>{e.setAttr("oldVisible",e.visible()),e.show()})),i&&p.find(".page-background").forEach((e=>e.hide()));const b=n?l.bleed:0;let y=b;!e.bleedVisible&&n||(e.bleedVisible||n?e.bleedVisible&&n?y=0:e.bleedVisible&&!n&&(y=-l.bleed):y=0);const x=document.createElement("canvas");x.width=Math.round((l.computedWidth+2*b)*r),x.height=Math.round((l.computedHeight+2*b)*r);const w=x.getContext("2d");"image/jpeg"===o&&(w.fillStyle="white",w.fillRect(0,0,x.width,x.height));const v=p.scale();p.scale({x:1,y:1});const E=p.toCanvas({x:p.x()-y,y:p.y()-y,width:l.computedWidth+2*b,height:l.computedHeight+2*b,pixelRatio:r});return p.scale(v),w.drawImage(E,0,0,x.width,x.height),konva_1.default.Util.releaseCanvas(E),i&&p.find(".page-background").forEach((e=>e.show())),f.forEach((e=>{e.visible(e.getAttr("oldVisible"))})),h.forEach((e=>{e.visible(e.getAttr("oldVisible"))})),p.find(".page-background").forEach((e=>e.shadowEnabled(!0))),p.find(".page-background").forEach((e=>e.strokeEnabled(!0))),d.find("Transformer").forEach((e=>e.visible(!0))),p.find(".highlighter").forEach((e=>e.visible(!0))),g.clip(u),_.clip(m),null==l||l.set({_exporting:!1}),x},async toDataURL({pixelRatio:t,ignoreBackground:i,pageId:a,mimeType:o,includeBleed:n,quality:s}={}){const r=await e._toCanvas({pixelRatio:t,ignoreBackground:i,pageId:a,mimeType:o,includeBleed:n}),l=r.toDataURL(o,s);return konva_1.default.Util.releaseCanvas(r),l},async toBlob({pixelRatio:t,ignoreBackground:i,pageId:a,mimeType:o,includeBleed:n,quality:s}={}){const r=await e._toCanvas({pixelRatio:t,ignoreBackground:i,pageId:a,mimeType:o,includeBleed:n}),l=new Promise((e=>{r.toBlob(e,o,s)}));return konva_1.default.Util.releaseCanvas(r),l},async saveAsImage(t={}){var{fileName:i}=t,a=__rest(t,["fileName"]);const o=a.mimeType||"image/png",n=o.split("/")[1];(0,download_1.downloadFile)(await e.toDataURL(a),i||"polotno."+n,o)},async _toPDF(t){const i=t.dpi||e.dpi,a=t.parallel||1,o=t.unit||("px"===e.unit?"mm":e.unit),n=t.pixelRatio||1,s=t.pageIds||e.pages.map((e=>e.id)),r=e.pages.filter((e=>s.includes(e.id))),l=await(0,pdf_1.getJsPDF)(),d=e=>(0,unit_1.pxToUnit)({px:e,unit:o,dpi:i}),c=d(t.cropMarkSize||0),p=r[0]||{},g=t.includeBleed?p.bleed:0,u=d(p.computedWidth+2*g)+2*c,_=d(p.computedHeight+2*g)+2*c;var m=new l({unit:o,orientation:u>_?"landscape":"portrait",format:[u,_],compress:!0,putOnlyUsedFonts:!0});m.deletePage(1);const f=e._elementsPixelRatio;e.setElementsPixelRatio(n),await new Promise((e=>setTimeout(e)));const h=((e,t)=>{for(var i=[],a=0;a<e.length;a+=t)i.push(e.slice(a,a+t));return i})(r,a);for(const i of h){const a=i.map((async i=>{const a=t.includeBleed?i.bleed:0,o=d(i.computedWidth+2*a)+2*c,s=d(i.computedHeight+2*a)+2*c;let r=0,l=n;for(;r<10;){r+=1,2===r&&console.error("Polotno can not export PDF with current settings. Quality is automatically reduced.");const a=await e.toDataURL(Object.assign(Object.assign({},t),{pageId:i.id,pixelRatio:l}));if(a.length>20)return{url:a,width:o,height:s};l*=.8}}));(await Promise.all(a)).forEach((({url:e,width:t,height:i})=>{m.addPage([t,i],t>i?"landscape":"portrait"),c&&(m.setLineWidth(d(1)),m.line(2*c,0,2*c,c),m.line(0,2*c,c,2*c),m.line(t-2*c,0,t-2*c,c),m.line(t,2*c,t-c,2*c),m.line(0,i-2*c,c,i-2*c),m.line(2*c,i,2*c,i-c),m.line(t,i-2*c,t-c,i-2*c),m.line(t-2*c,i,t-2*c,i-c)),m.addImage(e,c,c,t-2*c,i-2*c,void 0,"FAST")}))}return e.setElementsPixelRatio(f),m},toPDFDataURL:async t=>(await e._toPDF(Object.assign({mimeType:"image/jpeg"},t))).output("datauristring"),async toGIFDataURL(t={}){const i=t.pixelRatio||1,a=await(0,gif_lib_1.createGIF)({width:e.width*i,height:e.height*i}),o=1e3/(t.fps||10),n=e.duration/o;for(let t=0;t<n-1;t++){const n=t*o||1;e.setCurrentTime(n);let s=0,r="";for(const t of e.pages)if(s+=t.duration,t.set({_rendering:s>n}),s>n){r=t.id;break}const l=await e._toCanvas({pixelRatio:i,pageId:r});a.addFrame(l.getContext("2d"),{delay:o,copy:!0})}for(const t of e.pages)t.set({_rendering:!1});e.stop(),a.render();return new Promise((e=>{a.on("finished",(function(t){!function(e,t){var i=new FileReader;i.onload=function(e){t(e.target.result)},i.readAsDataURL(e)}(t,e)}))}))},async saveAsGIF(t={}){var{fileName:i}=t,a=__rest(t,["fileName"]);const o=await e.toGIFDataURL(a);(0,download_1.downloadFile)(o,i||"polotno.gif")},async toHTML(){const t=e.toJSON();return(0,html_1.jsonToHTML)({json:t})},async saveAsHTML({fileName:t}={}){const i=await e.toHTML(),a="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));(0,download_1.downloadFile)(a,t||"polotno.html")},async toSVG(){const t=e.toJSON();return(0,to_svg_1.jsonToSVG)({json:t})},async saveAsSVG({fileName:t}={}){const i=await e.toSVG(),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(i)));(0,download_1.downloadFile)(a,t||"polotno.svg")},async saveAsPDF(t={}){var{fileName:i}=t,a=__rest(t,["fileName"]);(await e._toPDF(Object.assign({mimeType:"image/jpeg"},a))).save(i||"polotno.pdf")},async waitLoading(){await new Promise((e=>setTimeout(e,50))),await(0,loader_1.whenLoaded)()},toJSON:()=>({width:e.width,height:e.height,fonts:(0,mobx_state_tree_1.getSnapshot)(e.fonts),pages:(0,mobx_state_tree_1.getSnapshot)(e.pages),unit:e.unit,dpi:e.dpi}),loadJSON(t,i=!1){var a;const o=Object.assign({},t),n=e.pages.indexOf(e.activePage);let s=null===(a=o.pages[n]||o.pages[0])||void 0===a?void 0:a.id;o._activePageId=s;const r=Object.assign({},(0,mobx_state_tree_1.getSnapshot)(e));Object.assign(r,o),r.history=i?e.history.toJSON():{history:[],undoIdx:-1},(0,mobx_state_tree_1.applySnapshot)(e,r)},clear({keepHistory:t=!1}={}){const i=e.pages.map((e=>e.id));e.deletePages(i),t||e.history.clear()},addFont(t){e.removeFont(t.fontFamily),e.fonts.push(t),e.loadFont(t.fontFamily)},removeFont(t){e.fonts.filter((e=>e.fontFamily===t)).forEach((e=>(0,mobx_state_tree_1.destroy)(e)))},async loadFont(t){const i=e.fonts.find((e=>e.fontFamily===t))||fonts.globalFonts.find((e=>e.fontFamily===t));i?fonts.injectCustomFont(i):fonts.injectGoogleFont(t),await fonts.loadFont(t)},validate:e=>exports.Store.validate(e,[{path:"",type:exports.Store}]).map((e=>({path:"store"+e.context.map((e=>e.path)).join("."),message:e.message})))}))),exports.createStore=createStore,exports.default=createStore;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polotno",
3
- "version": "2.2.4",
3
+ "version": "2.2.5",
4
4
  "description": "Design Editor Framework",
5
5
  "author": "Anton Lavrenov",
6
6
  "keywords": [