polotno 4.2.2 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/model/store.d.ts CHANGED
@@ -287,6 +287,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
287
287
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
288
288
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
289
289
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
290
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
290
291
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
291
292
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
292
293
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -2340,6 +2341,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
2340
2341
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
2341
2342
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
2342
2343
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
2344
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
2343
2345
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
2344
2346
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
2345
2347
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -4304,6 +4306,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
4304
4306
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
4305
4307
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
4306
4308
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
4309
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
4307
4310
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
4308
4311
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
4309
4312
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -6566,6 +6569,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
6566
6569
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
6567
6570
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
6568
6571
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
6572
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
6569
6573
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
6570
6574
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
6571
6575
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -8530,6 +8534,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
8530
8534
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
8531
8535
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
8532
8536
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
8537
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
8533
8538
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
8534
8539
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
8535
8540
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -10495,6 +10500,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
10495
10500
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
10496
10501
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
10497
10502
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
10503
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
10498
10504
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
10499
10505
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
10500
10506
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -12459,6 +12465,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
12459
12465
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
12460
12466
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
12461
12467
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
12468
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
12462
12469
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
12463
12470
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
12464
12471
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -14461,6 +14468,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
14461
14468
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
14462
14469
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
14463
14470
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
14471
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
14464
14472
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
14465
14473
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
14466
14474
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -16425,6 +16433,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
16425
16433
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
16426
16434
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
16427
16435
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
16436
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
16428
16437
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
16429
16438
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
16430
16439
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
package/model/store.js CHANGED
@@ -1 +1 @@
1
- var e=this&&this.__rest||function(e,t){var i={};for(var o in e){Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(i[o]=e[o])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++){t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(i[o[n]]=e[o[n]])}}return i};import{applySnapshot as t,cast as i,destroy as o,detach as n,getSnapshot as a,onSnapshot as s,setLivelinessChecking as r,types as l}from"mobx-state-tree";import{UndoManager as d}from"./history.js";import{nanoid as c}from"nanoid";import p from"konva";import{computed as g}from"mobx";import{ZERO_BLEED as m}from"@polotno/schema";import{downloadFile as u}from"../utils/download.js";import{getJsPDF as f}from"../utils/pdf.js";import{createGIF as h}from"../utils/gif-lib.js";import{validateKey as b,setKey as y}from"../utils/validate-key.js";import*as v from"../utils/fonts.js";import{flags as P}from"../utils/flags.js";import{addDpiMetadataToImage as w}from"../utils/image-dpi.js";import{nodeToCanvas as E}from"../utils/canvas.js";import{whenLoaded as x}from"../utils/loader.js";import{pxToUnit as T}from"../utils/unit.js";import{deepEqual as I}from"../utils/deep-equal.js";import{waitTillAvailable as _}from"../utils/wait.js";import{jsonToHTML as k}from"../utils/to-html.js";import{jsonToSVG as S}from"../utils/to-svg.js";import{Page as O}from"./page-model.js";import{forEveryChild as j,forEveryNode as R}from"./group-model.js";import{Audio as F}from"./audio-model.js";r("ignore");export const Font=l.model("Font",{fontFamily:l.string,url:l.optional(l.string,""),styles:l.frozen()}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}));export const ROLES={ADMIN:"admin",VIEWER:"viewer"};export const Store=l.model("Store",{role:"",pages:l.array(O),fonts:l.array(Font),audios:l.array(F),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:l.optional(l.enumeration("UnitType",["pt","mm","cm","in","px"]),"px"),dpi:72,schemaVersion:4,bleedVisible:!1,rulesVisible:!1,distanceGuidesVisible:!1,timingPreview:l.optional(l.enumeration("TimingPreview",["all","playhead"]),"all"),openedSidePanel:"",previousOpenedSidePanel:"",custom:l.frozen(),tool:l.optional(l.enumeration("Tool",["selection","draw","pan","text","eraser"]),"selection"),toolOptions:l.optional(l.model({brushType:l.optional(l.enumeration("BrushType",["brush","highlighter"]),"brush"),strokeWidth:l.optional(l.number,5),stroke:l.optional(l.string,"#000000"),opacity:l.optional(l.number,1)}),{}),selectedElementsIds:l.array(l.string),animatedElementsIds:l.array(l.string),history:l.optional(d,{targetPath:"../pages"}),_elementsPixelRatio:Math.min(2,"undefined"!=typeof window&&window.devicePixelRatio||1),_activePageId:"",_selectedPagesIds:l.array(l.string),_forceShowCredit:!1,_validated:!1}).views(e=>{const t=g(()=>{const t={};return R({children:e.pages},e=>(t[e.id]=e,!1)),t},{keepAlive:!0});return{get _idsMap(){return t.get()}}}).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=>e._idsMap[t]).filter(e=>!!e)},get children(){return e.pages},get selectedShapes(){const e=[];return j({children:this.selectedElements},t=>{"group"!==t.type&&e.push(t)}),e},get activePage(){return e.pages.slice().find(t=>t.id===e._activePageId)||(e.pages.length?e.pages[0]:null)},get selectedPages(){return e._selectedPagesIds.map(t=>e.pages.find(e=>e.id===t))},get duration(){let t=0;return e.pages.forEach(e=>{t+=e.duration}),t},pageAtTime(t){for(const i of e.pages){if(t>=i.startTime&&t<i.startTime+i.duration){return i}}return e.pages.length&&t>=this.duration?e.pages[e.pages.length-1]:null},get effectiveTime(){if(e.isPlaying){return e.currentTime}const t=this.activePage;return t&&this.pageAtTime(e.currentTime)!==t?t.startTime:e.currentTime},get playheadAccurate(){return e.isPlaying||"playhead"===e.timingPreview},get isEditingPaused(){var t;return!e.isPlaying&&!(null===(t=this.activePage)||void 0===t?void 0:t._exportingOrRendering)},get _hasCroppedImages(){return this.find(e=>"image"===e.type&&e._cropModeEnabled)},find(t){let i;return R({children:e.pages},e=>{if(!i&&t(e)){return i=e,!0}}),i},getElementById:t=>e._idsMap[t]})).actions(r=>{let l=0,d=null,g=!1;const y={afterCreate(){r.history.canUndo},setCurrentTime(e){r.currentTime=e},_togglePlaying(e=!r.isPlaying){r.isPlaying=e},play({animatedElementsIds:e=[],startTime:t=0,currentTime:o=0,endTime:n=r.duration,repeat:a=!1}={}){o&&(console.warn("currentTime property of store.play() is deprecated. Please use startTime instead."),t=o),r.animatedElementsIds=i(e),r.currentTime=t,r.isPlaying=!0,l=Date.now(),d=n,g=a,requestAnimationFrame(()=>y.seek())},checkActivePage(){const e=r.pageAtTime(r.currentTime);e&&y.selectPage(e.id)},seek(){if(!r.isPlaying){return}const e=Date.now(),t=e-l;l=e,r.currentTime+=t;const i=d||r.duration;r.currentTime>=i&&!g&&(r.currentTime=i),y.checkActivePage(),r.isPlaying&&r.currentTime<i?requestAnimationFrame(()=>y.seek()):r.isPlaying&&g?(r.currentTime=0,requestAnimationFrame(()=>y.seek())):y.pause()},pause(){r.isPlaying=!1,r.animatedElementsIds=i([])},stop(){y.pause(),r.currentTime=0,y.checkActivePage()},__(){r._validated||(b(r._forceShowCredit),r._validated=!0)},set(e){Object.assign(r,e)},setUnit({unit:e,dpi:t}){r.unit=e||r.unit,r.dpi=t||r.dpi},setRole(e){r.role=e},setTool(e){r.tool=e},setToolOptions(e){Object.assign(r.toolOptions,e)},addPage(e){const t=O.create(Object.assign({id:c(10)},e));return r.pages.push(t),r._activePageId=t.id,t},selectPage(e){r._activePageId=e,1===r._selectedPagesIds.length&&(r._selectedPagesIds=i([e]))},selectPages(e){r._selectedPagesIds=i(e),1===r._selectedPagesIds.length&&(r._activePageId=r._selectedPagesIds[0])},selectElements(e){const t=e.map(e=>r.getElementById(e)).filter(e=>!!e);t.sort((e,t)=>{var i,o,n,a;return(null!==(o=null===(i=e.parent)||void 0===i?void 0:i.children.indexOf(e))&&void 0!==o?o:0)-(null!==(a=null===(n=t.parent)||void 0===n?void 0:n.children.indexOf(t))&&void 0!==a?a:0)}),r.selectedElementsIds=i(t.map(e=>e.id))},toggleBleed(e){r.bleedVisible=null!=e?e:!r.bleedVisible},toggleRulers(e){r.rulesVisible=null!=e?e:!r.rulesVisible},setTimingPreview(e){r.timingPreview=e},toggleDistanceGuides(e){r.distanceGuidesVisible=null!=e?e:!r.distanceGuidesVisible},openSidePanel(e){r.openedSidePanel!==e&&(r.previousOpenedSidePanel=r.openedSidePanel,r.openedSidePanel=e)},restoreSidePanel(){const e=r.previousOpenedSidePanel;e&&e!==r.openedSidePanel?r.openedSidePanel=e:r.openedSidePanel="photos"},setScale(e){r.scale=e},_setScaleToFit(e){r.scaleToFit=e},setElementsPixelRatio(e){r._elementsPixelRatio=e},setSize(e,t,i){r.pages.forEach(o=>{o.setSize({width:e,height:t,useMagic:i,softChange:!0})}),r.width=e,r.height=t},setPageZIndex(e,t){const i=r.pages.find(t=>t.id===e);i&&(n(i),r.pages.remove(i),r.pages.splice(t,0,i))},deletePages(e){const t=r.pages.indexOf(r.activePage);e.forEach(e=>{const t=r.pages.find(t=>t.id===e);o(t)});const n=Math.min(r.pages.length-1,t),a=r.pages[n];a&&(r._activePageId=a.id),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},groupElements(e,t={}){const o=e.map(e=>r.getElementById(e)).filter(e=>!!e);if(!o.length){return}const a=o[0].parent;if(!a){return}if(!o.every(e=>e.parent===a)){return void console.warn("store.groupElements: refusing to group elements that do not share a parent. Pass ids whose elements all live under the same page or the same group.")}o.forEach(e=>n(e));const s=a.children.reduce((e,t)=>{var i;if("group"===t.type){const o=null===(i=t.name)||void 0===i?void 0:i.match(/group-(\d+)/);if(o){const t=parseInt(o[1],10);return Math.max(e,t)}}return e},0),l=Object.assign({id:c(10),name:`group-${s+1}`,children:o,type:"group"},t);return a.children.push(l),r.selectedElementsIds=i([l.id]),a.children.find(e=>e.id===l.id)},ungroupElements(e){const t=e.map(e=>r.getElementById(e)),o=[];t.forEach(e=>{if(e&&"group"===e.type){const t=e.parent;if(!t){return}const i=t.children.indexOf(e);e.children.forEach(e=>{o.push(e.id)}),e.children.slice().forEach(e=>{n(e),t.children.push(e)}),t.children.splice(i,1)}}),r.selectedElementsIds=i(o)},deleteElements(e){const t=[];r.find(i=>(e.includes(i.id)&&t.push(i),!1)),t.forEach(e=>{o(e)}),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},on(e,t){if("change"===e){let e=y.toJSON();return s(r,i=>{const o=y.toJSON();!I(e,o)&&(e=o,t(o))})}},async _toCanvas({pixelRatio:e,ignoreBackground:t,pageId:i,mimeType:o,includeBleed:n,_skipTimeout:a,quickMode:s=!1,_exportCanvases:l}={}){var d;const c=e||1;i=i||(null===(d=r.pages[0])||void 0===d?void 0:d.id);const g=r.pages.find(e=>e.id===i);if(!g){throw new Error(`No page for export with id ${i}`)}const u=r._elementsPixelRatio;c>r._elementsPixelRatio&&y.setElementsPixelRatio(c),s?null==g||g.set({_forceMount:!0}):null==g||g.set({_exporting:!0});const f=await _(()=>{const e=p.stages.filter(e=>e.getAttr("pageId")===i);return 0===e.length?null:e});if(!f){throw null==g||g.set({_forceMount:!1,_exporting:!1}),y.setElementsPixelRatio(u),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.`)}f.length>1&&console.error(`Polotno error: Detected several canvas elements for page "${i}" in the document. This is not supported and will lead to incorrect export. Make sure to use unique ids for all pages and make sure you unmount <Workspace /> when it is not needed.`);const h=f[0];await y.waitLoading({_skipTimeout:a});const b=h.findOne(".page-container");if(!b){throw y.setElementsPixelRatio(u),null==g||g.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const v=h.position();h.position({x:0,y:0}),h.find("Transformer").forEach(e=>{e.setAttr("oldVisible",e.visible()),e.visible(!1)}),b.find(".page-background").forEach(e=>e.shadowEnabled(!1)),b.find(".page-background").forEach(e=>e.strokeEnabled(!1)),b.find(".highlighter").forEach(e=>e.visible(!1));const P=b.findOne(".page-background-group"),w=P.clip();P.clip({x:null,y:null,width:null,height:null});const x=b.findOne(".elements-container"),T=x.clip();x.clip({x:null,y:null,width:null,height:null});const I=b.find(e=>!e.visible()&&e.getAttr("editModeEnabled")&&!e.getAttr("hideInExport"));I.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()});const k=b.find(e=>e.getAttr("hideInExport"));k.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()}),t&&b.find(".page-background").forEach(e=>e.hide());const S=n?g.computedBleed:m;let O=S.left,j=S.top;!r.bleedVisible&&n||(r.bleedVisible||n?r.bleedVisible&&n?(O=0,j=0):r.bleedVisible&&!n&&(O=-g.computedBleed.left,j=-g.computedBleed.top):(O=0,j=0));const R=g.computedWidth+S.left+S.right,F=g.computedHeight+S.top+S.bottom,C=b.scale();b.scale({x:1,y:1});const V=E(b,{x:b.x()-O,y:b.y()-j,width:R,height:F,pixelRatio:c,sceneCanvas:null==l?void 0:l.sceneCanvas,bufferCanvas:null==l?void 0:l.bufferCanvas});b.scale(C);const A=V._canvas;if("image/jpeg"===o){const e=A.getContext("2d");e.save(),e.globalCompositeOperation="destination-over",e.fillStyle="white",e.fillRect(0,0,A.width,A.height),e.restore()}return t&&b.find(".page-background").forEach(e=>e.show()),k.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),I.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),b.find(".page-background").forEach(e=>e.shadowEnabled(!0)),b.find(".page-background").forEach(e=>e.strokeEnabled(!0)),h.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),b.find(".highlighter").forEach(e=>e.visible(!0)),P.clip(w),x.clip(T),h.position(v),null==g||g.set({_exporting:!1,_forceMount:!1}),await Promise.resolve(),y.setElementsPixelRatio(u),A},async toDataURL(t={}){var{mimeType:i,quality:o,dpi:n,dpiMetadata:a="auto"}=t,s=e(t,["mimeType","quality","dpi","dpiMetadata"]);const l=await y._toCanvas(Object.assign({mimeType:i},s)),d=i||"image/png",c=l.toDataURL(d,o);p.Util.releaseCanvas(l);const g=null!=n?n:r.dpi;return"image/png"!==d&&"image/jpeg"!==d||"never"===a||"auto"===a&&72===g?c:w(c,d,g)},async toBlob(t={}){var{mimeType:i,quality:o}=t,n=e(t,["mimeType","quality"]);const a=await y._toCanvas(Object.assign({mimeType:i},n)),s=await new Promise(e=>{a.toBlob(e,i,o)});return p.Util.releaseCanvas(a),s},async saveAsImage(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=(o.mimeType||"image/png").split("/")[1];u(await y.toDataURL(o),i||"polotno."+n)},async _toPDF(e){const t=e.dpi||r.dpi,i=e.parallel||1,o=e.unit||("px"===r.unit?"mm":r.unit),n=e.pixelRatio||1,a=e.pageIds||(e.pageId?[e.pageId]:r.pages.map(e=>e.id)),s=r.pages.filter(e=>a.includes(e.id)),l=await f(),d=e=>T({px:e,unit:o,dpi:t}),c=e.cropMarkSize||0,p=d(c),g=s[0]||{},u=e.includeBleed&&g.computedBleed||m,h=d(g.computedWidth+u.left+u.right+2*p),b=d(g.computedHeight+u.top+u.bottom+2*p);var v=new l({unit:o,orientation:h>b?"landscape":"portrait",format:[h,b],compress:!0,putOnlyUsedFonts:!0});v.deletePage(1);const P=((e,t)=>{const i=[];for(let o=0;o<e.length;o+=t){i.push(e.slice(o,o+t))}return i})(s,i);let w=0;for(const r of P){const t=r.map(async t=>{const i=e.includeBleed?t.computedBleed:m,o=t.computedWidth+i.left+i.right+2*c,s=t.computedHeight+i.top+i.bottom+2*c,r=d(o),l=d(s);let p=0,g=n;for(;p<10;){p+=1;const d=await y.toDataURL(Object.assign(Object.assign({},e),{pageId:t.id,pixelRatio:g,dpiMetadata:"never"}));if(d.length>20){return g!==n&&console.error(`Polotno can not export PDF with current settings. Quality is automatically reduced. pixelRatio was reduced to ${parseFloat(g.toFixed(3))}.`),e.onProgress&&e.onProgress(++w/a.length*.9),{url:d,width:r,height:l,widthPx:o,heightPx:s,cb:i}}g*=.8}});(await Promise.all(t)).filter(e=>void 0!==e).forEach(({url:e,width:t,height:i,widthPx:n,heightPx:a,cb:s})=>{v.addPage([t,i],t>i?"landscape":"portrait");const r=v.getCurrentPageInfo();var l;switch(o){case"pt":l=1;break;case"mm":l=72/25.4;break;case"cm":l=72/2.54;break;case"in":l=72;break;case"px":l=.75;break;default:throw"Invalid unit: "+o}if(r.pageContext.cropBox={bottomLeftX:0,bottomLeftY:0,topRightX:t*l,topRightY:i*l},r.pageContext.artBox={bottomLeftX:d(c+s.left)*l,bottomLeftY:d(c+s.bottom)*l,topRightX:d(n-c-s.right)*l,topRightY:d(a-c-s.top)*l},r.pageContext.bleedBox={bottomLeftX:d(c+s.left)*l,bottomLeftY:d(c+s.bottom)*l,topRightX:d(n-c-s.right)*l,topRightY:d(a-c-s.top)*l},p){v.setLineWidth(d(1));const e=p+d(s.left),o=p+d(s.right),n=p+d(s.top),a=p+d(s.bottom);v.line(e,0,e,p),v.line(0,n,p,n),v.line(t-o,0,t-o,p),v.line(t,n,t-p,n),v.line(0,i-a,p,i-a),v.line(e,i,e,i-p),v.line(t,i-a,t-p,i-a),v.line(t-o,i,t-o,i-p)}v.addImage(e,p,p,t-2*p,i-2*p,void 0,"FAST")})}return v},toPDFDataURL:async e=>(await y._toPDF(Object.assign({mimeType:"image/jpeg"},e))).output("datauristring"),async toGIFDataURL(e={}){const t=e.pixelRatio||1,i=e.pageIds||(e.pageId?[e.pageId]:r.pages.map(e=>e.id)),o=r.pages.filter(e=>i.includes(e.id));if(!o.length){throw new Error("No pages found for GIF export")}const n=o[0],a=await h({width:n.computedWidth*t,height:n.computedHeight*t}),s=1e3/(e.fps||10);for(const l of o){const e=Math.max(1,Math.floor(l.duration/s));for(let i=0;i<e;i++){const e=l.startTime+i*s||1;y.setCurrentTime(e);for(const t of r.pages){t.set({_rendering:t.id===l.id})}const o=await y._toCanvas({pixelRatio:t,pageId:l.id,_skipTimeout:!0});a.addFrame(o.getContext("2d"),{delay:s,copy:!0})}}for(const l of r.pages){l.set({_rendering:!1})}return y.stop(),a.render(),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,o=e(t,["fileName"]);const n=await y.toGIFDataURL(o);u(n,i||"polotno.gif")},async toHTML({elementHook:e}={}){const t=y.toJSON();return k({json:t,elementHook:e})},async saveAsHTML({fileName:e,elementHook:t}={}){const i=await y.toHTML({elementHook:t}),o="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));u(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:t,fontEmbedding:i="inline"}={fontEmbedding:"inline"}){var o;const n=y.toJSON();t=t||(null===(o=n.pages[0])||void 0===o?void 0:o.id);const a=n.pages.find(e=>e.id===t);return S({json:Object.assign(Object.assign({},n),{pages:a?[a]:[]}),elementHook:e,fontEmbedding:i})},async saveAsSVG({fileName:e,elementHook:t,pageId:i,fontEmbedding:o="inline"}={}){const n=await y.toSVG({elementHook:t,pageId:i,fontEmbedding:o}),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(n)));u(a,e||"polotno.svg")},async saveAsPDF(t={}){var{fileName:i}=t,o=e(t,["fileName"]);(await y._toPDF(Object.assign({mimeType:"image/jpeg"},o))).save(i||"polotno.pdf")},async waitLoading({_skipTimeout:e=!1}={}){e||await new Promise(e=>setTimeout(e,50)),await x()},toJSON:()=>({width:r.width,height:r.height,fonts:a(r.fonts),pages:a(r.pages),audios:a(r.audios),unit:r.unit,dpi:r.dpi,custom:r.custom,schemaVersion:r.schemaVersion}),loadJSON(e,i=!1){var o,n,s;const l="boolean"==typeof i?i:null!==(o=null==i?void 0:i.keepHistory)&&void 0!==o&&o,d="boolean"!=typeof i&&null!==(n=null==i?void 0:i.modernizeTextBackground)&&void 0!==n&&n,c=JSON.parse(JSON.stringify(e)),p=c.schemaVersion||0;p<1&&(P.htmlRenderEnabled||P.renderTagTextEnabled)&&R({children:c.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),p<2&&R({children:c.pages},e=>{e.filters&&Object.keys(e.filters).forEach(t=>{if(["warm","cold","natural"].includes(t)){return}const i=e.filters[t];i&&"number"==typeof i.intensity&&(i.intensity=i.intensity/100)})}),p<3&&(P.htmlRenderEnabled||P.renderTagTextEnabled)&&!d&&R({children:c.pages},e=>{"text"===e.type&&e.backgroundEnabled&&(e.legacyBackground=!0)}),delete c.schemaVersion;const g=r.activePage?r.pages.indexOf(r.activePage):0;let m=null===(s=c.pages[g]||c.pages[0])||void 0===s?void 0:s.id;c._activePageId=m;const u=Object.assign({},a(r));Object.assign(u,c),u.history=l?a(r.history):{history:[],undoIdx:-1,targetPath:""},t(r,u)},clear({keepHistory:e=!1}={}){const t=r.pages.map(e=>e.id);y.deletePages(t),r.custom=null,e||r.history.clear()},addFont(e){y.removeFont(e.fontFamily),r.fonts.push(e)},removeFont(e){r.fonts.filter(t=>t.fontFamily===e).forEach(e=>o(e))},addAudio(e){const t=F.create(Object.assign({id:c(10)},e));r.audios.push(t)},removeAudio(e){const t=r.audios.find(t=>t.id===e);t&&r.audios.remove(t)},async loadFont(e,t,i,o){const n=r.fonts.find(t=>t.fontFamily===e)||v.globalFonts.find(t=>t.fontFamily===e);let a=[{fontStyle:"normal",fontWeight:"normal"},{fontStyle:"normal",fontWeight:"bold"}];return n?(n.styles&&(a=n.styles.map(e=>({fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"normal"}))),v.injectCustomFont(n)):v.injectGoogleFont(e),t&&i&&!a.some(e=>e.fontStyle===t&&e.fontWeight===i)&&a.push({fontStyle:t,fontWeight:i}),Promise.all(a.map(t=>v.loadFont(e,t.fontStyle,t.fontWeight,o)))},validate:e=>Store.validate(e,[{path:"",type:Store}]).map(e=>({path:"store"+e.context.map(e=>e.path).join("."),message:e.message}))};return y});export function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){return y(e),Store.create({_forceShowCredit:t})}export default createStore;
1
+ var e=this&&this.__rest||function(e,t){var i={};for(var o in e){Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(i[o]=e[o])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++){t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(i[o[n]]=e[o[n]])}}return i};import{applySnapshot as t,cast as i,destroy as o,detach as n,getSnapshot as a,onSnapshot as s,setLivelinessChecking as r,types as l}from"mobx-state-tree";import{UndoManager as d}from"./history.js";import{nanoid as p}from"nanoid";import c from"konva";import{computed as g}from"mobx";import{ZERO_BLEED as m}from"@polotno/schema";import{downloadFile as u}from"../utils/download.js";import{getJsPDF as f}from"../utils/pdf.js";import{createGIF as h}from"../utils/gif-lib.js";import{validateKey as b,setKey as y}from"../utils/validate-key.js";import*as v from"../utils/fonts.js";import{flags as P}from"../utils/flags.js";import{addDpiMetadataToImage as w}from"../utils/image-dpi.js";import{nodeToCanvas as E}from"../utils/canvas.js";import{whenLoaded as x}from"../utils/loader.js";import{polotnoError as I}from"../utils/errors.js";import{pxToUnit as T}from"../utils/unit.js";import{deepEqual as _}from"../utils/deep-equal.js";import{waitTillAvailable as O}from"../utils/wait.js";import{jsonToHTML as k}from"../utils/to-html.js";import{jsonToSVG as S}from"../utils/to-svg.js";import{Page as j}from"./page-model.js";import{forEveryChild as R,forEveryNode as F}from"./group-model.js";import{Audio as A}from"./audio-model.js";r("ignore");export const Font=l.model("Font",{fontFamily:l.string,url:l.optional(l.string,""),styles:l.frozen()}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}));export const ROLES={ADMIN:"admin",VIEWER:"viewer"};export const Store=l.model("Store",{role:"",pages:l.array(j),fonts:l.array(Font),audios:l.array(A),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:l.optional(l.enumeration("UnitType",["pt","mm","cm","in","px"]),"px"),dpi:72,schemaVersion:4,bleedVisible:!1,rulesVisible:!1,distanceGuidesVisible:!1,timingPreview:l.optional(l.enumeration("TimingPreview",["all","playhead"]),"all"),openedSidePanel:"",previousOpenedSidePanel:"",custom:l.frozen(),tool:l.optional(l.enumeration("Tool",["selection","draw","pan","text","eraser"]),"selection"),toolOptions:l.optional(l.model({brushType:l.optional(l.enumeration("BrushType",["brush","highlighter"]),"brush"),strokeWidth:l.optional(l.number,5),stroke:l.optional(l.string,"#000000"),opacity:l.optional(l.number,1)}),{}),selectedElementsIds:l.array(l.string),animatedElementsIds:l.array(l.string),history:l.optional(d,{targetPath:"../pages"}),_elementsPixelRatio:Math.min(2,"undefined"!=typeof window&&window.devicePixelRatio||1),_activePageId:"",_selectedPagesIds:l.array(l.string),_forceShowCredit:!1,_validated:!1}).views(e=>{const t=g(()=>{const t={};return F({children:e.pages},e=>(t[e.id]=e,!1)),t},{keepAlive:!0});return{get _idsMap(){return t.get()}}}).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=>e._idsMap[t]).filter(e=>!!e)},get children(){return e.pages},get selectedShapes(){const e=[];return R({children:this.selectedElements},t=>{"group"!==t.type&&e.push(t)}),e},get activePage(){return e.pages.slice().find(t=>t.id===e._activePageId)||(e.pages.length?e.pages[0]:null)},get selectedPages(){return e._selectedPagesIds.map(t=>e.pages.find(e=>e.id===t))},get duration(){let t=0;return e.pages.forEach(e=>{t+=e.duration}),t},pageAtTime(t){for(const i of e.pages){if(t>=i.startTime&&t<i.startTime+i.duration){return i}}return e.pages.length&&t>=this.duration?e.pages[e.pages.length-1]:null},get effectiveTime(){if(e.isPlaying){return e.currentTime}const t=this.activePage;return t&&this.pageAtTime(e.currentTime)!==t?t.startTime:e.currentTime},get playheadAccurate(){return e.isPlaying||"playhead"===e.timingPreview},get isEditingPaused(){var t;return!e.isPlaying&&!(null===(t=this.activePage)||void 0===t?void 0:t._exportingOrRendering)},get _hasCroppedImages(){return this.find(e=>"image"===e.type&&e._cropModeEnabled)},find(t){let i;return F({children:e.pages},e=>{if(!i&&t(e)){return i=e,!0}}),i},getElementById:t=>e._idsMap[t]})).actions(r=>{let l=0,d=null,g=!1;const y={afterCreate(){r.history.canUndo},setCurrentTime(e){r.currentTime=e},_togglePlaying(e=!r.isPlaying){r.isPlaying=e},play({animatedElementsIds:e=[],startTime:t=0,currentTime:o=0,endTime:n=r.duration,repeat:a=!1}={}){o&&(console.warn("currentTime property of store.play() is deprecated. Please use startTime instead."),t=o),r.animatedElementsIds=i(e),r.currentTime=t,r.isPlaying=!0,l=Date.now(),d=n,g=a,requestAnimationFrame(()=>y.seek())},checkActivePage(){const e=r.pageAtTime(r.currentTime);e&&y.selectPage(e.id)},seek(){if(!r.isPlaying){return}const e=Date.now(),t=e-l;l=e,r.currentTime+=t;const i=d||r.duration;r.currentTime>=i&&!g&&(r.currentTime=i),y.checkActivePage(),r.isPlaying&&r.currentTime<i?requestAnimationFrame(()=>y.seek()):r.isPlaying&&g?(r.currentTime=0,requestAnimationFrame(()=>y.seek())):y.pause()},pause(){r.isPlaying=!1,r.animatedElementsIds=i([])},stop(){y.pause(),r.currentTime=0,y.checkActivePage()},__(){r._validated||(b(r._forceShowCredit),r._validated=!0)},set(e){Object.assign(r,e)},setUnit({unit:e,dpi:t}){r.unit=e||r.unit,r.dpi=t||r.dpi},setRole(e){r.role=e},setTool(e){r.tool=e},setToolOptions(e){Object.assign(r.toolOptions,e)},addPage(e){const t=j.create(Object.assign({id:p(10)},e));return r.pages.push(t),r._activePageId=t.id,t},selectPage(e){r._activePageId=e,1===r._selectedPagesIds.length&&(r._selectedPagesIds=i([e]))},selectPages(e){r._selectedPagesIds=i(e),1===r._selectedPagesIds.length&&(r._activePageId=r._selectedPagesIds[0])},selectElements(e){const t=e.map(e=>r.getElementById(e)).filter(e=>!!e);t.sort((e,t)=>{var i,o,n,a;return(null!==(o=null===(i=e.parent)||void 0===i?void 0:i.children.indexOf(e))&&void 0!==o?o:0)-(null!==(a=null===(n=t.parent)||void 0===n?void 0:n.children.indexOf(t))&&void 0!==a?a:0)}),r.selectedElementsIds=i(t.map(e=>e.id))},toggleBleed(e){r.bleedVisible=null!=e?e:!r.bleedVisible},toggleRulers(e){r.rulesVisible=null!=e?e:!r.rulesVisible},setTimingPreview(e){r.timingPreview=e},toggleDistanceGuides(e){r.distanceGuidesVisible=null!=e?e:!r.distanceGuidesVisible},openSidePanel(e){r.openedSidePanel!==e&&(r.previousOpenedSidePanel=r.openedSidePanel,r.openedSidePanel=e)},restoreSidePanel(){const e=r.previousOpenedSidePanel;e&&e!==r.openedSidePanel?r.openedSidePanel=e:r.openedSidePanel="photos"},setScale(e){r.scale=e},_setScaleToFit(e){r.scaleToFit=e},setElementsPixelRatio(e){r._elementsPixelRatio=e},setSize(e,t,i){r.pages.forEach(o=>{o.setSize({width:e,height:t,useMagic:i,softChange:!0})}),r.width=e,r.height=t},setPageZIndex(e,t){const i=r.pages.find(t=>t.id===e);i&&(n(i),r.pages.remove(i),r.pages.splice(t,0,i))},deletePages(e){const t=r.pages.indexOf(r.activePage);e.forEach(e=>{const t=r.pages.find(t=>t.id===e);o(t)});const n=Math.min(r.pages.length-1,t),a=r.pages[n];a&&(r._activePageId=a.id),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},groupElements(e,t={}){const o=e.map(e=>r.getElementById(e)).filter(e=>!!e);if(!o.length){return}const a=o[0].parent;if(!a){return}if(!o.every(e=>e.parent===a)){return void console.warn("store.groupElements: refusing to group elements that do not share a parent. Pass ids whose elements all live under the same page or the same group.")}o.forEach(e=>n(e));const s=a.children.reduce((e,t)=>{var i;if("group"===t.type){const o=null===(i=t.name)||void 0===i?void 0:i.match(/group-(\d+)/);if(o){const t=parseInt(o[1],10);return Math.max(e,t)}}return e},0),l=Object.assign({id:p(10),name:`group-${s+1}`,children:o,type:"group"},t);return a.children.push(l),r.selectedElementsIds=i([l.id]),a.children.find(e=>e.id===l.id)},ungroupElements(e){const t=e.map(e=>r.getElementById(e)),o=[];t.forEach(e=>{if(e&&"group"===e.type){const t=e.parent;if(!t){return}const i=t.children.indexOf(e);e.children.forEach(e=>{o.push(e.id)}),e.children.slice().forEach(e=>{n(e),t.children.push(e)}),t.children.splice(i,1)}}),r.selectedElementsIds=i(o)},deleteElements(e){const t=[];r.find(i=>(e.includes(i.id)&&t.push(i),!1)),t.forEach(e=>{o(e)}),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},on(e,t){if("change"===e){let e=y.toJSON();return s(r,i=>{const o=y.toJSON();!_(e,o)&&(e=o,t(o))})}},async _toCanvas({pixelRatio:e,ignoreBackground:t,pageId:i,mimeType:o,includeBleed:n,_skipTimeout:a,quickMode:s=!1,_exportCanvases:l}={}){var d;const p=e||1;i=i||(null===(d=r.pages[0])||void 0===d?void 0:d.id);const g=r.pages.find(e=>e.id===i);if(!g){throw I("EXPORT_FAILED",`No page for export with id ${i}`,{reason:"page-not-found",pageId:i,availablePageIds:r.pages.map(e=>e.id)})}const u=r._elementsPixelRatio;p>r._elementsPixelRatio&&y.setElementsPixelRatio(p),s?null==g||g.set({_forceMount:!0}):null==g||g.set({_exporting:!0});const f=await O(()=>{const e=c.stages.filter(e=>e.getAttr("pageId")===i);return 0===e.length?null:e});if(!f){throw null==g||g.set({_forceMount:!1,_exporting:!1}),y.setElementsPixelRatio(u),I("EXPORT_FAILED",`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.`,{reason:"workspace-not-mounted",pageId:i})}f.length>1&&console.error(`Polotno error: Detected several canvas elements for page "${i}" in the document. This is not supported and will lead to incorrect export. Make sure to use unique ids for all pages and make sure you unmount <Workspace /> when it is not needed.`);const h=f[0];await y.waitLoading({_skipTimeout:a});const b=h.findOne(".page-container");if(!b){throw y.setElementsPixelRatio(u),null==g||g.set({_forceMount:!1,_exporting:!1}),I("EXPORT_FAILED","Export is failed. Canvas was unmounted.",{reason:"unmounted-during-export",pageId:i})}const v=h.position();h.position({x:0,y:0}),h.find("Transformer").forEach(e=>{e.setAttr("oldVisible",e.visible()),e.visible(!1)}),b.find(".page-background").forEach(e=>e.shadowEnabled(!1)),b.find(".page-background").forEach(e=>e.strokeEnabled(!1)),b.find(".highlighter").forEach(e=>e.visible(!1));const P=b.findOne(".page-background-group"),w=P.clip();P.clip({x:null,y:null,width:null,height:null});const x=b.findOne(".elements-container"),T=x.clip();x.clip({x:null,y:null,width:null,height:null});const _=b.find(e=>!e.visible()&&e.getAttr("editModeEnabled")&&!e.getAttr("hideInExport"));_.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()});const k=b.find(e=>e.getAttr("hideInExport"));k.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()}),t&&b.find(".page-background").forEach(e=>e.hide());const S=n?g.computedBleed:m;let j=S.left,R=S.top;!r.bleedVisible&&n||(r.bleedVisible||n?r.bleedVisible&&n?(j=0,R=0):r.bleedVisible&&!n&&(j=-g.computedBleed.left,R=-g.computedBleed.top):(j=0,R=0));const F=g.computedWidth+S.left+S.right,A=g.computedHeight+S.top+S.bottom,C=b.scale();b.scale({x:1,y:1});const V=E(b,{x:b.x()-j,y:b.y()-R,width:F,height:A,pixelRatio:p,sceneCanvas:null==l?void 0:l.sceneCanvas,bufferCanvas:null==l?void 0:l.bufferCanvas});b.scale(C);const L=V._canvas;if("image/jpeg"===o){const e=L.getContext("2d");e.save(),e.globalCompositeOperation="destination-over",e.fillStyle="white",e.fillRect(0,0,L.width,L.height),e.restore()}return t&&b.find(".page-background").forEach(e=>e.show()),k.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),_.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),b.find(".page-background").forEach(e=>e.shadowEnabled(!0)),b.find(".page-background").forEach(e=>e.strokeEnabled(!0)),h.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),b.find(".highlighter").forEach(e=>e.visible(!0)),P.clip(w),x.clip(T),h.position(v),null==g||g.set({_exporting:!1,_forceMount:!1}),await Promise.resolve(),y.setElementsPixelRatio(u),L},async toDataURL(t={}){var{mimeType:i,quality:o,dpi:n,dpiMetadata:a="auto"}=t,s=e(t,["mimeType","quality","dpi","dpiMetadata"]);const l=await y._toCanvas(Object.assign({mimeType:i},s)),d=i||"image/png",p=l.toDataURL(d,o);c.Util.releaseCanvas(l);const g=null!=n?n:r.dpi;return"image/png"!==d&&"image/jpeg"!==d||"never"===a||"auto"===a&&72===g?p:w(p,d,g)},async toBlob(t={}){var{mimeType:i,quality:o}=t,n=e(t,["mimeType","quality"]);const a=await y._toCanvas(Object.assign({mimeType:i},n)),s=await new Promise(e=>{a.toBlob(e,i,o)});return c.Util.releaseCanvas(a),s},async saveAsImage(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=(o.mimeType||"image/png").split("/")[1];u(await y.toDataURL(o),i||"polotno."+n)},async _toPDF(e){const t=e.dpi||r.dpi,i=e.parallel||1,o=e.unit||("px"===r.unit?"mm":r.unit),n=e.pixelRatio||1,a=e.pageIds||(e.pageId?[e.pageId]:r.pages.map(e=>e.id)),s=r.pages.filter(e=>a.includes(e.id)),l=await f(),d=e=>T({px:e,unit:o,dpi:t}),p=e.cropMarkSize||0,c=d(p),g=s[0]||{},u=e.includeBleed&&g.computedBleed||m,h=d(g.computedWidth+u.left+u.right+2*c),b=d(g.computedHeight+u.top+u.bottom+2*c);var v=new l({unit:o,orientation:h>b?"landscape":"portrait",format:[h,b],compress:!0,putOnlyUsedFonts:!0});v.deletePage(1);const P=((e,t)=>{const i=[];for(let o=0;o<e.length;o+=t){i.push(e.slice(o,o+t))}return i})(s,i);let w=0;for(const r of P){const t=r.map(async t=>{const i=e.includeBleed?t.computedBleed:m,o=t.computedWidth+i.left+i.right+2*p,s=t.computedHeight+i.top+i.bottom+2*p,r=d(o),l=d(s);let c=0,g=n;for(;c<10;){c+=1;const d=await y.toDataURL(Object.assign(Object.assign({},e),{pageId:t.id,pixelRatio:g,dpiMetadata:"never"}));if(d.length>20){return g!==n&&console.error(`Polotno can not export PDF with current settings. Quality is automatically reduced. pixelRatio was reduced to ${parseFloat(g.toFixed(3))}.`),e.onProgress&&e.onProgress(++w/a.length*.9),{url:d,width:r,height:l,widthPx:o,heightPx:s,cb:i}}g*=.8}});(await Promise.all(t)).filter(e=>void 0!==e).forEach(({url:e,width:t,height:i,widthPx:n,heightPx:a,cb:s})=>{v.addPage([t,i],t>i?"landscape":"portrait");const r=v.getCurrentPageInfo();var l;switch(o){case"pt":l=1;break;case"mm":l=72/25.4;break;case"cm":l=72/2.54;break;case"in":l=72;break;case"px":l=.75;break;default:throw I("EXPORT_FAILED","Invalid unit: "+o,{reason:"invalid-options",option:"unit",value:o})}if(r.pageContext.cropBox={bottomLeftX:0,bottomLeftY:0,topRightX:t*l,topRightY:i*l},r.pageContext.artBox={bottomLeftX:d(p+s.left)*l,bottomLeftY:d(p+s.bottom)*l,topRightX:d(n-p-s.right)*l,topRightY:d(a-p-s.top)*l},r.pageContext.bleedBox={bottomLeftX:d(p+s.left)*l,bottomLeftY:d(p+s.bottom)*l,topRightX:d(n-p-s.right)*l,topRightY:d(a-p-s.top)*l},c){v.setLineWidth(d(1));const e=c+d(s.left),o=c+d(s.right),n=c+d(s.top),a=c+d(s.bottom);v.line(e,0,e,c),v.line(0,n,c,n),v.line(t-o,0,t-o,c),v.line(t,n,t-c,n),v.line(0,i-a,c,i-a),v.line(e,i,e,i-c),v.line(t,i-a,t-c,i-a),v.line(t-o,i,t-o,i-c)}v.addImage(e,c,c,t-2*c,i-2*c,void 0,"FAST")})}return v},toPDFDataURL:async e=>(await y._toPDF(Object.assign({mimeType:"image/jpeg"},e))).output("datauristring"),async toGIFDataURL(e={}){const t=e.pixelRatio||1,i=e.pageIds||(e.pageId?[e.pageId]:r.pages.map(e=>e.id)),o=r.pages.filter(e=>i.includes(e.id));if(!o.length){throw I("EXPORT_FAILED","No pages found for GIF export",{reason:"page-not-found",pageId:e.pageId,availablePageIds:r.pages.map(e=>e.id)})}const n=o[0],a=await h({width:n.computedWidth*t,height:n.computedHeight*t}),s=1e3/(e.fps||10);for(const l of o){const e=Math.max(1,Math.floor(l.duration/s));for(let i=0;i<e;i++){const e=l.startTime+i*s||1;y.setCurrentTime(e);for(const t of r.pages){t.set({_rendering:t.id===l.id})}const o=await y._toCanvas({pixelRatio:t,pageId:l.id,_skipTimeout:!0});a.addFrame(o.getContext("2d"),{delay:s,copy:!0})}}for(const l of r.pages){l.set({_rendering:!1})}return y.stop(),a.render(),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,o=e(t,["fileName"]);const n=await y.toGIFDataURL(o);u(n,i||"polotno.gif")},async toHTML({elementHook:e}={}){const t=y.toJSON();return k({json:t,elementHook:e})},async saveAsHTML({fileName:e,elementHook:t}={}){const i=await y.toHTML({elementHook:t}),o="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));u(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:t,fontEmbedding:i="inline"}={fontEmbedding:"inline"}){var o;const n=y.toJSON();t=t||(null===(o=n.pages[0])||void 0===o?void 0:o.id);const a=n.pages.find(e=>e.id===t);return S({json:Object.assign(Object.assign({},n),{pages:a?[a]:[]}),elementHook:e,fontEmbedding:i})},async saveAsSVG({fileName:e,elementHook:t,pageId:i,fontEmbedding:o="inline"}={}){const n=await y.toSVG({elementHook:t,pageId:i,fontEmbedding:o}),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(n)));u(a,e||"polotno.svg")},async saveAsPDF(t={}){var{fileName:i}=t,o=e(t,["fileName"]);(await y._toPDF(Object.assign({mimeType:"image/jpeg"},o))).save(i||"polotno.pdf")},async waitLoading({_skipTimeout:e=!1}={}){e||await new Promise(e=>setTimeout(e,50)),await x()},toJSON:()=>({width:r.width,height:r.height,fonts:a(r.fonts),pages:a(r.pages),audios:a(r.audios),unit:r.unit,dpi:r.dpi,custom:r.custom,schemaVersion:r.schemaVersion}),loadJSON(e,i=!1){var o,n,s;const l="boolean"==typeof i?i:null!==(o=null==i?void 0:i.keepHistory)&&void 0!==o&&o,d="boolean"!=typeof i&&null!==(n=null==i?void 0:i.modernizeTextBackground)&&void 0!==n&&n,p=JSON.parse(JSON.stringify(e)),c=p.schemaVersion||0;c<1&&(P.htmlRenderEnabled||P.renderTagTextEnabled)&&F({children:p.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),c<2&&F({children:p.pages},e=>{e.filters&&Object.keys(e.filters).forEach(t=>{if(["warm","cold","natural"].includes(t)){return}const i=e.filters[t];i&&"number"==typeof i.intensity&&(i.intensity=i.intensity/100)})}),c<3&&(P.htmlRenderEnabled||P.renderTagTextEnabled)&&!d&&F({children:p.pages},e=>{"text"===e.type&&e.backgroundEnabled&&(e.legacyBackground=!0)}),delete p.schemaVersion;const g=r.activePage?r.pages.indexOf(r.activePage):0;let m=null===(s=p.pages[g]||p.pages[0])||void 0===s?void 0:s.id;p._activePageId=m;const u=Object.assign({},a(r));Object.assign(u,p),u.history=l?a(r.history):{history:[],undoIdx:-1,targetPath:""},t(r,u)},clear({keepHistory:e=!1}={}){const t=r.pages.map(e=>e.id);y.deletePages(t),r.custom=null,e||r.history.clear()},addFont(e){y.removeFont(e.fontFamily),r.fonts.push(e)},removeFont(e){r.fonts.filter(t=>t.fontFamily===e).forEach(e=>o(e))},addAudio(e){const t=A.create(Object.assign({id:p(10)},e));r.audios.push(t)},removeAudio(e){const t=r.audios.find(t=>t.id===e);t&&r.audios.remove(t)},async loadFont(e,t,i,o){const n=r.fonts.find(t=>t.fontFamily===e)||v.globalFonts.find(t=>t.fontFamily===e);let a=[{fontStyle:"normal",fontWeight:"normal"},{fontStyle:"normal",fontWeight:"bold"}];return n?(n.styles&&(a=n.styles.map(e=>({fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"normal"}))),v.injectCustomFont(n)):v.injectGoogleFont(e),t&&i&&!a.some(e=>e.fontStyle===t&&e.fontWeight===i)&&a.push({fontStyle:t,fontWeight:i}),Promise.all(a.map(t=>v.loadFont(e,t.fontStyle,t.fontWeight,o)))},validate:e=>Store.validate(e,[{path:"",type:Store}]).map(e=>({path:"store"+e.context.map(e=>e.path).join("."),message:e.message}))};return y});export function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){return y(e),Store.create({_forceShowCredit:t})}export default createStore;
@@ -65,6 +65,7 @@ export declare const TextElement: import("mobx-state-tree").IModelType<{
65
65
  verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
66
66
  strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
67
67
  stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
68
+ strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
68
69
  lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
69
70
  letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
70
71
  _editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
@@ -1 +1 @@
1
- import{types as e}from"mobx-state-tree";import{Shape as t}from"./shape-model.js";const n=e=>{if("string"!=typeof e){return e}const t=e.trim().match(/^(-?\d*\.?\d+)(%?)$/);if(!t){return e}const n=parseFloat(t[1]);return t[2]?n/100:n};export const TextElement=t.named("Text").props({type:"text",text:"",placeholder:"",fontSize:14,fontFamily:"Roboto",fontStyle:"normal",fontWeight:"normal",textDecoration:"",textTransform:"none",fill:"black",align:"center",width:100,height:0,verticalAlign:"top",strokeWidth:0,stroke:"black",lineHeight:e.optional(e.union(e.number,e.string),1.2),letterSpacing:0,_editModeEnabled:!1,backgroundEnabled:!1,backgroundColor:"#7ED321",backgroundOpacity:1,backgroundCornerRadius:.5,backgroundPadding:.5,legacyBackground:e.maybe(e.boolean),curveEnabled:!1,curvePower:.5}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontSize:null!=e.fontSize&&e.fontSize<1?1:e.fontSize,lineHeight:n(e.lineHeight)})).actions(e=>{const t=e.set;return{set(e){null!=e.fontSize&&e.fontSize<1&&(e=Object.assign(Object.assign({},e),{fontSize:1})),"string"==typeof e.lineHeight&&(e=Object.assign(Object.assign({},e),{lineHeight:n(e.lineHeight)})),t(e)},afterCreate(){if(!e.height){const t=e.lineHeight,n="number"==typeof t?t:parseFloat(t)||1.2;e.height=Math.round(e.fontSize*n)}},toggleEditMode(t){const n=null!=t?t:!e._editModeEnabled;n!==e._editModeEnabled&&(e._editModeEnabled=n,e._editModeEnabled?e.store.history.startTransaction():e.store.history.endTransaction())},beforeDestroy(){e._editModeEnabled&&e.store.history.endTransaction()}}});
1
+ import{types as e}from"mobx-state-tree";import{Shape as t}from"./shape-model.js";const n=e=>{if("string"!=typeof e){return e}const t=e.trim().match(/^(-?\d*\.?\d+)(%?)$/);if(!t){return e}const n=parseFloat(t[1]);return t[2]?n/100:n};export const TextElement=t.named("Text").props({type:"text",text:"",placeholder:"",fontSize:14,fontFamily:"Roboto",fontStyle:"normal",fontWeight:"normal",textDecoration:"",textTransform:"none",fill:"black",align:"center",width:100,height:0,verticalAlign:"top",strokeWidth:0,stroke:"black",strokeLineJoin:"round",lineHeight:e.optional(e.union(e.number,e.string),1.2),letterSpacing:0,_editModeEnabled:!1,backgroundEnabled:!1,backgroundColor:"#7ED321",backgroundOpacity:1,backgroundCornerRadius:.5,backgroundPadding:.5,legacyBackground:e.maybe(e.boolean),curveEnabled:!1,curvePower:.5}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontSize:null!=e.fontSize&&e.fontSize<1?1:e.fontSize,lineHeight:n(e.lineHeight)})).actions(e=>{const t=e.set;return{set(e){null!=e.fontSize&&e.fontSize<1&&(e=Object.assign(Object.assign({},e),{fontSize:1})),"string"==typeof e.lineHeight&&(e=Object.assign(Object.assign({},e),{lineHeight:n(e.lineHeight)})),t(e)},afterCreate(){if(!e.height){const t=e.lineHeight,n="number"==typeof t?t:parseFloat(t)||1.2;e.height=Math.round(e.fontSize*n)}},toggleEditMode(t){const n=null!=t?t:!e._editModeEnabled;n!==e._editModeEnabled&&(e._editModeEnabled=n,e._editModeEnabled?e.store.history.startTransaction():e.store.history.endTransaction())},beforeDestroy(){e._editModeEnabled&&e.store.history.endTransaction()}}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polotno",
3
- "version": "4.2.2",
3
+ "version": "4.3.0",
4
4
  "description": "Design Editor Framework",
5
5
  "author": "Anton Lavrenov",
6
6
  "keywords": [
@@ -96,7 +96,7 @@
96
96
  },
97
97
  "dependencies": {
98
98
  "@base-ui/react": "^1.5.0",
99
- "@polotno/schema": "0.1.6",
99
+ "@polotno/schema": "0.2.0",
100
100
  "class-variance-authority": "^0.7.1",
101
101
  "clsx": "^2.1.1",
102
102
  "gifuct-js": "^2.1.2",
@@ -115,7 +115,7 @@
115
115
  "react-konva-utils": "^2.0.0",
116
116
  "react-sortablejs": "6.1.4",
117
117
  "react-window": "^1.8.11",
118
- "render-tag": "^0.1.16",
118
+ "render-tag": "^0.1.17",
119
119
  "sortablejs": "^1.15.7",
120
120
  "svg-round-corners": "^0.4.3",
121
121
  "swr": "^2.4.1",
@@ -1 +1 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import o from"react";import{observer as n}from"mobx-react-lite";import{nodeReaction as i}from"../utils/mobx.js";import{onSnapshot as s}from"mobx-state-tree";import{PolotnoIcon as a}from"../icons/registry.js";import{flags as r}from"../utils/flags.js";import{t as l}from"../utils/l10n.js";import{deepEqual as d}from"../utils/deep-equal.js";import{DropdownMenu as c,DropdownMenuContent as p,DropdownMenuItem as u}from"../primitives/dropdown-menu.js";import{Spinner as g}from"./spinner.js";import{TrackMenuButton as m}from"./track-styles.js";let h=[],f=!1;const v=async()=>{if(f||0===h.length){return}f=!0;const{page:e,setPreview:t}=h.shift();try{t(await e.store.toDataURL({pageId:e.id,pixelRatio:.1,quickMode:!0}))}catch(o){o instanceof Error&&"string"==typeof o.message&&(o.message.includes("Canvas was unmounted.")||o.message.includes("<Workspace /> component is not mounted"))||console.error(o)}finally{f=!1}v()};export const usePagePreview=({page:e,setPreview:t,groupRef:n})=>{const a=o.useRef(!1);o.useEffect(()=>{const o=()=>{h.push({page:e,setPreview:e=>t(e)}),v()};let r=null,l=null,c=Date.now();const p=()=>{r&&clearTimeout(r),a.current&&(l||(l=setTimeout(()=>{Date.now()-c>=6e3&&(o(),c=Date.now(),l=null)},6e3)),r=setTimeout(()=>{o(),c=Date.now(),r=null,l&&(clearTimeout(l),l=null)},300))};let u=null;const g=s(e,e=>{d(u,e)||(p(),u=e)}),m=i(e,()=>e.children.some(e=>e._editModeEnabled),e=>{e||p()}),f=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting?(a.current=!0,p()):(r&&clearTimeout(r),l&&clearTimeout(l),a.current=!1)})},{threshold:.1});return n.current&&f.observe(n.current),()=>{f.disconnect(),r&&clearTimeout(r),l&&clearTimeout(l),g(),m(),h=h.filter(t=>t.page!==e)}},[n,e,t])};export const PagePreview=n(({page:n,scale:i})=>{const[s,d]=o.useState(null),[h,f]=o.useState(!1),v=n.store.activePage===n||n.store._selectedPagesIds.includes(n.id),x=o.useRef(null),b=n.store.pages.indexOf(n),w=60/n.computedHeight*n.computedWidth,P=r.animationsEnabled?n.duration*i:w,y=n.store.pages.length>1;o.useLayoutEffect(()=>{x.current&&(x.current.style.width=P+"px")},[b,P]),usePagePreview({page:n,setPreview:d,groupRef:x});const{handleStartDrag:E}=((e,t)=>({handleStartDrag:o.useCallback((o,n)=>{o.preventDefault();const i=o=>{if(o.preventDefault(),!t.current){return}const i="start"===n?7:-7,{clientX:s}=o,{left:a,width:r}=t.current.getBoundingClientRect(),l=(s-a-i)/r;"end"===n&&e.set({duration:Math.max(1e3,l*e.duration)})},s=()=>{window.removeEventListener("mousemove",i),window.removeEventListener("mouseup",s)};window.addEventListener("mousemove",i),window.addEventListener("mouseup",s)},[t,e])}))(n,x);return t("div",{ref:x,style:{width:P+"px",marginRight:r.animationsEnabled?"0px":"10px",height:"60px",display:"flex",position:"relative",borderRadius:"15px",boxShadow:"0 1px 4px rgba(0, 0, 0, 0.18)"},onMouseEnter:()=>f(!0),onMouseLeave:()=>f(!1),className:"polotno-page-container"+(v?" sortable-selected":""),children:[e("div",{style:{width:"100%",height:"100%",borderRadius:"15px",backgroundImage:s?`url("${s}")`:"none",backgroundRepeat:"repeat-x",backgroundSize:"auto 100%",backgroundColor:"white",display:"flex",justifyContent:"center",alignItems:"center"},onClick:e=>{const{store:t}=n,o=t._selectedPagesIds.length?t._selectedPagesIds:t.activePage?[t.activePage.id]:[],i=o.includes(n.id),s=e.shiftKey;if(s&&i){const e=o.filter(e=>e!==n.id);t.selectPages(e)}else if(s&&!i){const e=o.concat([n.id]);t.selectPages(e)}else{t.selectPages([n.id])}},children:!s&&e(g,{})}),e("div",{style:{position:"absolute",top:"0",left:"0px",bottom:"0px",right:"0px",borderRadius:"15px",border:v?"2px solid rgb(0, 161, 255, 0.9)":"2px solid var(--pn-border)",zIndex:1,pointerEvents:"none"}}),r.animationsEnabled&&t("div",{style:{position:"absolute",zIndex:1,bottom:"5px",left:"5px",backgroundColor:"rgba(0, 0, 0, 0.5)",color:"white",padding:"2px 7px",textAlign:"center",borderRadius:"4rem"},children:[(n.duration/1e3).toFixed(1),"s"]}),r.animationsEnabled&&e("div",{style:{position:"absolute",zIndex:1,top:"50%",right:"0px",width:"8px",height:"50%",transform:"translateY(-50%) translateX(-3px)",borderRadius:"5px",border:"1px solid rgb(255, 255, 255, 0.6)",backgroundColor:"rgb(0, 0, 0, 0.6)",cursor:"ew-resize"},onMouseDown:e=>E(e,"end")}),v&&e("div",{className:"polotno-page-menu",style:{position:"absolute",zIndex:20,top:"5px",right:"5px",opacity:h?1:0,pointerEvents:h?"auto":"none",transition:"opacity 0.15s"},onClick:e=>{e.stopPropagation()},children:t(c,{children:[e(m,{}),t(p,{side:"top",className:"pn:whitespace-nowrap",children:[t(u,{onSelect:e=>{e.preventDefault();const t=n.store,o=(t.selectedPages||[]).filter(Boolean),i=o.length?o:t.activePage?[t.activePage]:[];if(!i.length){return}const s=new Set(i.map(e=>e.id)),a=t.pages.filter(e=>s.has(e.id)),r=a[a.length-1],l=a.map(e=>e.clone()),d=t.pages.indexOf(r);l.forEach((e,t)=>{e.setZIndex(d+1+t)}),t.selectPages(l.map(e=>e.id))},children:[e(a,{name:"action.duplicate",className:"pn:size-4"}),l("pagesTimeline.duplicatePage")]}),t(u,{onSelect:e=>{var t,o,i;e.preventDefault();const s=n.store.addPage({bleed:(null===(t=n.store.activePage)||void 0===t?void 0:t.bleed)||0,width:(null===(o=n.store.activePage)||void 0===o?void 0:o.width)||"auto",height:(null===(i=n.store.activePage)||void 0===i?void 0:i.height)||"auto"}),a=n.store.pages.indexOf(n);s.setZIndex(a+1)},children:[e(a,{name:"action.add",className:"pn:size-4"}),l("pagesTimeline.addPage")]}),y&&t(u,{onSelect:e=>{e.preventDefault();const t=n.store,o=(t.selectedPages||[]).filter(Boolean),i=o.length?o.map(e=>e.id):t.activePage?[t.activePage.id]:[];i.length&&t.deletePages(i)},children:[e(a,{name:"action.remove",className:"pn:size-4"}),l("pagesTimeline.removePage")]})]})]})})]})});
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import o from"react";import{observer as n}from"mobx-react-lite";import{nodeReaction as i}from"../utils/mobx.js";import{onSnapshot as s}from"mobx-state-tree";import{PolotnoIcon as a}from"../icons/registry.js";import{flags as r}from"../utils/flags.js";import{t as l}from"../utils/l10n.js";import{deepEqual as d}from"../utils/deep-equal.js";import{DropdownMenu as c,DropdownMenuContent as p,DropdownMenuItem as u}from"../primitives/dropdown-menu.js";import{Spinner as g}from"./spinner.js";import{TrackMenuButton as m}from"./track-styles.js";let v=[],h=!1;const f=async()=>{var e;if(h||0===v.length){return}h=!0;const{page:t,setPreview:o}=v.shift();try{o(await t.store.toDataURL({pageId:t.id,pixelRatio:.1,quickMode:!0}))}catch(n){"EXPORT_FAILED"===(null==n?void 0:n.code)&&["workspace-not-mounted","unmounted-during-export"].includes(null===(e=n.details)||void 0===e?void 0:e.reason)||n instanceof Error&&"string"==typeof n.message&&(n.message.includes("Canvas was unmounted.")||n.message.includes("<Workspace /> component is not mounted"))||console.error(n)}finally{h=!1}f()};export const usePagePreview=({page:e,setPreview:t,groupRef:n})=>{const a=o.useRef(!1);o.useEffect(()=>{const o=()=>{v.push({page:e,setPreview:e=>t(e)}),f()};let r=null,l=null,c=Date.now();const p=()=>{r&&clearTimeout(r),a.current&&(l||(l=setTimeout(()=>{Date.now()-c>=6e3&&(o(),c=Date.now(),l=null)},6e3)),r=setTimeout(()=>{o(),c=Date.now(),r=null,l&&(clearTimeout(l),l=null)},300))};let u=null;const g=s(e,e=>{d(u,e)||(p(),u=e)}),m=i(e,()=>e.children.some(e=>e._editModeEnabled),e=>{e||p()}),h=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting?(a.current=!0,p()):(r&&clearTimeout(r),l&&clearTimeout(l),a.current=!1)})},{threshold:.1});return n.current&&h.observe(n.current),()=>{h.disconnect(),r&&clearTimeout(r),l&&clearTimeout(l),g(),m(),v=v.filter(t=>t.page!==e)}},[n,e,t])};export const PagePreview=n(({page:n,scale:i})=>{const[s,d]=o.useState(null),[v,h]=o.useState(!1),f=n.store.activePage===n||n.store._selectedPagesIds.includes(n.id),x=o.useRef(null),b=n.store.pages.indexOf(n),w=60/n.computedHeight*n.computedWidth,P=r.animationsEnabled?n.duration*i:w,y=n.store.pages.length>1;o.useLayoutEffect(()=>{x.current&&(x.current.style.width=P+"px")},[b,P]),usePagePreview({page:n,setPreview:d,groupRef:x});const{handleStartDrag:E}=((e,t)=>({handleStartDrag:o.useCallback((o,n)=>{o.preventDefault();const i=o=>{if(o.preventDefault(),!t.current){return}const i="start"===n?7:-7,{clientX:s}=o,{left:a,width:r}=t.current.getBoundingClientRect(),l=(s-a-i)/r;"end"===n&&e.set({duration:Math.max(1e3,l*e.duration)})},s=()=>{window.removeEventListener("mousemove",i),window.removeEventListener("mouseup",s)};window.addEventListener("mousemove",i),window.addEventListener("mouseup",s)},[t,e])}))(n,x);return t("div",{ref:x,style:{width:P+"px",marginRight:r.animationsEnabled?"0px":"10px",height:"60px",display:"flex",position:"relative",borderRadius:"15px",boxShadow:"0 1px 4px rgba(0, 0, 0, 0.18)"},onMouseEnter:()=>h(!0),onMouseLeave:()=>h(!1),className:"polotno-page-container"+(f?" sortable-selected":""),children:[e("div",{style:{width:"100%",height:"100%",borderRadius:"15px",backgroundImage:s?`url("${s}")`:"none",backgroundRepeat:"repeat-x",backgroundSize:"auto 100%",backgroundColor:"white",display:"flex",justifyContent:"center",alignItems:"center"},onClick:e=>{const{store:t}=n,o=t._selectedPagesIds.length?t._selectedPagesIds:t.activePage?[t.activePage.id]:[],i=o.includes(n.id),s=e.shiftKey;if(s&&i){const e=o.filter(e=>e!==n.id);t.selectPages(e)}else if(s&&!i){const e=o.concat([n.id]);t.selectPages(e)}else{t.selectPages([n.id])}},children:!s&&e(g,{})}),e("div",{style:{position:"absolute",top:"0",left:"0px",bottom:"0px",right:"0px",borderRadius:"15px",border:f?"2px solid rgb(0, 161, 255, 0.9)":"2px solid var(--pn-border)",zIndex:1,pointerEvents:"none"}}),r.animationsEnabled&&t("div",{style:{position:"absolute",zIndex:1,bottom:"5px",left:"5px",backgroundColor:"rgba(0, 0, 0, 0.5)",color:"white",padding:"2px 7px",textAlign:"center",borderRadius:"4rem"},children:[(n.duration/1e3).toFixed(1),"s"]}),r.animationsEnabled&&e("div",{style:{position:"absolute",zIndex:1,top:"50%",right:"0px",width:"8px",height:"50%",transform:"translateY(-50%) translateX(-3px)",borderRadius:"5px",border:"1px solid rgb(255, 255, 255, 0.6)",backgroundColor:"rgb(0, 0, 0, 0.6)",cursor:"ew-resize"},onMouseDown:e=>E(e,"end")}),f&&e("div",{className:"polotno-page-menu",style:{position:"absolute",zIndex:20,top:"5px",right:"5px",opacity:v?1:0,pointerEvents:v?"auto":"none",transition:"opacity 0.15s"},onClick:e=>{e.stopPropagation()},children:t(c,{children:[e(m,{}),t(p,{side:"top",className:"pn:whitespace-nowrap",children:[t(u,{onSelect:e=>{e.preventDefault();const t=n.store,o=(t.selectedPages||[]).filter(Boolean),i=o.length?o:t.activePage?[t.activePage]:[];if(!i.length){return}const s=new Set(i.map(e=>e.id)),a=t.pages.filter(e=>s.has(e.id)),r=a[a.length-1],l=a.map(e=>e.clone()),d=t.pages.indexOf(r);l.forEach((e,t)=>{e.setZIndex(d+1+t)}),t.selectPages(l.map(e=>e.id))},children:[e(a,{name:"action.duplicate",className:"pn:size-4"}),l("pagesTimeline.duplicatePage")]}),t(u,{onSelect:e=>{var t,o,i;e.preventDefault();const s=n.store.addPage({bleed:(null===(t=n.store.activePage)||void 0===t?void 0:t.bleed)||0,width:(null===(o=n.store.activePage)||void 0===o?void 0:o.width)||"auto",height:(null===(i=n.store.activePage)||void 0===i?void 0:i.height)||"auto"}),a=n.store.pages.indexOf(n);s.setZIndex(a+1)},children:[e(a,{name:"action.add",className:"pn:size-4"}),l("pagesTimeline.addPage")]}),y&&t(u,{onSelect:e=>{e.preventDefault();const t=n.store,o=(t.selectedPages||[]).filter(Boolean),i=o.length?o.map(e=>e.id):t.activePage?[t.activePage.id]:[];i.length&&t.deletePages(i)},children:[e(a,{name:"action.remove",className:"pn:size-4"}),l("pagesTimeline.removePage")]})]})]})})]})});