polotno 4.2.1 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blueprint/pages-timeline/page-preview.js +2 -2
- package/blueprint/toolbar/html-toolbar.js +3 -3
- package/canvas/apply-filters.d.ts +11 -0
- package/canvas/apply-filters.js +1 -1
- package/canvas/audio.js +1 -1
- package/canvas/element.js +1 -1
- package/canvas/gif-element.js +1 -1
- package/canvas/hotkeys.d.ts +8 -0
- package/canvas/hotkeys.js +1 -1
- package/canvas/html-element.js +1 -1
- package/canvas/image-element.js +1 -1
- package/canvas/render-tag-element.js +1 -1
- package/canvas/rich-editor.js +2 -2
- package/canvas/table-element.js +1 -1
- package/canvas/text-element/fit-font-size.js +1 -1
- package/canvas/text-element.js +1 -1
- package/canvas/tooltip.js +1 -1
- package/canvas/use-filtered-source.d.ts +2 -0
- package/canvas/use-filtered-source.js +1 -0
- package/canvas/use-mediabunny-video.js +1 -1
- package/canvas/video-element.d.ts +1 -1
- package/canvas/video-element.js +1 -1
- package/canvas/workspace-canvas.d.ts +2 -1
- package/canvas/workspace-canvas.js +1 -1
- package/model/group-model.d.ts +1 -0
- package/model/group-model.js +1 -1
- package/model/page-model.d.ts +1 -0
- package/model/store.d.ts +9 -0
- package/model/store.js +1 -1
- package/model/text-model.d.ts +1 -0
- package/model/text-model.js +1 -1
- package/package.json +3 -3
- package/pages-timeline/page-preview.js +1 -1
- package/polotno.bundle.js +127 -126
- package/side-panel/effects-panel.js +1 -1
- package/side-panel/upload-panel.d.ts +1 -3
- package/side-panel/upload-panel.js +1 -1
- package/toolbar/html-toolbar.js +3 -3
- package/utils/base64.d.ts +2 -0
- package/utils/base64.js +1 -0
- package/utils/clipboard.d.ts +361 -0
- package/utils/clipboard.js +1 -1
- package/utils/errors.d.ts +7 -0
- package/utils/errors.js +1 -0
- package/utils/file.d.ts +6 -0
- package/utils/file.js +1 -1
- package/utils/fonts.js +1 -1
- package/utils/image-dpi.js +1 -1
- package/utils/insert-file.d.ts +23 -0
- package/utils/insert-file.js +1 -0
- package/utils/l10n.d.ts +4 -0
- package/utils/l10n.js +1 -1
- package/utils/loader.d.ts +3 -2
- package/utils/loader.js +1 -1
- package/utils/mobx.d.ts +4 -0
- package/utils/mobx.js +1 -0
- package/utils/text-html.d.ts +1 -0
- package/utils/text-html.js +1 -1
- package/utils/text-types.d.ts +2 -0
- package/utils/text-types.js +1 -1
- package/utils/to-html.js +1 -1
- package/utils/to-svg.js +1 -1
- package/utils/validate-key.js +1 -1
- package/utils/video.js +1 -1
package/utils/image-dpi.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{decodeBase64 as t,encodeBase64 as e}from"./base64.js";const n=[112,72,89,115],r=(()=>{const t=new Uint32Array(256);for(let e=0;e<256;e++){let n=e;for(let t=0;t<8;t++){n=1&n?3988292384^n>>>1:n>>>1}t[e]=n>>>0}return t})(),s=(t,e,n)=>{t[e]=n>>>24&255,t[e+1]=n>>>16&255,t[e+2]=n>>>8&255,t[e+3]=255&n};export const addDpiMetadataToImage=(o,l,a)=>{const i=o.indexOf(","),f=i>=0?o.slice(i+1):o,c=t(f),g="image/png"===l?((t,e)=>{const o=(t=>{const e=new Uint8Array(9),o=new DataView(e.buffer);o.setUint32(0,t,!1),o.setUint32(4,t,!1),e[8]=1;const l=new Uint8Array(8+e.length+4);s(l,0,e.length),l.set(n,4),l.set(e,8);const a=new Uint8Array(4+e.length);return a.set(n,0),a.set(e,4),s(l,8+e.length,(t=>{let e=4294967295;for(let n=0;n<t.length;n++){e=r[255&(e^t[n])]^e>>>8}return(4294967295^e)>>>0})(a)),l})(Math.round(e/.0254)),l=((t,e)=>{let n=8;for(;n+8<=t.length;){const r=t[n]<<24|t[n+1]<<16|t[n+2]<<8|t[n+3],s=n+4,o=t.subarray(s,s+4),l=8+r+4;if(e.every((t,e)=>o[e]===t)){return{offset:n,totalLength:l}}n+=l}return null})(t,n);if(l){const e=new Uint8Array(t.length-l.totalLength+o.length);return e.set(t.slice(0,l.offset),0),e.set(o,l.offset),e.set(t.slice(l.offset+l.totalLength),l.offset+o.length),e}const a=16+(t[8]<<24|t[9]<<16|t[10]<<8|t[11])+4;if(a>t.length){return t}const i=new Uint8Array(t.length+o.length);return i.set(t.slice(0,a),0),i.set(o,a),i.set(t.slice(a),a+o.length),i})(c,a):((t,e)=>{const n=(t=>{let e=2;for(;e+4<t.length;){if(255!==t[e]){return-1}const n=t[e+1];if(216===n||217===n){e+=2;continue}const r=t[e+2]<<8|t[e+3];if(r<2){return-1}if(224===n&&74===t[e+4]&&70===t[e+5]&&73===t[e+6]&&70===t[e+7]&&0===t[e+8]){return e}const s=e+2+r;if(s<=e||s>t.length){return-1}e=s}return-1})(t);if(n>=0){const r=new Uint8Array(t),s=n+11;return r[s]=1,r[s+1]=e>>8&255,r[s+2]=255&e,r[s+3]=e>>8&255,r[s+4]=255&e,r}const r=(t=>{const e=new Uint8Array(18);return e[0]=255,e[1]=224,e[2]=0,e[3]=16,e[4]=74,e[5]=70,e[6]=73,e[7]=70,e[8]=0,e[9]=1,e[10]=1,e[11]=1,e[12]=t>>8&255,e[13]=255&t,e[14]=t>>8&255,e[15]=255&t,e})(e),s=new Uint8Array(t.length+r.length);return s.set(t.subarray(0,2),0),s.set(r,2),s.set(t.subarray(2),2+r.length),s})(c,a);return`data:${l};base64,${e(g)}`};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { StoreType, ShapeType } from '../ui-types.js';
|
|
2
|
+
import { MediaType } from './file.js';
|
|
3
|
+
type MediaProps = {
|
|
4
|
+
url: string;
|
|
5
|
+
type: MediaType;
|
|
6
|
+
store: StoreType;
|
|
7
|
+
droppedPos?: {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
};
|
|
11
|
+
targetElement?: ShapeType;
|
|
12
|
+
};
|
|
13
|
+
export declare const insertMediaIntoPage: ({ url, type, store, droppedPos, targetElement, }: MediaProps) => Promise<void>;
|
|
14
|
+
type FileProps = {
|
|
15
|
+
file: File;
|
|
16
|
+
store: StoreType;
|
|
17
|
+
droppedPos?: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export declare const insertFileIntoPage: ({ file, store, droppedPos }: FileProps) => Promise<void>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getType as e,getUploadFunc as t}from"./file.js";import{selectImage as o}from"../side-panel/select-image.js";import{selectVideo as s}from"../side-panel/select-video.js";import{selectSvg as r}from"../side-panel/select-svg.js";import{selectGif as a}from"../side-panel/select-gif.js";export const insertMediaIntoPage=async({url:e,type:t,store:i,droppedPos:p,targetElement:d})=>{const n=e;"image"===t?await o({src:n,store:i,droppedPos:p,targetElement:d}):"svg"===t?await r({src:n,store:i,droppedPos:p,targetElement:d}):"gif"===t?await a({src:n,store:i,droppedPos:p,targetElement:d}):"video"===t?await s({src:n,store:i,droppedPos:p,targetElement:d}):"audio"===t&&i.addAudio({src:n})};export const insertFileIntoPage=async({file:o,store:s,droppedPos:r})=>{const a=await t()(o);await insertMediaIntoPage({url:a,type:e(o),store:s,droppedPos:r})};
|
package/utils/l10n.d.ts
CHANGED
|
@@ -28,6 +28,10 @@ export declare const getTranslations: () => {
|
|
|
28
28
|
natural: string;
|
|
29
29
|
warm: string;
|
|
30
30
|
textStroke: string;
|
|
31
|
+
strokeLineJoin: string;
|
|
32
|
+
joinRound: string;
|
|
33
|
+
joinMiter: string;
|
|
34
|
+
joinBevel: string;
|
|
31
35
|
shadow: string;
|
|
32
36
|
border: string;
|
|
33
37
|
cornerRadius: string;
|
package/utils/l10n.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{observable as e,action as o,toJS as r}from"mobx";const a=e({toolbar:{duration:"Duration",opacity:"Opacity",effects:"Effects",blur:"Blur",curvedText:"Curved text",curvePower:"Power",temperature:"Temperature",saturation:"Saturation",contrast:"Contrast",shadows:"Shadows",white:"White",black:"Black",vibrance:"Vibrance",textBackground:"Background",backgroundCornerRadius:"Corner radius",backgroundOpacity:"Opacity",backgroundPadding:"Padding",brightness:"Brightness",filters:"Filters",sepia:"Sepia",grayscale:"Grayscale",cold:"Cold",natural:"Natural",warm:"Warm",textStroke:"Text Stroke",shadow:"Shadow",border:"Border",cornerRadius:"Corner Radius",copyStyle:"Copy style",uppercase:"Uppercase",position:"Position",layering:"Layering",toForward:"To Front",up:"Forward",down:"Backward",toBottom:"To back",alignLeft:"Align left",alignCenter:"Align center",alignRight:"Align right",alignTop:"Align top",alignMiddle:"Align middle",alignBottom:"Align bottom",flip:"Flip",flipHorizontally:"Flip horizontally",flipVertically:"Flip vertically",fitToBackground:"Fit to page",removeBackground:"Remove background",removeBackgroundTitle:"Remove background from image",cancelRemoveBackground:"Cancel",confirmRemoveBackground:"Confirm",crop:"Crop",cropDone:"Done",cropCancel:"Cancel",clip:"Apply mask",removeClip:"Remove mask",removeMask:"Remove mask",transparency:"Transparency",lockedDescription:"Object is locked. Unlock it to allow changes from canvas.",unlockedDescription:"Object is unlocked. Lock it to prevent changes from canvas.",removeElements:"Remove elements",duplicateElements:"Duplicate elements",download:"Download",saveAsImage:"Save as image",saveAsPDF:"Save as PDF",lineHeight:"Line height",letterSpacing:"Letter spacing",offsetX:"Offset X",offsetY:"Offset Y",color:"Color",selectable:"Selectable",draggable:"Draggable",removable:"Removable",resizable:"Resizable",contentEditable:"Can change content",styleEditable:"Can change style",alwaysOnTop:"Always on top",showInExport:"Show in export",ungroupElements:"Ungroup",groupElements:"Group",lineSize:"Line size",fade:"Fade",move:"Move",zoom:"Zoom",animate:"Animate",rotate:"Rotate",none:"None",bounce:"Bounce",blink:"Blink",strength:"Strength",spaceEvenly:"Space evenly",horizontalDistribution:"Horizontally",verticalDistribution:"Vertically",strokeWidth:"Stroke Width",strokeSettings:"Stroke settings",spacing:"Spacing",volume:"Volume",speed:"Speed",seconds:"sec",lineStyle:"Line style",lineStartHead:"Line start",lineEndHead:"Line end",textDirection:"Text direction",fontSize:"Font size",fontFamily:"Font family",fontFamilyMixed:"Mixed",fontsInSelection:"Fonts in selection",textAlign:"Text align",verticalAlign:"Vertical align",bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",cellBackground:"Cell background",tableBorderSettings:"Border settings",tableBorderColor:"Border color",tableBorderWidth:"Border width",tableBorderStyle:"Border style",borderModeAll:"All borders",borderModeOuter:"Outer borders",borderModeInner:"Inner borders",borderModeBottomOnly:"Bottom only",borderModeTopOnly:"Top only",borderModeLeftOnly:"Left only",borderModeRightOnly:"Right only",borderModeInnerHorizontal:"Inner horizontal",borderModeInnerVertical:"Inner vertical",tableStructure:"Table structure",tableRows:"Rows",tableColumns:"Columns",insertRowAbove:"Insert row above",insertRowBelow:"Insert row below",deleteRow:"Delete row",insertColumnLeft:"Insert column left",insertColumnRight:"Insert column right",deleteColumn:"Delete column",deleteRows:"Delete rows",deleteColumns:"Delete columns",distributeRowsEvenly:"Distribute rows evenly",distributeColumnsEvenly:"Distribute columns evenly",cellPadding:"Cell padding",listFormat:"List",colorPicker:{solid:"Solid",linear:"Linear",angle:"Angle",colors:"Colors",resetColors:"Reset",recolorAll:"Recolor all"},aiText:{aiWrite:"AI write",rewrite:"Rewrite",shorten:"Shorten",continue:"Continue writing",proofread:"Proofread",tones:"Tones",friendly:"Friendly",professional:"Professional",humorous:"Humorous",formal:"Formal",customPrompt:"Custom prompt",generatedResult:"Generated result",cancel:"Cancel",generate:"Generate",back:"Back",tryAgain:"Try Again",insert:"Insert",promptPlaceholder:"Describe what you want to generate"}},workspace:{noPages:"There are no pages yet...",addPage:"Add page",removePage:"Remove page",duplicatePage:"Duplicate page",moveUp:"Move up",moveDown:"Move down",moveLeft:"Move left",moveRight:"Move right"},scale:{reset:"Reset"},error:{removeBackground:"Ops! Something went wrong. Background can not be removed."},sidePanel:{templates:"Templates",searchTemplatesWithSameSize:"Show templates with the same size",searchPlaceholder:"Search...",otherFormats:"Other formats",noResults:"No results",error:"Loading is failed...",text:"Text",uploadFont:"Upload font",myFonts:"My fonts",photos:"Photos",videos:"Videos",animations:"Animations",effects:"Effects",elements:"Elements",shapes:"Shapes",tables:"Tables",lines:"Lines",draw:"Draw",upload:"Upload",uploadImage:"Add file",uploadTip:"Upload your assets",background:"Background",resize:"Resize",layers:"Layers",animate:"Animate",layerTypes:{image:"Image",text:"Text",svg:"SVG",line:"Line",figure:"Figure",group:"Group"},layersTip:"Elements on your active page:",noLayers:"No elements on the page...",namePlaceholder:"Type element name...",useMagicResize:"Use magic resize",advanced:"Advanced",bleed:"Bleed",showBleed:"Show bleed",clipImage:"Mask image",width:"Width",height:"Height",units:"Units",magicResizeDescription:"Magic resize will automatically resize and move all elements on the canvas",headerText:"Header",createHeader:"Create header",subHeaderText:"Sub Header",createSubHeader:"Create sub header",bodyText:"Body text",createBody:"Create body text"},pagesTimeline:{pages:"Pages",removePage:"Remove page",addPage:"Add page",duplicatePage:"Duplicate page",removeAudio:"Remove audio",duplicateAudio:"Duplicate audio",muteAudio:"Mute",unmuteAudio:"Unmute",volume:"Volume",speed:"Speed",rewind:"Rewind to start",editAsVideo:"Edit as video",editAsVideoHint:"On: preview the frame at the playhead — timed elements hide outside their range. Off: show all elements while editing."},contextMenu:{duplicate:"Duplicate",split:"Split at playhead",remove:"Remove",lock:"Lock",unlock:"Unlock",copy:"Copy",paste:"Paste",copyStyle:"Copy style",moveUp:"Move up",moveDown:"Move down",moveBack:"Move back",moveForward:"Move forward"}}),n=e=>e&&"object"==typeof e;function i(e,o){Object.keys(o).forEach(r=>{const a=e[r],l=o[r];n(l)&&n(a)?i(a,l):e[r]=l})}function l(e,o,r=""){Object.keys(o).forEach(a=>{const i=o[a],s=r?`${r}.${a}`:a;n(i)?n(e[a])?l(e[a],i,s):console.warn(`Missing nested translation object at '${s}'`):void 0===e[a]&&console.warn(`Missing translation '${s}'`)})}export const setTranslations=o((e,{validate:o=!1}={})=>{o&&l(e,a),i(a,e)});export const getTranslations=()=>r(a);const s={};export const t=e=>{const o=function(e,o){var r,a=o.split("."),n=e;for(r=0;r<a.length;++r){if(null==n[a[r]]){return}n=n[a[r]]}return n}(a,e);if(void 0!==o){return o}s[e]||(s[e]=!0,console.warn(`Missing translation '${e}'`));const r=e.split("."),n=r[r.length-1]||" ";return n.charAt(0).toUpperCase()+n.slice(1)};
|
|
1
|
+
import{observable as e,action as o,toJS as r}from"mobx";const a=e({toolbar:{duration:"Duration",opacity:"Opacity",effects:"Effects",blur:"Blur",curvedText:"Curved text",curvePower:"Power",temperature:"Temperature",saturation:"Saturation",contrast:"Contrast",shadows:"Shadows",white:"White",black:"Black",vibrance:"Vibrance",textBackground:"Background",backgroundCornerRadius:"Corner radius",backgroundOpacity:"Opacity",backgroundPadding:"Padding",brightness:"Brightness",filters:"Filters",sepia:"Sepia",grayscale:"Grayscale",cold:"Cold",natural:"Natural",warm:"Warm",textStroke:"Text Stroke",strokeLineJoin:"Corners",joinRound:"Round",joinMiter:"Miter",joinBevel:"Bevel",shadow:"Shadow",border:"Border",cornerRadius:"Corner Radius",copyStyle:"Copy style",uppercase:"Uppercase",position:"Position",layering:"Layering",toForward:"To Front",up:"Forward",down:"Backward",toBottom:"To back",alignLeft:"Align left",alignCenter:"Align center",alignRight:"Align right",alignTop:"Align top",alignMiddle:"Align middle",alignBottom:"Align bottom",flip:"Flip",flipHorizontally:"Flip horizontally",flipVertically:"Flip vertically",fitToBackground:"Fit to page",removeBackground:"Remove background",removeBackgroundTitle:"Remove background from image",cancelRemoveBackground:"Cancel",confirmRemoveBackground:"Confirm",crop:"Crop",cropDone:"Done",cropCancel:"Cancel",clip:"Apply mask",removeClip:"Remove mask",removeMask:"Remove mask",transparency:"Transparency",lockedDescription:"Object is locked. Unlock it to allow changes from canvas.",unlockedDescription:"Object is unlocked. Lock it to prevent changes from canvas.",removeElements:"Remove elements",duplicateElements:"Duplicate elements",download:"Download",saveAsImage:"Save as image",saveAsPDF:"Save as PDF",lineHeight:"Line height",letterSpacing:"Letter spacing",offsetX:"Offset X",offsetY:"Offset Y",color:"Color",selectable:"Selectable",draggable:"Draggable",removable:"Removable",resizable:"Resizable",contentEditable:"Can change content",styleEditable:"Can change style",alwaysOnTop:"Always on top",showInExport:"Show in export",ungroupElements:"Ungroup",groupElements:"Group",lineSize:"Line size",fade:"Fade",move:"Move",zoom:"Zoom",animate:"Animate",rotate:"Rotate",none:"None",bounce:"Bounce",blink:"Blink",strength:"Strength",spaceEvenly:"Space evenly",horizontalDistribution:"Horizontally",verticalDistribution:"Vertically",strokeWidth:"Stroke Width",strokeSettings:"Stroke settings",spacing:"Spacing",volume:"Volume",speed:"Speed",seconds:"sec",lineStyle:"Line style",lineStartHead:"Line start",lineEndHead:"Line end",textDirection:"Text direction",fontSize:"Font size",fontFamily:"Font family",fontFamilyMixed:"Mixed",fontsInSelection:"Fonts in selection",textAlign:"Text align",verticalAlign:"Vertical align",bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",cellBackground:"Cell background",tableBorderSettings:"Border settings",tableBorderColor:"Border color",tableBorderWidth:"Border width",tableBorderStyle:"Border style",borderModeAll:"All borders",borderModeOuter:"Outer borders",borderModeInner:"Inner borders",borderModeBottomOnly:"Bottom only",borderModeTopOnly:"Top only",borderModeLeftOnly:"Left only",borderModeRightOnly:"Right only",borderModeInnerHorizontal:"Inner horizontal",borderModeInnerVertical:"Inner vertical",tableStructure:"Table structure",tableRows:"Rows",tableColumns:"Columns",insertRowAbove:"Insert row above",insertRowBelow:"Insert row below",deleteRow:"Delete row",insertColumnLeft:"Insert column left",insertColumnRight:"Insert column right",deleteColumn:"Delete column",deleteRows:"Delete rows",deleteColumns:"Delete columns",distributeRowsEvenly:"Distribute rows evenly",distributeColumnsEvenly:"Distribute columns evenly",cellPadding:"Cell padding",listFormat:"List",colorPicker:{solid:"Solid",linear:"Linear",angle:"Angle",colors:"Colors",resetColors:"Reset",recolorAll:"Recolor all"},aiText:{aiWrite:"AI write",rewrite:"Rewrite",shorten:"Shorten",continue:"Continue writing",proofread:"Proofread",tones:"Tones",friendly:"Friendly",professional:"Professional",humorous:"Humorous",formal:"Formal",customPrompt:"Custom prompt",generatedResult:"Generated result",cancel:"Cancel",generate:"Generate",back:"Back",tryAgain:"Try Again",insert:"Insert",promptPlaceholder:"Describe what you want to generate"}},workspace:{noPages:"There are no pages yet...",addPage:"Add page",removePage:"Remove page",duplicatePage:"Duplicate page",moveUp:"Move up",moveDown:"Move down",moveLeft:"Move left",moveRight:"Move right"},scale:{reset:"Reset"},error:{removeBackground:"Ops! Something went wrong. Background can not be removed."},sidePanel:{templates:"Templates",searchTemplatesWithSameSize:"Show templates with the same size",searchPlaceholder:"Search...",otherFormats:"Other formats",noResults:"No results",error:"Loading is failed...",text:"Text",uploadFont:"Upload font",myFonts:"My fonts",photos:"Photos",videos:"Videos",animations:"Animations",effects:"Effects",elements:"Elements",shapes:"Shapes",tables:"Tables",lines:"Lines",draw:"Draw",upload:"Upload",uploadImage:"Add file",uploadTip:"Upload your assets",background:"Background",resize:"Resize",layers:"Layers",animate:"Animate",layerTypes:{image:"Image",text:"Text",svg:"SVG",line:"Line",figure:"Figure",group:"Group"},layersTip:"Elements on your active page:",noLayers:"No elements on the page...",namePlaceholder:"Type element name...",useMagicResize:"Use magic resize",advanced:"Advanced",bleed:"Bleed",showBleed:"Show bleed",clipImage:"Mask image",width:"Width",height:"Height",units:"Units",magicResizeDescription:"Magic resize will automatically resize and move all elements on the canvas",headerText:"Header",createHeader:"Create header",subHeaderText:"Sub Header",createSubHeader:"Create sub header",bodyText:"Body text",createBody:"Create body text"},pagesTimeline:{pages:"Pages",removePage:"Remove page",addPage:"Add page",duplicatePage:"Duplicate page",removeAudio:"Remove audio",duplicateAudio:"Duplicate audio",muteAudio:"Mute",unmuteAudio:"Unmute",volume:"Volume",speed:"Speed",rewind:"Rewind to start",editAsVideo:"Edit as video",editAsVideoHint:"On: preview the frame at the playhead — timed elements hide outside their range. Off: show all elements while editing."},contextMenu:{duplicate:"Duplicate",split:"Split at playhead",remove:"Remove",lock:"Lock",unlock:"Unlock",copy:"Copy",paste:"Paste",copyStyle:"Copy style",moveUp:"Move up",moveDown:"Move down",moveBack:"Move back",moveForward:"Move forward"}}),n=e=>e&&"object"==typeof e;function i(e,o){Object.keys(o).forEach(r=>{const a=e[r],l=o[r];n(l)&&n(a)?i(a,l):e[r]=l})}function l(e,o,r=""){Object.keys(o).forEach(a=>{const i=o[a],s=r?`${r}.${a}`:a;n(i)?n(e[a])?l(e[a],i,s):console.warn(`Missing nested translation object at '${s}'`):void 0===e[a]&&console.warn(`Missing translation '${s}'`)})}export const setTranslations=o((e,{validate:o=!1}={})=>{o&&l(e,a),i(a,e)});export const getTranslations=()=>r(a);const s={};export const t=e=>{const o=function(e,o){var r,a=o.split("."),n=e;for(r=0;r<a.length;++r){if(null==n[a[r]]){return}n=n[a[r]]}return n}(a,e);if(void 0!==o){return o}s[e]||(s[e]=!0,console.warn(`Missing translation '${e}'`));const r=e.split("."),n=r[r.length-1]||" ";return n.charAt(0).toUpperCase()+n.slice(1)};
|
package/utils/loader.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PolotnoError } from './errors.js';
|
|
1
2
|
export declare const setAssetLoadTimeout: (timeout: number) => void;
|
|
2
3
|
export declare const getAssetLoadTimeout: () => number;
|
|
3
4
|
export declare const setFontLoadTimeout: (timeout: number) => void;
|
|
@@ -5,5 +6,5 @@ export declare const getFontLoadTimeout: () => number;
|
|
|
5
6
|
export declare function incrementLoader(id: any): () => void;
|
|
6
7
|
export declare function decrementLoader(): void;
|
|
7
8
|
export declare function whenLoaded(): Promise<unknown>;
|
|
8
|
-
export declare function onLoadError(func:
|
|
9
|
-
export declare function triggerLoadError(error: string): void;
|
|
9
|
+
export declare function onLoadError(func: (error: PolotnoError) => void): void;
|
|
10
|
+
export declare function triggerLoadError(error: string | PolotnoError): void;
|
package/utils/loader.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isAnimationUsed as e}from"../canvas/use-fadein.js";let o=0,
|
|
1
|
+
import{isAnimationUsed as e}from"../canvas/use-fadein.js";import{polotnoError as t}from"./errors.js";let o=0,r=[],n=3e4;export const setAssetLoadTimeout=e=>{n=e};export const getAssetLoadTimeout=()=>n;let s=6e3;export const setFontLoadTimeout=e=>{s=e};export const getFontLoadTimeout=()=>s;export function incrementLoader(e){o+=1;let r=!1,s=!1;const i=setTimeout(()=>{if(r){return}const o=String(e),s=o.startsWith("image")?"IMAGE_FAILED":o.startsWith("video")||o.startsWith("mediabunny")?"VIDEO_FAILED":"UNKNOWN";triggerLoadError(t(s,`Timeout loading asset ${e}`,{reason:"timeout",label:o,timeoutMs:n})),console.error("Timeout triggered for loader. Some assets may not have loaded.",e),r=!0,decrementLoader()},n);return()=>{s?console.error("Finish called twice! That is not expected. id: ",e):(s=!0,r||(clearTimeout(i),decrementLoader()))}}export function decrementLoader(){o-=1,0===o&&(r.forEach(e=>e()),r=[])}export function whenLoaded(){return new Promise(t=>{return n=()=>{e()?setTimeout(t,300):t(!0)},void(0===o?n():r.push(n));var n})}let i=[];export function onLoadError(e){i.push(e)}export function triggerLoadError(e){const o="string"==typeof e?t("UNKNOWN",e):e;i.forEach(e=>e(o))}
|
package/utils/mobx.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { IAutorunOptions, IReactionOptions, IReactionDisposer } from 'mobx';
|
|
2
|
+
import { IAnyStateTreeNode } from 'mobx-state-tree';
|
|
3
|
+
export declare function nodeAutorun(node: IAnyStateTreeNode, view: () => void, opts?: IAutorunOptions): IReactionDisposer;
|
|
4
|
+
export declare function nodeReaction<T>(node: IAnyStateTreeNode, expression: () => T, effect: (value: T | undefined, prev: T | undefined) => void, opts?: IReactionOptions<T | undefined, boolean>): IReactionDisposer;
|
package/utils/mobx.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{autorun as o,reaction as t}from"mobx";import{isAlive as r}from"mobx-state-tree";export function nodeAutorun(t,e,n){return o(()=>{r(t)&&e()},n)}export function nodeReaction(o,e,n,i){return t(()=>r(o)?e():void 0,(t,e)=>{r(o)&&n(t,e)},i)}
|
package/utils/text-html.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { StyledSegment } from './text.js';
|
|
2
2
|
import { TextElementLike } from './text-types.js';
|
|
3
3
|
export declare function getDir(string: string): "rtl" | "ltr";
|
|
4
|
+
export declare function normalizeStrokeLineJoin(join?: string): 'round' | 'miter' | 'bevel';
|
|
4
5
|
export declare function getCurvePath(width: number, height: number, power: number, absLineHeight: number): string;
|
|
5
6
|
export declare function createSVGGradientDef(gradientColor: string, id: string, width?: number, height?: number): string;
|
|
6
7
|
export declare function getCurveTextDimensions(element: TextElementLike, precomputed?: {
|
package/utils/text-html.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"konva";import*as e from"./gradient.js";import{removeTags as n,sanitizeHtml as o,parseHtmlToSegments as i}from"./text.js";import{flags as r}from"./flags.js";import{xmlEscape as l}from"./xml.js";import{applyTextDefaults as a}from"./text-types.js";import{normalizeRichTextHtml as s}from"./rich-text-html.js";function f(t){var e="֑-߿יִ-﷽ﹰ-ﻼ";return new RegExp("^[^"+e+"]*?["+e+"]").test(t)}export function getDir(t){return function(t){t=t.replace(/\s/g,"");let e=0;for(var n=0;n<t.length;n++){f(t[n])&&(e+=1)}return e>t.length/2}(t)?"rtl":"ltr"}export function getCurvePath(t,e,n,o){const i=Math.max(-.9999,Math.min(.9999,n));if(Math.abs(i)<1e-4){return`M 0 ${e/2} L ${t} ${e/2}`}const r=5*o/(2*Math.abs(i))-o,l=t/2;if(i>0){const t=2*r+o/2;return[`M ${l} ${t}`,`A ${r} ${r} 0 1 1 ${l} ${t-2*r}`,`A ${r} ${r} 0 1 1 ${l} ${t}`].join(" ")}{const t=-(2*r-Math.round(e))-o/2;return[`M ${l} ${t}`,`A ${r} ${r} 0 1 0 ${l} ${t+2*r}`,`A ${r} ${r} 0 1 0 ${l} ${t}`].join(" ")}}export function createSVGGradientDef(t,n,o,i){if(!e.isGradient(t)){return""}const{stops:r,rotation:l}=e.parseColor(t),a=l*Math.PI/180;return`<linearGradient id="${n}" x1="${100*(.5-.5*Math.sin(a))}%" y1="${100*(.5+.5*Math.cos(a))}%" x2="${100*(.5+.5*Math.sin(a))}%" y2="${100*(.5-.5*Math.cos(a))}%">${r.map(({offset:t,color:e})=>`<stop offset="${100*t}%" stop-color="${e}" />`).join("")}</linearGradient>`}let c=null;function h(){return c||(c=document.createElement("canvas").getContext("2d")),c}export function getCurveTextDimensions(e,o){var r,l,f,c,$,d;const u=e.a?e.a:e,g=a(e),p=null!==(r=u.fontSize)&&void 0!==r?r:g.fontSize,m=null!==(l=null==o?void 0:o.normalizedText)&&void 0!==l?l:s(g.text,{fontSize:p,fontFamily:g.fontFamily}),x=null!==(f=null==o?void 0:o.segments)&&void 0!==f?f:i(m,{fontSize:p,fontFamily:g.fontFamily}),y=Math.max(p,...x.map(t=>{var e;return null!==(e=t.fontSize)&&void 0!==e?e:p})),v=n(m),k=function(t,e,n,o,i,r){if(!t.some(t=>t.fontFamily&&t.fontFamily!==n)||e.length<=1){return 0}const l=function(t,e,n,o,i){var r;const l=h();let a=0;for(const s of t){const t=s.fontFamily||e,f=s.bold?"bold":n,c=s.italic?"italic":o,h=null!==(r=s.fontSize)&&void 0!==r?r:i,$=t.replace(/'/g,"");l.font=`${c} ${f} ${h}px '${$}'`,a+=l.measureText(s.text).width}return a}(t,n,o,i,r),a=h();a.font=`${i} ${o} ${r}px '${n}'`;const s=l-a.measureText(e).width;return s<=0?0:s/(e.length-1)}(x,v,g.fontFamily,g.fontWeight||"normal",g.fontStyle||"normal",y),S=null!==(c=u.width)&&void 0!==c?c:g.width,w=new t.TextPath({data:getCurvePath(S,null!==(d=null!==($=u.height)&&void 0!==$?$:g.height)&&void 0!==d?d:0,g.curvePower,y),align:"center",textBaseline:"middle",text:v,fontSize:y,fontFamily:g.fontFamily,fontWeight:g.fontWeight,fontStyle:g.fontStyle,letterSpacing:g.letterSpacing*y+k,fill:g.fill}),b=w.getSelfRect();return w.destroy(),{width:b.width||S,height:b.height||y}}export function getCurveTextHeight(t){return getCurveTextDimensions(t).height}export function segmentsToTspans(t,e,n){return t.map(t=>{var o;const i=[];t.bold&&"bold"!==e.fontWeight&&i.push('font-weight="bold"'),t.italic&&"italic"!==e.fontStyle&&i.push('font-style="italic"');const r=[];t.underline&&r.push("underline"),t.strike&&r.push("line-through"),r.length&&i.push(`text-decoration="${r.join(" ")}"`),!(null==n?void 0:n.omitColors)&&t.color&&t.color!==e.fill&&i.push(`fill="${l(t.color)}"`);const a=t.fontFamily||e.fontFamily;a!==e.fontFamily&&i.push(`font-family="${l(a)}"`);const s=null!==(o=t.fontSize)&&void 0!==o?o:e.fontSize;s!==e.fontSize&&i.push(`font-size="${s}"`);const f=l(t.text);return 0===i.length?f:`<tspan ${i.join(" ")}>${f}</tspan>`}).join("")}export function getQuillEditorHtml(t,e){const n=a(t),i=e||n.fontFamily,r=s(n.text,{fontSize:n.fontSize,fontFamily:i});return o(r).replace(/\n/g,"<br/>")}export function getHtml(t,{fontFamily:f="",color:c="black",forEditor:h=!1}={}){const $=a(t),d=f||$.fontFamily,u=s($.text,{fontSize:$.fontSize,fontFamily:d}),g=e.isGradient($.fill),p=e.isGradient($.stroke)&&!!$.strokeWidth,m="ellipsis"===r.textOverflow&&!h&&!$.curveEnabled&&!!$.height,x=(()=>{if(!m){return[]}const t=Math.max(1,Math.round($.height)),e="number"==typeof $.lineHeight?$.lineHeight:1.2,n=Math.max(1,e*$.fontSize),o=Math.max(1,Math.floor(t/n));return[`max-height: ${t}px`,"overflow: hidden","display: -webkit-box","-webkit-box-orient: vertical",`-webkit-line-clamp: ${o}`,`line-clamp: ${o}`]})(),y=t=>`\n background-image: ${t};\n background-size: 100% 100%;\n background-repeat: repeat;\n -webkit-background-clip: text;\n -moz-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n color: transparent\n `.trim();let v=`color: ${c||$.fill}`,k="";p&&$.strokeWidth?(v=`color: ${c||$.fill}; ${y($.stroke)}`,k=`-webkit-text-stroke: ${$.strokeWidth}px transparent`):g&&(v=y($.fill));const S=["white-space: pre-wrap","overflow-wrap: break-word",`width: ${Math.round($.width||100)}px`,...x,v,`font-size: ${$.fontSize}px`,`font-family: '${d}'`,`text-align: ${$.align}`,`text-transform: ${$.textTransform}`,$.textDecoration?`text-decoration: ${$.textDecoration}; text-decoration-color: ${c||$.fill}; text-decoration-layer: over`:"",$.lineHeight?`line-height: ${$.lineHeight}`:"",$.letterSpacing?`letter-spacing: ${$.letterSpacing}em`:"",$.fontStyle?`font-style: ${$.fontStyle}`:"",$.fontWeight?`font-weight: ${$.fontWeight}`:"",k||($.strokeWidth?`-webkit-text-stroke: ${$.strokeWidth}px ${$.stroke}`:""),$.strokeWidth&&!p?"paint-order: stroke fill":""].filter(Boolean).join("; ");if($.curveEnabled&&!h){const e=i(u,{fontSize:$.fontSize,fontFamily:d}),n=getCurveTextDimensions(t,{normalizedText:u,segments:e}),o=Math.round(n.width),r=n.height,a=Math.max($.fontSize,...e.map(t=>{var e;return null!==(e=t.fontSize)&&void 0!==e?e:$.fontSize})),s=getCurvePath(o,r,$.curvePower,a),f={fontWeight:$.fontWeight||"normal",fontStyle:$.fontStyle||"normal",fill:c||$.fill||"black",fontFamily:d,fontSize:$.fontSize},h=segmentsToTspans(e,f),m=segmentsToTspans(e,f,{omitColors:!0}),x=l($.id||"temp"),y=`curve-${x}`,v=$.strokeWidth&&(p||g&&!p);let k=`<svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${r}" overflow="visible">\n <defs>\n <path id="${y}" d="${s}" fill="none" />`;if(g){const t=`curve-fill-grad-${x}`;k+=createSVGGradientDef($.fill,t,o,r)}if(p&&$.strokeWidth){const t=`curve-stroke-grad-${x}`;k+=createSVGGradientDef($.stroke,t,o,r)}k+="</defs>";const S=l(d),w=l($.fontWeight||"normal"),b=l($.fontStyle||"normal");if(v){const t=`\n font-family="'${S}'"\n font-size="${$.fontSize}"\n font-weight="${w}"\n font-style="${b}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${$.letterSpacing*a}"${$.textDecoration?` text-decoration="${$.textDecoration}"`:""}`,e=p?`url(#curve-stroke-grad-${x})`:$.stroke;k+=`\n <text ${t} fill="${e}" stroke="${e}" stroke-width="${$.strokeWidth}">\n <textPath href="#${y}" startOffset="50%">${m}</textPath>\n </text>`,k+=`\n <text ${t} fill="${g?`url(#curve-fill-grad-${x})`:c}">\n <textPath href="#${y}" startOffset="50%">${h}</textPath>\n </text>`}else{const t=g?`url(#curve-fill-grad-${x})`:c,e=p?`url(#curve-stroke-grad-${x})`:$.stroke;k+=`\n <text\n font-family="'${S}'"\n font-size="${$.fontSize}"\n font-weight="${w}"\n font-style="${b}"\n fill="${t}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${$.letterSpacing*a}"${$.textDecoration?` text-decoration="${$.textDecoration}"`:""}${$.strokeWidth?` stroke="${e}" stroke-width="${$.strokeWidth}" paint-order="stroke fill"`:""}>\n <textPath href="#${y}" startOffset="50%">${h}</textPath>\n </text>`}return k+="</svg>",k}if($.strokeWidth&&(p||g&&!p)&&!h){const t=o(u).replace(/\n/g,"<br/>"),e=Math.round($.width||100),i=["white-space: pre-wrap","overflow-wrap: break-word",`width: ${e}px`,...x,`font-size: ${$.fontSize}px`,`font-family: '${d}'`,`text-align: ${$.align}`,`text-transform: ${$.textTransform}`,$.textDecoration?`text-decoration: ${$.textDecoration}; text-decoration-color: ${c||$.fill}; text-decoration-layer: over`:"",$.lineHeight?`line-height: ${$.lineHeight}`:"",$.letterSpacing?`letter-spacing: ${$.letterSpacing}em`:"",$.fontStyle?`font-style: ${$.fontStyle}`:"",$.fontWeight?`font-weight: ${$.fontWeight}`:""].filter(Boolean).join("; ");let r;r=p?`${i}; ${y($.stroke)}; -webkit-text-stroke: ${$.strokeWidth}px transparent`:`${i}; color: transparent; -webkit-text-stroke: ${$.strokeWidth}px ${$.stroke}`;const l=`${i}; ${g?y($.fill):`color: ${c||$.fill}`}`;let a="";if(g||p){const t=[];p&&$.strokeWidth&&t.push(`.stroke-layer li, .stroke-layer li::before { ${y($.stroke)}; }`),g&&t.push(`.fill-layer li, .fill-layer li::before { ${y($.fill)}; }`),t.length&&(a=`<style>${t.join("\n")}</style>`)}return`\n <div style="position: relative; width: ${e}px;">\n <div class="stroke-layer" style="${r}; position: absolute; top: 0; left: 0; pointer-events: none;" aria-hidden="true">${t}</div>\n <div class="fill-layer" style="${l}; position: relative;" contentEditable dir="${getDir(n(u))}">${t}</div>\n </div>\n ${a}\n `}let w="";return g&&!p&&(w=`<style>\n li, li::before {\n ${y($.fill)};\n }\n </style>`),`<div style="${S}" contentEditable dir="${getDir(n(u))}">${o(u).replace(/\n/g,"<br/>")}</div>${w}`}export function resolveLineHeight({fontFamily:t,fontSize:e,lineHeight:n}){if("number"==typeof n){return n}const o=document.createElement("div");o.style.fontFamily=t,o.style.fontSize=e+"px",o.style.lineHeight=n,o.innerText="Test text",document.body.appendChild(o);try{return o.offsetHeight/e}finally{document.body.removeChild(o)}}
|
|
1
|
+
import t from"konva";import*as e from"./gradient.js";import{removeTags as n,sanitizeHtml as o,parseHtmlToSegments as i}from"./text.js";import{flags as r}from"./flags.js";import{xmlEscape as l}from"./xml.js";import{applyTextDefaults as a}from"./text-types.js";import{normalizeRichTextHtml as s}from"./rich-text-html.js";function f(t){var e="֑-߿יִ-﷽ﹰ-ﻼ";return new RegExp("^[^"+e+"]*?["+e+"]").test(t)}export function getDir(t){return function(t){t=t.replace(/\s/g,"");let e=0;for(var n=0;n<t.length;n++){f(t[n])&&(e+=1)}return e>t.length/2}(t)?"rtl":"ltr"}export function normalizeStrokeLineJoin(t){return"miter"===t||"bevel"===t?t:"round"}export function getCurvePath(t,e,n,o){const i=Math.max(-.9999,Math.min(.9999,n));if(Math.abs(i)<1e-4){return`M 0 ${e/2} L ${t} ${e/2}`}const r=5*o/(2*Math.abs(i))-o,l=t/2;if(i>0){const t=2*r+o/2;return[`M ${l} ${t}`,`A ${r} ${r} 0 1 1 ${l} ${t-2*r}`,`A ${r} ${r} 0 1 1 ${l} ${t}`].join(" ")}{const t=-(2*r-Math.round(e))-o/2;return[`M ${l} ${t}`,`A ${r} ${r} 0 1 0 ${l} ${t+2*r}`,`A ${r} ${r} 0 1 0 ${l} ${t}`].join(" ")}}export function createSVGGradientDef(t,n,o,i){if(!e.isGradient(t)){return""}const{stops:r,rotation:l}=e.parseColor(t),a=l*Math.PI/180;return`<linearGradient id="${n}" x1="${100*(.5-.5*Math.sin(a))}%" y1="${100*(.5+.5*Math.cos(a))}%" x2="${100*(.5+.5*Math.sin(a))}%" y2="${100*(.5-.5*Math.cos(a))}%">${r.map(({offset:t,color:e})=>`<stop offset="${100*t}%" stop-color="${e}" />`).join("")}</linearGradient>`}let c=null;function h(){return c||(c=document.createElement("canvas").getContext("2d")),c}export function getCurveTextDimensions(e,o){var r,l,f,c,$,d;const u=e.a?e.a:e,m=a(e),g=null!==(r=u.fontSize)&&void 0!==r?r:m.fontSize,p=null!==(l=null==o?void 0:o.normalizedText)&&void 0!==l?l:s(m.text,{fontSize:g,fontFamily:m.fontFamily}),x=null!==(f=null==o?void 0:o.segments)&&void 0!==f?f:i(p,{fontSize:g,fontFamily:m.fontFamily}),y=Math.max(g,...x.map(t=>{var e;return null!==(e=t.fontSize)&&void 0!==e?e:g})),k=n(p),v=function(t,e,n,o,i,r){if(!t.some(t=>t.fontFamily&&t.fontFamily!==n)||e.length<=1){return 0}const l=function(t,e,n,o,i){var r;const l=h();let a=0;for(const s of t){const t=s.fontFamily||e,f=s.bold?"bold":n,c=s.italic?"italic":o,h=null!==(r=s.fontSize)&&void 0!==r?r:i,$=t.replace(/'/g,"");l.font=`${c} ${f} ${h}px '${$}'`,a+=l.measureText(s.text).width}return a}(t,n,o,i,r),a=h();a.font=`${i} ${o} ${r}px '${n}'`;const s=l-a.measureText(e).width;return s<=0?0:s/(e.length-1)}(x,k,m.fontFamily,m.fontWeight||"normal",m.fontStyle||"normal",y),S=null!==(c=u.width)&&void 0!==c?c:m.width,w=new t.TextPath({data:getCurvePath(S,null!==(d=null!==($=u.height)&&void 0!==$?$:m.height)&&void 0!==d?d:0,m.curvePower,y),align:"center",textBaseline:"middle",text:k,fontSize:y,fontFamily:m.fontFamily,fontWeight:m.fontWeight,fontStyle:m.fontStyle,letterSpacing:m.letterSpacing*y+v,fill:m.fill}),b=w.getSelfRect();return w.destroy(),{width:b.width||S,height:b.height||y}}export function getCurveTextHeight(t){return getCurveTextDimensions(t).height}export function segmentsToTspans(t,e,n){return t.map(t=>{var o;const i=[];t.bold&&"bold"!==e.fontWeight&&i.push('font-weight="bold"'),t.italic&&"italic"!==e.fontStyle&&i.push('font-style="italic"');const r=[];t.underline&&r.push("underline"),t.strike&&r.push("line-through"),r.length&&i.push(`text-decoration="${r.join(" ")}"`),!(null==n?void 0:n.omitColors)&&t.color&&t.color!==e.fill&&i.push(`fill="${l(t.color)}"`);const a=t.fontFamily||e.fontFamily;a!==e.fontFamily&&i.push(`font-family="${l(a)}"`);const s=null!==(o=t.fontSize)&&void 0!==o?o:e.fontSize;s!==e.fontSize&&i.push(`font-size="${s}"`);const f=l(t.text);return 0===i.length?f:`<tspan ${i.join(" ")}>${f}</tspan>`}).join("")}export function getQuillEditorHtml(t,e){const n=a(t),i=e||n.fontFamily,r=s(n.text,{fontSize:n.fontSize,fontFamily:i});return o(r).replace(/\n/g,"<br/>")}export function getHtml(t,{fontFamily:f="",color:c="black",forEditor:h=!1}={}){const $=a(t),d=f||$.fontFamily,u=s($.text,{fontSize:$.fontSize,fontFamily:d}),m=e.isGradient($.fill),g=e.isGradient($.stroke)&&!!$.strokeWidth,p="ellipsis"===r.textOverflow&&!h&&!$.curveEnabled&&!!$.height,x=(()=>{if(!p){return[]}const t=Math.max(1,Math.round($.height)),e="number"==typeof $.lineHeight?$.lineHeight:1.2,n=Math.max(1,e*$.fontSize),o=Math.max(1,Math.floor(t/n));return[`max-height: ${t}px`,"overflow: hidden","display: -webkit-box","-webkit-box-orient: vertical",`-webkit-line-clamp: ${o}`,`line-clamp: ${o}`]})(),y=t=>`\n background-image: ${t};\n background-size: 100% 100%;\n background-repeat: repeat;\n -webkit-background-clip: text;\n -moz-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n color: transparent\n `.trim();let k=`color: ${c||$.fill}`,v="";g&&$.strokeWidth?(k=`color: ${c||$.fill}; ${y($.stroke)}`,v=`-webkit-text-stroke: ${$.strokeWidth}px transparent`):m&&(k=y($.fill));const S=["white-space: pre-wrap","overflow-wrap: break-word",`width: ${Math.round($.width||100)}px`,...x,k,`font-size: ${$.fontSize}px`,`font-family: '${d}'`,`text-align: ${$.align}`,`text-transform: ${$.textTransform}`,$.textDecoration?`text-decoration: ${$.textDecoration}; text-decoration-color: ${c||$.fill}; text-decoration-layer: over`:"",$.lineHeight?`line-height: ${$.lineHeight}`:"",$.letterSpacing?`letter-spacing: ${$.letterSpacing}em`:"",$.fontStyle?`font-style: ${$.fontStyle}`:"",$.fontWeight?`font-weight: ${$.fontWeight}`:"",v||($.strokeWidth?`-webkit-text-stroke: ${$.strokeWidth}px ${$.stroke}`:""),$.strokeWidth&&!g?"paint-order: stroke fill":"",$.strokeWidth?`stroke-linejoin: ${normalizeStrokeLineJoin($.strokeLineJoin)}`:""].filter(Boolean).join("; ");if($.curveEnabled&&!h){const e=i(u,{fontSize:$.fontSize,fontFamily:d}),n=getCurveTextDimensions(t,{normalizedText:u,segments:e}),o=Math.round(n.width),r=n.height,a=Math.max($.fontSize,...e.map(t=>{var e;return null!==(e=t.fontSize)&&void 0!==e?e:$.fontSize})),s=getCurvePath(o,r,$.curvePower,a),f={fontWeight:$.fontWeight||"normal",fontStyle:$.fontStyle||"normal",fill:c||$.fill||"black",fontFamily:d,fontSize:$.fontSize},h=segmentsToTspans(e,f),p=segmentsToTspans(e,f,{omitColors:!0}),x=l($.id||"temp"),y=`curve-${x}`,k=$.strokeWidth&&(g||m&&!g);let v=`<svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${r}" overflow="visible">\n <defs>\n <path id="${y}" d="${s}" fill="none" />`;if(m){const t=`curve-fill-grad-${x}`;v+=createSVGGradientDef($.fill,t,o,r)}if(g&&$.strokeWidth){const t=`curve-stroke-grad-${x}`;v+=createSVGGradientDef($.stroke,t,o,r)}v+="</defs>";const S=l(d),w=l($.fontWeight||"normal"),b=l($.fontStyle||"normal");if(k){const t=`\n font-family="'${S}'"\n font-size="${$.fontSize}"\n font-weight="${w}"\n font-style="${b}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${$.letterSpacing*a}"${$.textDecoration?` text-decoration="${$.textDecoration}"`:""}`,e=g?`url(#curve-stroke-grad-${x})`:$.stroke;v+=`\n <text ${t} fill="${e}" stroke="${e}" stroke-width="${$.strokeWidth}" stroke-linejoin="${normalizeStrokeLineJoin($.strokeLineJoin)}">\n <textPath href="#${y}" startOffset="50%">${p}</textPath>\n </text>`,v+=`\n <text ${t} fill="${m?`url(#curve-fill-grad-${x})`:c}">\n <textPath href="#${y}" startOffset="50%">${h}</textPath>\n </text>`}else{const t=m?`url(#curve-fill-grad-${x})`:c,e=g?`url(#curve-stroke-grad-${x})`:$.stroke;v+=`\n <text\n font-family="'${S}'"\n font-size="${$.fontSize}"\n font-weight="${w}"\n font-style="${b}"\n fill="${t}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${$.letterSpacing*a}"${$.textDecoration?` text-decoration="${$.textDecoration}"`:""}${$.strokeWidth?` stroke="${e}" stroke-width="${$.strokeWidth}" stroke-linejoin="${normalizeStrokeLineJoin($.strokeLineJoin)}" paint-order="stroke fill"`:""}>\n <textPath href="#${y}" startOffset="50%">${h}</textPath>\n </text>`}return v+="</svg>",v}if($.strokeWidth&&(g||m&&!g)&&!h){const t=o(u).replace(/\n/g,"<br/>"),e=Math.round($.width||100),i=["white-space: pre-wrap","overflow-wrap: break-word",`width: ${e}px`,...x,`font-size: ${$.fontSize}px`,`font-family: '${d}'`,`text-align: ${$.align}`,`text-transform: ${$.textTransform}`,$.textDecoration?`text-decoration: ${$.textDecoration}; text-decoration-color: ${c||$.fill}; text-decoration-layer: over`:"",$.lineHeight?`line-height: ${$.lineHeight}`:"",$.letterSpacing?`letter-spacing: ${$.letterSpacing}em`:"",$.fontStyle?`font-style: ${$.fontStyle}`:"",$.fontWeight?`font-weight: ${$.fontWeight}`:""].filter(Boolean).join("; ");let r;r=g?`${i}; ${y($.stroke)}; -webkit-text-stroke: ${$.strokeWidth}px transparent`:`${i}; color: transparent; -webkit-text-stroke: ${$.strokeWidth}px ${$.stroke}`;const l=`${i}; ${m?y($.fill):`color: ${c||$.fill}`}`;let a="";if(m||g){const t=[];g&&$.strokeWidth&&t.push(`.stroke-layer li, .stroke-layer li::before { ${y($.stroke)}; }`),m&&t.push(`.fill-layer li, .fill-layer li::before { ${y($.fill)}; }`),t.length&&(a=`<style>${t.join("\n")}</style>`)}return`\n <div style="position: relative; width: ${e}px;">\n <div class="stroke-layer" style="${r}; position: absolute; top: 0; left: 0; pointer-events: none;" aria-hidden="true">${t}</div>\n <div class="fill-layer" style="${l}; position: relative;" contentEditable dir="${getDir(n(u))}">${t}</div>\n </div>\n ${a}\n `}let w="";return m&&!g&&(w=`<style>\n li, li::before {\n ${y($.fill)};\n }\n </style>`),`<div style="${S}" contentEditable dir="${getDir(n(u))}">${o(u).replace(/\n/g,"<br/>")}</div>${w}`}export function resolveLineHeight({fontFamily:t,fontSize:e,lineHeight:n}){if("number"==typeof n){return n}const o=document.createElement("div");o.style.fontFamily=t,o.style.fontSize=e+"px",o.style.lineHeight=n,o.innerText="Test text",document.body.appendChild(o);try{return o.offsetHeight/e}finally{document.body.removeChild(o)}}
|
package/utils/text-types.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface TextElementLike {
|
|
|
15
15
|
fill?: string;
|
|
16
16
|
stroke?: string;
|
|
17
17
|
strokeWidth?: number;
|
|
18
|
+
strokeLineJoin?: string;
|
|
18
19
|
curveEnabled?: boolean;
|
|
19
20
|
curvePower?: number;
|
|
20
21
|
a?: {
|
|
@@ -40,6 +41,7 @@ export declare const TEXT_DEFAULTS: {
|
|
|
40
41
|
readonly fill: "black";
|
|
41
42
|
readonly stroke: "black";
|
|
42
43
|
readonly strokeWidth: 0;
|
|
44
|
+
readonly strokeLineJoin: "round";
|
|
43
45
|
readonly curveEnabled: false;
|
|
44
46
|
readonly curvePower: 0.5;
|
|
45
47
|
};
|
package/utils/text-types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const TEXT_DEFAULTS={fontSize:14,fontFamily:"Roboto",fontWeight:"normal",fontStyle:"normal",lineHeight:1.2,letterSpacing:0,textTransform:"none",textDecoration:"",align:"center",fill:"black",stroke:"black",strokeWidth:0,curveEnabled:!1,curvePower:.5};export function applyTextDefaults(t){return Object.assign(Object.assign({},TEXT_DEFAULTS),t)}
|
|
1
|
+
export const TEXT_DEFAULTS={fontSize:14,fontFamily:"Roboto",fontWeight:"normal",fontStyle:"normal",lineHeight:1.2,letterSpacing:0,textTransform:"none",textDecoration:"",align:"center",fill:"black",stroke:"black",strokeWidth:0,strokeLineJoin:"round",curveEnabled:!1,curvePower:.5};export function applyTextDefaults(t){return Object.assign(Object.assign({},TEXT_DEFAULTS),t)}
|
package/utils/to-html.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var t=this&&this.__rest||function(t,e){var o={};for(var i in t){Object.prototype.hasOwnProperty.call(t,i)&&e.indexOf(i)<0&&(o[i]=t[i])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(i=Object.getOwnPropertySymbols(t);n<i.length;n++){e.indexOf(i[n])<0&&Object.prototype.propertyIsEnumerable.call(t,i[n])&&(o[i[n]]=t[i[n]])}}return o};import{getCrop as e,loadImage as o}from"./image.js";import*as i from"./svg.js";import{figureToSvg as n}from"./figure-to-svg.js";import{resetStyleContent as r}from"./reset-style.js";import{Effects as a,shapeFilterToCSS as s}from"./filters.js";import{getVideoSize as l}from"./video.js";import{getGoogleFontsUrl as d}from"./fonts.js";import{forEveryNode as c}from"../model/group-model.js";import{getCurvePath as p}from"../canvas/text-element.js";import{removeTags as g,parseHtmlToSegments as f}from"./text.js";import b from"konva";import*as m from"./gradient.js";import{createSVGGradientDef as u,segmentsToTspans as y,getHtml as k}from"./text-html.js";import{generateBackgroundShapeFromRects as x}from"./background-shape.js";import{detectLineRects as w,detectSize as $}from"./html2canvas.js";import{normalizeRichTextHtml as v,extractFontFamiliesFromHtml as j}from"./rich-text-html.js";export const h=(t,e,...o)=>({type:t,props:e,children:o||[]});function S(t){return m.isGradient(t),t}export function fixRatio(t){var e=(new DOMParser).parseFromString(t,"image/svg+xml");return e.documentElement.setAttribute("preserveAspectRatio","none"),(new XMLSerializer).serializeToString(e)}const O=async({element:t,page:e,store:n})=>{let{src:r}=t;if("svg"===t.type){let e=await i.urlToString(r);e=fixRatio(e),r=Object.keys(t.colorsReplace).length?i.replaceColors(e,new Map(Object.entries(t.colorsReplace))):i.svgToURL(e)}let a="";t.flipX&&(a+="scaleX(-1)"),t.flipY&&(a+="scaleY(-1)"),a||(a="none");const s={};if("svg"===t.type&&t.maskSrc){const e=await i.urlToBase64(r);s["mask-image"]=`url(${e})`,s["mask-size"]="100% 100%",s["mask-position"]="0 0",s["mask-repeat"]="no-repeat",s["-webkit-mask-image"]=`url(${e})`,s["-webkit-mask-size"]="100% 100%",s["-webkit-mask-position"]="0 0",s["-webkit-mask-repeat"]="no-repeat",r=t.maskSrc}else if(t.clipSrc){const e=t.clipSrc,o=await i.urlToBase64(e);s["mask-image"]=`url(${o})`,s["mask-size"]="100% 100%",s["mask-position"]="0 0",s["mask-repeat"]="no-repeat",s["-webkit-mask-image"]=`url(${o})`,s["-webkit-mask-size"]="100% 100%",s["-webkit-mask-position"]="0 0",s["-webkit-mask-repeat"]="no-repeat"}const l=await o(r),d=l.width*t.cropWidth,c=l.height*t.cropHeight,p=t.width/t.height;let g,f;const b=d/c,u="svg"===t.type||t.stretchEnabled;u?(g=d,f=c):p>=b?(g=d,f=d/p):(g=c*p,f=c);const y=g/l.width,k=f/l.height,x=g/f>t.width/t.height?t.height/f:t.width/g,w=u?t.width/g:x,$=u?t.height/f:x,v=g*w/y,j=f*$/k;let O=t.cropX*w*l.width,z=t.cropY*$*l.height;t.flipX&&(O=(1-t.cropX-t.cropWidth)*w*l.width),t.flipY&&(z=(1-t.cropY-t.cropHeight)*$*l.height);const H=t.borderSize&&m.isGradient(t.borderColor),W=H?Math.max(0,t.cornerRadius-t.borderSize):t.cornerRadius,T=h("div",{style:Object.assign(Object.assign({},s),{width:"100%",height:"100%",borderRadius:W+"px",border:t.borderSize&&!H?`${t.borderSize}px solid ${t.borderColor}`:"none",backgroundRepeat:"no-repeat",backgroundImage:`url(${r})`,transform:a,backgroundSize:`${Math.round(v)}px ${Math.round(j)}px`,backgroundPositionX:-Math.round(O)+"px",backgroundPositionY:-Math.round(z)+"px"})});return H?h("div",{style:{width:"100%",height:"100%",borderRadius:t.cornerRadius+"px",background:S(t.borderColor),padding:t.borderSize+"px",boxSizing:"border-box"}},T):T},z=({element:t,type:e})=>{const o={"stroke-width":t.height,stroke:t.color,"stroke-linecap":"round","stroke-linejoin":"round",opacity:t.opacity},i=Object.assign(Object.assign({},o),{fill:t.color}),n=Object.assign(Object.assign({},o),{fill:"none"});return"arrow"===e?h("polyline",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},n)):"triangle"===e?h("polygon",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},i)):"bar"===e?h("polyline",Object.assign({points:`0,${2*-t.height} 0,${2*t.height}`},n)):"circle"===e?h("circle",Object.assign({cx:2*t.height,cy:0,r:2*t.height},i)):"square"===e?h("polygon",Object.assign({points:`0,${2*-t.height} ${4*t.height},${2*-t.height} ${4*t.height},${2*t.height} 0,${2*t.height}`},i)):null},H={image:O,svg:O,text:async({element:t,page:e,store:o})=>{const i=m.isGradient(t.fill),n=m.isGradient(t.stroke);if(t.curveEnabled){const e=v(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}),o=f(e,{fontSize:t.fontSize,fontFamily:t.fontFamily}),r=Math.max(t.fontSize,...o.map(e=>{var o;return null!==(o=e.fontSize)&&void 0!==o?o:t.fontSize})),a=p(t.width,t.height,t.curvePower,r),s={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:t.fontSize},l=y(o,s);let d=`\n <svg xmlns="http://www.w3.org/2000/svg" width="${t.width}" height="${t.height}" style="display: block;">\n <defs>\n <path id="curve-${t.id}" d="${a}" fill="none" />`;if(i){const e=`curve-fill-grad-${t.id}`;d+=u(t.fill,e)}if(n&&t.strokeWidth){const e=`curve-stroke-grad-${t.id}`;d+=u(t.stroke,e)}d+=`</defs>\n <text\n font-family="'${t.fontFamily}'"\n font-size="${t.fontSize}"\n font-weight="${t.fontWeight}"\n font-style="${t.fontStyle}"\n fill="${i?`url(#curve-fill-grad-${t.id})`:t.fill}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${t.letterSpacing*r}"${t.textDecoration?` text-decoration="${t.textDecoration}"`:""}${t.strokeWidth?` stroke="${n?`url(#curve-stroke-grad-${t.id})`:t.stroke}" stroke-width="${t.strokeWidth}" paint-order="stroke fill"`:""}>\n <textPath href="#curve-${t.id}" startOffset="50%">${l}</textPath>\n </text>\n </svg>`;const c=t.backgroundPadding*(t.fontSize*t.lineHeight),g=t.backgroundEnabled&&h("div",{style:{position:"absolute",top:-c/2+"px",left:-c/2+"px",width:t.width+c+"px",height:t.height+c+"px",backgroundColor:t.backgroundColor,opacity:t.backgroundOpacity,borderRadius:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)+"px"}}),b=h("div",{style:{width:"100%",height:"100%",position:"absolute",top:0,left:0},innerHTML:d});return h("div",{style:{position:"relative",width:"100%",height:"100%"}},g,b)}const a=t=>({backgroundImage:t,backgroundSize:"100% 100%",backgroundRepeat:"repeat",WebkitBackgroundClip:"text",MozBackgroundClip:"text",backgroundClip:"text",WebkitTextFillColor:"transparent",MozTextFillColor:"transparent",color:"transparent"}),s="middle"===t.verticalAlign?{top:"50%",transform:"translateY(-50%)"}:"bottom"===t.verticalAlign?{bottom:0}:{top:0};let l=Object.assign(Object.assign({left:0},s),i?a(t.fill):{}),d=null;if(t.backgroundEnabled){if(t.legacyBackground){const e=t.backgroundPadding*(t.fontSize*t.lineHeight);d=h("div",{style:{position:"absolute",top:-e/2+"px",left:-e/2+"px",display:"block",width:t.width+e+"px",height:t.height+e+"px",backgroundColor:t.backgroundColor,opacity:t.backgroundOpacity,borderRadius:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)+"px"}})}else{const e=k(t);let o=[];try{o=w(e)}catch(H){o=[]}if(o.length){const i=t.backgroundPadding*(t.fontSize*t.lineHeight*.5),n=t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5),r=x({rects:o,padding:i,cornerRadius:n});if(r){let n=0;try{const{height:o}=$(e);"middle"===t.verticalAlign?n=(t.height-o)/2:"bottom"===t.verticalAlign&&(n=t.height-o)}catch(W){}const a=Math.min(...o.map(t=>t.top)),s=Math.max(...o.map(t=>t.bottom)),l=Math.min(...o.map(t=>t.left)),c=l-i,p=a-i,g=Math.max(...o.map(t=>t.right))-l+2*i,f=s-a+2*i;d=h("svg",{xmlns:"http://www.w3.org/2000/svg",width:g,height:f,viewBox:`${c} ${p} ${g} ${f}`,style:{position:"absolute",top:n+p+"px",left:c+"px",opacity:t.backgroundOpacity,pointerEvents:"none"},innerHTML:`<path d="${r}" fill="${t.backgroundColor}" />`})}}}}else{d=null}const c=/<[a-z][\s\S]*>/i.test(t.text),g=c?v(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}):t.text.split("\n").join("<br />");if(t.strokeWidth&&(n||i&&!n)){const e={position:"absolute",width:t.width+"px",whiteSpace:"pre-wrap",overflowWrap:"break-word",fontSize:t.fontSize+"px",textAlign:t.align,fontFamily:`'${t.fontFamily}'`,textDecoration:t.textDecoration||"none",textDecorationColor:t.textDecoration?t.fill:void 0,textTransform:t.textTransform||"none",lineHeight:t.lineHeight,letterSpacing:t.letterSpacing*t.fontSize+"px",fontStyle:t.fontStyle,fontWeight:t.fontWeight},o=n?Object.assign(Object.assign(Object.assign({},e),a(t.stroke)),{WebkitTextStroke:`${t.strokeWidth}px transparent`}):Object.assign(Object.assign({},e),{color:"transparent",WebkitTextStroke:`${t.strokeWidth}px ${t.stroke}`}),l=i?Object.assign(Object.assign({},e),a(t.fill)):Object.assign(Object.assign({},e),{color:t.fill}),p="el-"+t.id,f=c?`<style>#${p} {${r}}</style>`:"",b=h("div",{style:Object.assign(Object.assign({},o),{position:"absolute",top:0,left:0,pointerEvents:"none"}),"aria-hidden":"true",innerHTML:c?`${f}${g}`:g}),m=h("div",Object.assign(Object.assign({style:Object.assign(Object.assign({},l),{position:"relative"})},c?{id:p}:{}),{innerHTML:c?`${f}${g}`:g}));return h("div",{style:{position:"relative",width:"100%",height:"100%"}},d,h("div",{style:Object.assign({position:"absolute",width:t.width+"px",left:0},s)},b,m))}const b=Object.assign(Object.assign({},l),{position:"absolute",width:t.width+"px",color:t.fill,whiteSpace:"pre-wrap",overflowWrap:"break-word",fontSize:t.fontSize+"px",textAlign:t.align,fontFamily:`'${t.fontFamily}'`,textDecoration:t.textDecoration||"none",textDecorationColor:t.textDecoration?t.fill:void 0,textTransform:t.textTransform||"none",lineHeight:t.lineHeight,letterSpacing:t.letterSpacing*t.fontSize+"px",fontStyle:t.fontStyle,fontWeight:t.fontWeight,WebkitTextStroke:t.strokeWidth?`${t.strokeWidth}px ${t.stroke}`:void 0,paintOrder:t.strokeWidth?"stroke fill":void 0}),j="el-"+t.id,S=c?{id:j}:{},O=`<style>#${j} {${r}}</style>`,z=h("div",Object.assign(Object.assign({style:b},S),{innerHTML:c?`${O}${g}`:g}));return h("div",{style:{position:"relative",width:"100%",height:"100%"}},d,z)},line:async({element:t,page:e,store:o})=>h("svg",{style:{width:"100%",height:"100%",contain:"layout style size",overflow:"visible"}},h("line",{x1:0,y1:t.height/2,x2:t.width,y2:t.height/2,stroke:t.color,"stroke-width":t.height,"stroke-dasharray":t.dash&&t.dash.length?t.dash.map(e=>e*t.height).join(" "):void 0}),h("g",{transform:`translate(0 ${t.height/2})`},z({element:t,type:t.startHead})),h("g",{transform:`translate(${t.width} ${t.height/2}) rotate(180)`},z({element:t,type:t.endHead}))),figure:async({element:t,page:e,store:o,elementHook:i})=>{let r=n(t);if(t.strokeWidth&&m.isGradient(t.stroke)){const e=`figure-stroke-grad-${t.id}`,o=u(t.stroke,e);r=r.replace(new RegExp(`stroke="${t.stroke.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"`,"g"),`stroke="url(#${e})"`),r=r.replace("</defs>",`${o}</defs>`)}if(m.isGradient(t.fill)){const e=`figure-fill-grad-${t.id}`,o=u(t.fill,e);r=r.replace(new RegExp(`fill="${t.fill.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"`,"g"),`fill="url(#${e})"`),r=r.replace("</defs>",`${o}</defs>`)}const a=h("div",{innerHTML:r});return i&&i({dom:a,element:t})||a},group:async({element:t,page:e,store:o,elementHook:i})=>{const n=await Promise.all(t.children.map(t=>W({element:t,page:e,store:o,elementHook:i}))),r=h("div",{style:{transformOrigin:"top left",opacity:t.opacity}},...n);return i&&i({dom:r,element:t})||r},video:async({element:t,page:e,store:o,elementHook:i})=>{const{cropX:n,cropY:r,cropWidth:a,cropHeight:s}=t,d=await l(t.src),c=d.width*a,p=d.height*s,g=t.width/t.height;let f,b;g>=c/p?(f=c,b=c/g):(f=p*g,b=p);const u=f/a,y=b/s,k=n*d.width,x=r*d.height,w=Math.max(t.width/d.width,t.height/d.height),$={position:"absolute",width:`${Math.round(u*w)}px`,height:`${Math.round(y*w)}px`,left:-Math.round(k*w)+"px",top:-Math.round(x*w)+"px",objectFit:"fill"},v=`video-${t.id}`,j=t.borderSize&&m.isGradient(t.borderColor),O=j?Math.max(0,t.cornerRadius-t.borderSize):t.cornerRadius,z=h("div",{style:{position:"relative",width:"100%",height:"100%",overflow:"hidden",borderRadius:O+"px",border:t.borderSize&&!j?`${t.borderSize}px solid ${t.borderColor}`:"none"}},h("video",{id:v,src:t.src,style:$,controls:!0,playsInline:!0,muted:!0,volume:t.volume}));if(j){const e=h("div",{style:{width:"100%",height:"100%",borderRadius:t.cornerRadius+"px",background:S(t.borderColor),padding:t.borderSize+"px",boxSizing:"border-box"}},z);return i&&i({dom:e,element:t})||e}return i&&i({dom:z,element:t})||z},gif:O,table:async({element:t})=>{const e=t.rows,o=t.cols,i=t.colWidths,n=t.rowHeights,r=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],a=(t.cells||[]).map(e=>{if(!e){return e}const o=Object.assign({},e);for(const i of r){void 0===o[i]&&(o[i]=t[i])}return o}),s=[];for(let d=0;d<e;d++){const e=[];for(let i=0;i<o;i++){const r=a[d*o+i];if(!r||r.mergedInto){continue}const s=r.cellPadding||4,l=r.colSpan||1,c=r.rowSpan||1,p=e=>{var o,i,n,a,s;const l=null===(o=r.borders)||void 0===o?void 0:o[e];return`${null!==(i=null==l?void 0:l.width)&&void 0!==i?i:t.borderWidth}px ${null!==(a=null!==(n=null==l?void 0:l.style)&&void 0!==n?n:t.borderStyle)&&void 0!==a?a:"solid"} ${null!==(s=null==l?void 0:l.color)&&void 0!==s?s:t.borderColor}`},f={style:{padding:s+"px",background:r.cellBackground||"transparent",fontSize:(r.fontSize||12)+"px",fontFamily:`'${r.fontFamily||"Roboto"}'`,fontWeight:r.fontWeight||"normal",fontStyle:r.fontStyle||"normal",color:r.fill||"black",textAlign:r.align||"left",verticalAlign:r.verticalAlign||"top",lineHeight:String(r.lineHeight||1.2),letterSpacing:r.letterSpacing?r.letterSpacing*(r.fontSize||12)+"px":void 0,textDecoration:r.textDecoration||"none",textTransform:r.textTransform||"none",borderTop:p("top"),borderRight:p("right"),borderBottom:p("bottom"),borderLeft:p("left"),overflow:"hidden",overflowWrap:"break-word",whiteSpace:"pre-wrap",height:n[d]*t.height+"px"}};l>1&&(f.colspan=String(l)),c>1&&(f.rowspan=String(c)),e.push(h("td",f,g(r.text||"")))}s.push(h("tr",{},...e))}const l=i.map(t=>h("col",{style:{width:100*t+"%"}}));return h("table",{style:{width:"100%",height:"100%",borderCollapse:"collapse",tableLayout:"fixed"}},h("colgroup",{},...l),h("tbody",{},...s))}};async function W({element:t,page:e,store:o,elementHook:i}){var n;let r=await H[t.type];if(r||(r=()=>h("div",{}),console.error(`HTML export does not support ${t.type} type...`)),!t.visible){return null}const l=await r({element:t,page:e,store:o}),d=[],c=[];if(t.blurEnabled&&d.push(`blur(${t.blurRadius/2}px)`),t.brightnessEnabled&&d.push(`brightness(${100*t.brightness+100}%)`),t.sepiaEnabled&&d.push("sepia()"),t.grayscaleEnabled&&d.push("grayscale()"),t.filters){for(const[g,f]of Object.entries(t.filters)){const t=s(a[g],f.intensity);t&&(d.push(t.filter),t.html&&c.push(t.html))}}if(t.shadowEnabled){const e=function(t,e){if(1===e){return t}const o=b.Util.colorToRGBA(t);return o?`rgba(${o.r}, ${o.g}, ${o.b}, ${o.a*e})`:t}(t.shadowColor,null!==(n=t.shadowOpacity)&&void 0!==n?n:1);d.push(`drop-shadow(${t.shadowOffsetX}px ${t.shadowOffsetY}px ${t.shadowBlur/2}px ${e})`)}const p=h("div",{id:t.id,style:{position:"absolute",left:t.x+"px",top:t.y+"px",width:t.width+"px",height:t.height+"px",transform:`rotate(${t.rotation}deg)`,transformOrigin:"top left",opacity:t.opacity,display:t.visible&&t.showInExport?"block":"none",filter:d.join(" ")||"none"}},l,...c);return i&&i({dom:p,element:t})||p}export async function jsonToDOM({json:t,elementHook:i}){const n=await Promise.all(t.pages.map(n=>async function({page:t,store:i,elementHook:n}){const r=[...t.children.filter(t=>!t.alwaysOnTop),...t.children.filter(t=>t.alwaysOnTop)],a=await Promise.all(r.map(e=>W({element:e,page:t,store:i,elementHook:n}))),s="auto"===t.width?i.width:t.width,l="auto"===t.height?i.height:t.height;let d={};if(t.background.indexOf("url")>=0||t.background.indexOf("http")>=0||t.background.indexOf(".jpg")>=0||t.background.indexOf(".png")>=0||t.background.indexOf(".jpeg")>=0){const{width:n,height:r}=await o(t.background),d=await O({element:Object.assign({x:0,y:0,width:s,height:l,src:t.background,cornerRadius:0},e({width:s,height:l},{width:n,height:r})),page:t,store:i});a.unshift(d)}else{d=m.isGradient(t.background)?Object.assign(Object.assign({},d),{backgroundImage:t.background}):Object.assign(Object.assign({},d),{backgroundColor:t.background})}return h("div",{className:"page",id:t.id,style:Object.assign(Object.assign({},d),{width:s+"px",height:l+"px",overflow:"hidden",position:"relative"})},...a)}({page:n,store:t,elementHook:i}))),r=[];c({children:t.pages},t=>{if(("text"===t.type||"tablecell"===t.type||"table"===t.type)&&(t.fontFamily&&-1===r.indexOf(t.fontFamily)&&r.push(t.fontFamily),t.text)){for(const e of j(t.text)){-1===r.indexOf(e)&&r.push(e)}}});const a=r.map(e=>{const o=t.fonts.find(t=>t.fontFamily===e);if(o){const t=(o.styles||(o.url?[{src:`url("${o.url}")`}]:[])).map(t=>`\n @font-face {\n font-family: '${o.fontFamily}';\n src: ${t.src};\n font-style: ${t.fontStyle||"normal"};\n font-weight: ${t.fontWeight||"normal"};\n font-display: swap;\n }`).join("\n");return h("style",{},t)}return h("link",{href:d(e),rel:"stylesheet"})});return h("div",{className:"design"},...a,...n)}const T=({dom:e})=>{if("string"==typeof e){return e}if(!e){return""}const o=e.props,{innerHTML:i}=o,n=t(o,["innerHTML"]),r=Object.keys(n).map(t=>"style"===t&&"object"==typeof n[t]?`style="${Object.keys(n[t]).filter(e=>null!=n[t][e]).map(e=>`${e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}: ${n[t][e]}`).join("; ")}"`:((t,e)=>null==e||""===e?"":"object"==typeof e?`${t}="${Object.keys(e).map(t=>`${t.replace(/-([a-z])/g,t=>t[1].toUpperCase())}:${e[t]};`).join(" ")}"`:`${t}="${e}"`)(t,n[t])).filter(t=>t&&t.trim().length>0).join(" ");return`<${e.type} ${r}>${i||e.children.map(t=>T({dom:t})).join("")}</${e.type}>`};export async function jsonToHTML({json:t,elementHook:e}){const o=await jsonToDOM({json:t,elementHook:e});return T({dom:o})}
|
|
1
|
+
var t=this&&this.__rest||function(t,e){var o={};for(var i in t){Object.prototype.hasOwnProperty.call(t,i)&&e.indexOf(i)<0&&(o[i]=t[i])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(i=Object.getOwnPropertySymbols(t);n<i.length;n++){e.indexOf(i[n])<0&&Object.prototype.propertyIsEnumerable.call(t,i[n])&&(o[i[n]]=t[i[n]])}}return o};import{getCrop as e,loadImage as o}from"./image.js";import*as i from"./svg.js";import{figureToSvg as n}from"./figure-to-svg.js";import{resetStyleContent as r}from"./reset-style.js";import{Effects as a,shapeFilterToCSS as s}from"./filters.js";import{getElementBlurRadius as l}from"../canvas/apply-filters.js";import{getVideoSize as d}from"./video.js";import{getGoogleFontsUrl as c}from"./fonts.js";import{forEveryNode as p}from"../model/group-model.js";import{getCurvePath as g}from"../canvas/text-element.js";import{removeTags as f,parseHtmlToSegments as m}from"./text.js";import b from"konva";import*as u from"./gradient.js";import{createSVGGradientDef as y,segmentsToTspans as k,getHtml as x,normalizeStrokeLineJoin as w}from"./text-html.js";import{generateBackgroundShapeFromRects as $}from"./background-shape.js";import{detectLineRects as v,detectSize as j}from"./html2canvas.js";import{normalizeRichTextHtml as S,extractFontFamiliesFromHtml as O}from"./rich-text-html.js";export const h=(t,e,...o)=>({type:t,props:e,children:o||[]});function z(t){return u.isGradient(t),t}export function fixRatio(t){var e=(new DOMParser).parseFromString(t,"image/svg+xml");return e.documentElement.setAttribute("preserveAspectRatio","none"),(new XMLSerializer).serializeToString(e)}const H=async({element:t,page:e,store:n})=>{let{src:r}=t;if("svg"===t.type){let e=await i.urlToString(r);e=fixRatio(e),r=Object.keys(t.colorsReplace).length?i.replaceColors(e,new Map(Object.entries(t.colorsReplace))):i.svgToURL(e)}let a="";t.flipX&&(a+="scaleX(-1)"),t.flipY&&(a+="scaleY(-1)"),a||(a="none");const s={};if("svg"===t.type&&t.maskSrc){const e=await i.urlToBase64(r);s["mask-image"]=`url(${e})`,s["mask-size"]="100% 100%",s["mask-position"]="0 0",s["mask-repeat"]="no-repeat",s["-webkit-mask-image"]=`url(${e})`,s["-webkit-mask-size"]="100% 100%",s["-webkit-mask-position"]="0 0",s["-webkit-mask-repeat"]="no-repeat",r=t.maskSrc}else if(t.clipSrc){const e=t.clipSrc,o=await i.urlToBase64(e);s["mask-image"]=`url(${o})`,s["mask-size"]="100% 100%",s["mask-position"]="0 0",s["mask-repeat"]="no-repeat",s["-webkit-mask-image"]=`url(${o})`,s["-webkit-mask-size"]="100% 100%",s["-webkit-mask-position"]="0 0",s["-webkit-mask-repeat"]="no-repeat"}const l=await o(r),d=l.width*t.cropWidth,c=l.height*t.cropHeight,p=t.width/t.height;let g,f;const m=d/c,b="svg"===t.type||t.stretchEnabled;b?(g=d,f=c):p>=m?(g=d,f=d/p):(g=c*p,f=c);const y=g/l.width,k=f/l.height,x=g/f>t.width/t.height?t.height/f:t.width/g,w=b?t.width/g:x,$=b?t.height/f:x,v=g*w/y,j=f*$/k;let S=t.cropX*w*l.width,O=t.cropY*$*l.height;t.flipX&&(S=(1-t.cropX-t.cropWidth)*w*l.width),t.flipY&&(O=(1-t.cropY-t.cropHeight)*$*l.height);const H=t.borderSize&&u.isGradient(t.borderColor),W=H?Math.max(0,t.cornerRadius-t.borderSize):t.cornerRadius,T=h("div",{style:Object.assign(Object.assign({},s),{width:"100%",height:"100%",borderRadius:W+"px",border:t.borderSize&&!H?`${t.borderSize}px solid ${t.borderColor}`:"none",backgroundRepeat:"no-repeat",backgroundImage:`url(${r})`,transform:a,backgroundSize:`${Math.round(v)}px ${Math.round(j)}px`,backgroundPositionX:-Math.round(S)+"px",backgroundPositionY:-Math.round(O)+"px"})});return H?h("div",{style:{width:"100%",height:"100%",borderRadius:t.cornerRadius+"px",background:z(t.borderColor),padding:t.borderSize+"px",boxSizing:"border-box"}},T):T},W=({element:t,type:e})=>{const o={"stroke-width":t.height,stroke:t.color,"stroke-linecap":"round","stroke-linejoin":"round",opacity:t.opacity},i=Object.assign(Object.assign({},o),{fill:t.color}),n=Object.assign(Object.assign({},o),{fill:"none"});return"arrow"===e?h("polyline",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},n)):"triangle"===e?h("polygon",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},i)):"bar"===e?h("polyline",Object.assign({points:`0,${2*-t.height} 0,${2*t.height}`},n)):"circle"===e?h("circle",Object.assign({cx:2*t.height,cy:0,r:2*t.height},i)):"square"===e?h("polygon",Object.assign({points:`0,${2*-t.height} ${4*t.height},${2*-t.height} ${4*t.height},${2*t.height} 0,${2*t.height}`},i)):null},T={image:H,svg:H,text:async({element:t,page:e,store:o})=>{const i=u.isGradient(t.fill),n=u.isGradient(t.stroke);if(t.curveEnabled){const e=S(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}),o=m(e,{fontSize:t.fontSize,fontFamily:t.fontFamily}),r=Math.max(t.fontSize,...o.map(e=>{var o;return null!==(o=e.fontSize)&&void 0!==o?o:t.fontSize})),a=g(t.width,t.height,t.curvePower,r),s={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:t.fontSize},l=k(o,s);let d=`\n <svg xmlns="http://www.w3.org/2000/svg" width="${t.width}" height="${t.height}" style="display: block;">\n <defs>\n <path id="curve-${t.id}" d="${a}" fill="none" />`;if(i){const e=`curve-fill-grad-${t.id}`;d+=y(t.fill,e)}if(n&&t.strokeWidth){const e=`curve-stroke-grad-${t.id}`;d+=y(t.stroke,e)}d+=`</defs>\n <text\n font-family="'${t.fontFamily}'"\n font-size="${t.fontSize}"\n font-weight="${t.fontWeight}"\n font-style="${t.fontStyle}"\n fill="${i?`url(#curve-fill-grad-${t.id})`:t.fill}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${t.letterSpacing*r}"${t.textDecoration?` text-decoration="${t.textDecoration}"`:""}${t.strokeWidth?` stroke="${n?`url(#curve-stroke-grad-${t.id})`:t.stroke}" stroke-width="${t.strokeWidth}" stroke-linejoin="${w(t.strokeLineJoin)}" paint-order="stroke fill"`:""}>\n <textPath href="#curve-${t.id}" startOffset="50%">${l}</textPath>\n </text>\n </svg>`;const c=t.backgroundPadding*(t.fontSize*t.lineHeight),p=t.backgroundEnabled&&h("div",{style:{position:"absolute",top:-c/2+"px",left:-c/2+"px",width:t.width+c+"px",height:t.height+c+"px",backgroundColor:t.backgroundColor,opacity:t.backgroundOpacity,borderRadius:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)+"px"}}),f=h("div",{style:{width:"100%",height:"100%",position:"absolute",top:0,left:0},innerHTML:d});return h("div",{style:{position:"relative",width:"100%",height:"100%"}},p,f)}const a=t=>({backgroundImage:t,backgroundSize:"100% 100%",backgroundRepeat:"repeat",WebkitBackgroundClip:"text",MozBackgroundClip:"text",backgroundClip:"text",WebkitTextFillColor:"transparent",MozTextFillColor:"transparent",color:"transparent"}),s="middle"===t.verticalAlign?{top:"50%",transform:"translateY(-50%)"}:"bottom"===t.verticalAlign?{bottom:0}:{top:0};let l=Object.assign(Object.assign({left:0},s),i?a(t.fill):{}),d=null;if(t.backgroundEnabled){if(t.legacyBackground){const e=t.backgroundPadding*(t.fontSize*t.lineHeight);d=h("div",{style:{position:"absolute",top:-e/2+"px",left:-e/2+"px",display:"block",width:t.width+e+"px",height:t.height+e+"px",backgroundColor:t.backgroundColor,opacity:t.backgroundOpacity,borderRadius:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)+"px"}})}else{const e=x(t);let o=[];try{o=v(e)}catch(W){o=[]}if(o.length){const i=t.backgroundPadding*(t.fontSize*t.lineHeight*.5),n=t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5),r=$({rects:o,padding:i,cornerRadius:n});if(r){let n=0;try{const{height:o}=j(e);"middle"===t.verticalAlign?n=(t.height-o)/2:"bottom"===t.verticalAlign&&(n=t.height-o)}catch(T){}const a=Math.min(...o.map(t=>t.top)),s=Math.max(...o.map(t=>t.bottom)),l=Math.min(...o.map(t=>t.left)),c=l-i,p=a-i,g=Math.max(...o.map(t=>t.right))-l+2*i,f=s-a+2*i;d=h("svg",{xmlns:"http://www.w3.org/2000/svg",width:g,height:f,viewBox:`${c} ${p} ${g} ${f}`,style:{position:"absolute",top:n+p+"px",left:c+"px",opacity:t.backgroundOpacity,pointerEvents:"none"},innerHTML:`<path d="${r}" fill="${t.backgroundColor}" />`})}}}}else{d=null}const c=/<[a-z][\s\S]*>/i.test(t.text),p=c?S(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}):t.text.split("\n").join("<br />");if(t.strokeWidth&&(n||i&&!n)){const e={position:"absolute",width:t.width+"px",whiteSpace:"pre-wrap",overflowWrap:"break-word",fontSize:t.fontSize+"px",textAlign:t.align,fontFamily:`'${t.fontFamily}'`,textDecoration:t.textDecoration||"none",textDecorationColor:t.textDecoration?t.fill:void 0,textTransform:t.textTransform||"none",lineHeight:t.lineHeight,letterSpacing:t.letterSpacing*t.fontSize+"px",fontStyle:t.fontStyle,fontWeight:t.fontWeight},o=n?Object.assign(Object.assign(Object.assign({},e),a(t.stroke)),{WebkitTextStroke:`${t.strokeWidth}px transparent`}):Object.assign(Object.assign({},e),{color:"transparent",WebkitTextStroke:`${t.strokeWidth}px ${t.stroke}`}),l=i?Object.assign(Object.assign({},e),a(t.fill)):Object.assign(Object.assign({},e),{color:t.fill}),g="el-"+t.id,f=c?`<style>#${g} {${r}}</style>`:"",m=h("div",{style:Object.assign(Object.assign({},o),{position:"absolute",top:0,left:0,pointerEvents:"none"}),"aria-hidden":"true",innerHTML:c?`${f}${p}`:p}),b=h("div",Object.assign(Object.assign({style:Object.assign(Object.assign({},l),{position:"relative"})},c?{id:g}:{}),{innerHTML:c?`${f}${p}`:p}));return h("div",{style:{position:"relative",width:"100%",height:"100%"}},d,h("div",{style:Object.assign({position:"absolute",width:t.width+"px",left:0},s)},m,b))}const f=Object.assign(Object.assign({},l),{position:"absolute",width:t.width+"px",color:t.fill,whiteSpace:"pre-wrap",overflowWrap:"break-word",fontSize:t.fontSize+"px",textAlign:t.align,fontFamily:`'${t.fontFamily}'`,textDecoration:t.textDecoration||"none",textDecorationColor:t.textDecoration?t.fill:void 0,textTransform:t.textTransform||"none",lineHeight:t.lineHeight,letterSpacing:t.letterSpacing*t.fontSize+"px",fontStyle:t.fontStyle,fontWeight:t.fontWeight,WebkitTextStroke:t.strokeWidth?`${t.strokeWidth}px ${t.stroke}`:void 0,paintOrder:t.strokeWidth?"stroke fill":void 0}),b="el-"+t.id,O=c?{id:b}:{},z=`<style>#${b} {${r}}</style>`,H=h("div",Object.assign(Object.assign({style:f},O),{innerHTML:c?`${z}${p}`:p}));return h("div",{style:{position:"relative",width:"100%",height:"100%"}},d,H)},line:async({element:t,page:e,store:o})=>h("svg",{style:{width:"100%",height:"100%",contain:"layout style size",overflow:"visible"}},h("line",{x1:0,y1:t.height/2,x2:t.width,y2:t.height/2,stroke:t.color,"stroke-width":t.height,"stroke-dasharray":t.dash&&t.dash.length?t.dash.map(e=>e*t.height).join(" "):void 0}),h("g",{transform:`translate(0 ${t.height/2})`},W({element:t,type:t.startHead})),h("g",{transform:`translate(${t.width} ${t.height/2}) rotate(180)`},W({element:t,type:t.endHead}))),figure:async({element:t,page:e,store:o,elementHook:i})=>{let r=n(t);if(t.strokeWidth&&u.isGradient(t.stroke)){const e=`figure-stroke-grad-${t.id}`,o=y(t.stroke,e);r=r.replace(new RegExp(`stroke="${t.stroke.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"`,"g"),`stroke="url(#${e})"`),r=r.replace("</defs>",`${o}</defs>`)}if(u.isGradient(t.fill)){const e=`figure-fill-grad-${t.id}`,o=y(t.fill,e);r=r.replace(new RegExp(`fill="${t.fill.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"`,"g"),`fill="url(#${e})"`),r=r.replace("</defs>",`${o}</defs>`)}const a=h("div",{innerHTML:r});return i&&i({dom:a,element:t})||a},group:async({element:t,page:e,store:o,elementHook:i})=>{const n=await Promise.all(t.children.map(t=>M({element:t,page:e,store:o,elementHook:i}))),r=h("div",{style:{transformOrigin:"top left",opacity:t.opacity}},...n);return i&&i({dom:r,element:t})||r},video:async({element:t,page:e,store:o,elementHook:i})=>{const{cropX:n,cropY:r,cropWidth:a,cropHeight:s}=t,l=await d(t.src),c=l.width*a,p=l.height*s,g=t.width/t.height;let f,m;g>=c/p?(f=c,m=c/g):(f=p*g,m=p);const b=f/a,y=m/s,k=n*l.width,x=r*l.height,w=Math.max(t.width/l.width,t.height/l.height),$={position:"absolute",width:`${Math.round(b*w)}px`,height:`${Math.round(y*w)}px`,left:-Math.round(k*w)+"px",top:-Math.round(x*w)+"px",objectFit:"fill"},v=`video-${t.id}`,j=t.borderSize&&u.isGradient(t.borderColor),S=j?Math.max(0,t.cornerRadius-t.borderSize):t.cornerRadius,O=h("div",{style:{position:"relative",width:"100%",height:"100%",overflow:"hidden",borderRadius:S+"px",border:t.borderSize&&!j?`${t.borderSize}px solid ${t.borderColor}`:"none"}},h("video",{id:v,src:t.src,style:$,controls:!0,playsInline:!0,muted:!0,volume:t.volume}));if(j){const e=h("div",{style:{width:"100%",height:"100%",borderRadius:t.cornerRadius+"px",background:z(t.borderColor),padding:t.borderSize+"px",boxSizing:"border-box"}},O);return i&&i({dom:e,element:t})||e}return i&&i({dom:O,element:t})||O},gif:H,table:async({element:t})=>{const e=t.rows,o=t.cols,i=t.colWidths,n=t.rowHeights,r=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],a=(t.cells||[]).map(e=>{if(!e){return e}const o=Object.assign({},e);for(const i of r){void 0===o[i]&&(o[i]=t[i])}return o}),s=[];for(let d=0;d<e;d++){const e=[];for(let i=0;i<o;i++){const r=a[d*o+i];if(!r||r.mergedInto){continue}const s=r.cellPadding||4,l=r.colSpan||1,c=r.rowSpan||1,p=e=>{var o,i,n,a,s;const l=null===(o=r.borders)||void 0===o?void 0:o[e];return`${null!==(i=null==l?void 0:l.width)&&void 0!==i?i:t.borderWidth}px ${null!==(a=null!==(n=null==l?void 0:l.style)&&void 0!==n?n:t.borderStyle)&&void 0!==a?a:"solid"} ${null!==(s=null==l?void 0:l.color)&&void 0!==s?s:t.borderColor}`},g={style:{padding:s+"px",background:r.cellBackground||"transparent",fontSize:(r.fontSize||12)+"px",fontFamily:`'${r.fontFamily||"Roboto"}'`,fontWeight:r.fontWeight||"normal",fontStyle:r.fontStyle||"normal",color:r.fill||"black",textAlign:r.align||"left",verticalAlign:r.verticalAlign||"top",lineHeight:String(r.lineHeight||1.2),letterSpacing:r.letterSpacing?r.letterSpacing*(r.fontSize||12)+"px":void 0,textDecoration:r.textDecoration||"none",textTransform:r.textTransform||"none",borderTop:p("top"),borderRight:p("right"),borderBottom:p("bottom"),borderLeft:p("left"),overflow:"hidden",overflowWrap:"break-word",whiteSpace:"pre-wrap",height:n[d]*t.height+"px"}};l>1&&(g.colspan=String(l)),c>1&&(g.rowspan=String(c)),e.push(h("td",g,f(r.text||"")))}s.push(h("tr",{},...e))}const l=i.map(t=>h("col",{style:{width:100*t+"%"}}));return h("table",{style:{width:"100%",height:"100%",borderCollapse:"collapse",tableLayout:"fixed"}},h("colgroup",{},...l),h("tbody",{},...s))}};async function M({element:t,page:e,store:o,elementHook:i}){var n;let r=await T[t.type];if(r||(r=()=>h("div",{}),console.error(`HTML export does not support ${t.type} type...`)),!t.visible){return null}const d=await r({element:t,page:e,store:o}),c=[],p=[];if(t.blurEnabled&&c.push(`blur(${l(t)/2}px)`),t.brightnessEnabled&&c.push(`brightness(${100*t.brightness+100}%)`),t.sepiaEnabled&&c.push("sepia()"),t.grayscaleEnabled&&c.push("grayscale()"),t.filters){for(const[l,f]of Object.entries(t.filters)){const t=s(a[l],f.intensity);t&&(c.push(t.filter),t.html&&p.push(t.html))}}if(t.shadowEnabled){const e=function(t,e){if(1===e){return t}const o=b.Util.colorToRGBA(t);return o?`rgba(${o.r}, ${o.g}, ${o.b}, ${o.a*e})`:t}(t.shadowColor,null!==(n=t.shadowOpacity)&&void 0!==n?n:1);c.push(`drop-shadow(${t.shadowOffsetX}px ${t.shadowOffsetY}px ${t.shadowBlur/2}px ${e})`)}const g=h("div",{id:t.id,style:{position:"absolute",left:t.x+"px",top:t.y+"px",width:t.width+"px",height:t.height+"px",transform:`rotate(${t.rotation}deg)`,transformOrigin:"top left",opacity:t.opacity,display:t.visible&&t.showInExport?"block":"none",filter:c.join(" ")||"none"}},d,...p);return i&&i({dom:g,element:t})||g}export async function jsonToDOM({json:t,elementHook:i}){const n=await Promise.all(t.pages.map(n=>async function({page:t,store:i,elementHook:n}){const r=[...t.children.filter(t=>!t.alwaysOnTop),...t.children.filter(t=>t.alwaysOnTop)],a=await Promise.all(r.map(e=>M({element:e,page:t,store:i,elementHook:n}))),s="auto"===t.width?i.width:t.width,l="auto"===t.height?i.height:t.height;let d={};if(t.background.indexOf("url")>=0||t.background.indexOf("http")>=0||t.background.indexOf(".jpg")>=0||t.background.indexOf(".png")>=0||t.background.indexOf(".jpeg")>=0){const{width:n,height:r}=await o(t.background),d=await H({element:Object.assign({x:0,y:0,width:s,height:l,src:t.background,cornerRadius:0},e({width:s,height:l},{width:n,height:r})),page:t,store:i});a.unshift(d)}else{d=u.isGradient(t.background)?Object.assign(Object.assign({},d),{backgroundImage:t.background}):Object.assign(Object.assign({},d),{backgroundColor:t.background})}return h("div",{className:"page",id:t.id,style:Object.assign(Object.assign({},d),{width:s+"px",height:l+"px",overflow:"hidden",position:"relative"})},...a)}({page:n,store:t,elementHook:i}))),r=[];p({children:t.pages},t=>{if(("text"===t.type||"tablecell"===t.type||"table"===t.type)&&(t.fontFamily&&-1===r.indexOf(t.fontFamily)&&r.push(t.fontFamily),t.text)){for(const e of O(t.text)){-1===r.indexOf(e)&&r.push(e)}}});const a=r.map(e=>{const o=t.fonts.find(t=>t.fontFamily===e);if(o){const t=(o.styles||(o.url?[{src:`url("${o.url}")`}]:[])).map(t=>`\n @font-face {\n font-family: '${o.fontFamily}';\n src: ${t.src};\n font-style: ${t.fontStyle||"normal"};\n font-weight: ${t.fontWeight||"normal"};\n font-display: swap;\n }`).join("\n");return h("style",{},t)}return h("link",{href:c(e),rel:"stylesheet"})});return h("div",{className:"design"},...a,...n)}const R=({dom:e})=>{if("string"==typeof e){return e}if(!e){return""}const o=e.props,{innerHTML:i}=o,n=t(o,["innerHTML"]),r=Object.keys(n).map(t=>"style"===t&&"object"==typeof n[t]?`style="${Object.keys(n[t]).filter(e=>null!=n[t][e]).map(e=>`${e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}: ${n[t][e]}`).join("; ")}"`:((t,e)=>null==e||""===e?"":"object"==typeof e?`${t}="${Object.keys(e).map(t=>`${t.replace(/-([a-z])/g,t=>t[1].toUpperCase())}:${e[t]};`).join(" ")}"`:`${t}="${e}"`)(t,n[t])).filter(t=>t&&t.trim().length>0).join(" ");return`<${e.type} ${r}>${i||e.children.map(t=>R({dom:t})).join("")}</${e.type}>`};export async function jsonToHTML({json:t,elementHook:e}){const o=await jsonToDOM({json:t,elementHook:e});return R({dom:o})}
|
package/utils/to-svg.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var t=this&&this.__rest||function(t,e){var n={};for(var o in t){Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(n[o]=t[o])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(t);i<o.length;i++){e.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(t,o[i])&&(n[o[i]]=t[o[i]])}}return n};import{cropImage as e,getCrop as n,loadImage as o}from"./image.js";import*as i from"./svg.js";import{figureToSvg as r}from"./figure-to-svg.js";import{Effects as l,shapeFilterToCSS as s}from"./filters.js";import{removeTags as a,parseHtmlToSegments as h}from"./text.js";import{segmentsToTspans as c}from"./text-html.js";import{xmlEscape as d}from"./xml.js";import{getCurvePath as f}from"../canvas/text-element.js";import*as g from"./gradient.js";import{normalizeRichTextHtml as p,extractFontFamiliesFromHtml as u}from"./rich-text-html.js";import{bulletMarkerPosition as m,numberMarkerPosition as y}from"./list-marker-geometry.js";import{generateBackgroundShapeFromRects as x,textLinesToRects as w}from"./background-shape.js";export const forEveryNode=(t,e)=>{if(t.children){for(const n of t.children){if(!0===e(n)){break}forEveryNode(n,e)}}if(t.cells){for(const n of t.cells){if(!0===e(n)){break}}}};const k=(t,e,...n)=>({type:t,props:e,children:n||[]});function b(t,e){if(!g.isGradient(t)){return null}const{stops:n,rotation:o}=g.parseColor(t),i=o*Math.PI/180,r=.5-.5*Math.sin(i),l=.5+.5*Math.cos(i),s=.5+.5*Math.sin(i),a=.5-.5*Math.cos(i),h=n.map(({offset:t,color:e})=>k("stop",{offset:100*t+"%","stop-color":e}));return k("linearGradient",{id:e,x1:100*r+"%",y1:100*l+"%",x2:100*s+"%",y2:100*a+"%"},...h)}export function fixRatio(t){var e=(new DOMParser).parseFromString(t,"image/svg+xml");return e.documentElement.setAttribute("preserveAspectRatio","none"),(new XMLSerializer).serializeToString(e)}const $=async t=>{try{const e=await fetch(t);if("undefined"!=typeof Buffer){const t=await e.arrayBuffer(),n=Buffer.from(t).toString("base64");return`data:${e.headers.get("content-type")||"image/png"};base64,${n}`}{const t=await e.blob();return new Promise((e,n)=>{const o=new FileReader;o.onloadend=()=>e(o.result),o.onerror=n,o.readAsDataURL(t)})}}catch(e){return console.error("Error converting URL to data URL:",e),t}},v=async({element:t,page:e,store:n})=>{let{src:r}=t;if("svg"===t.type){const e=await i.urlToString(r);r=i.replaceColors(e,new Map(Object.entries(t.colorsReplace)))}else{r=await $(r)}let l,s,a,h,c="";if(t.flipX||t.flipY){const e=t.flipX?-1:1,n=t.flipY?-1:1,o=t.width/2,i=t.height/2;c=`translate(${o}, ${i}) scale(${e}, ${n}) translate(${-o}, ${-i})`}t.clipSrc&&(l=`clip-img-mask-${t.id}`,s=await $(t.clipSrc)),t.maskSrc&&(a=`mask-img-${t.id}`,h=await $(t.maskSrc));const d=await o(r),f=d.width*t.cropWidth,p=d.height*t.cropHeight,u=t.width/t.height;let m,y;const x=f/p,w="boolean"==typeof t.stretchEnabled&&t.stretchEnabled||"svg"===t.type;w?(m=f,y=p):u>=x?(m=f,y=f/u):(m=p*u,y=p);const v=m/d.width,S=y/d.height,O=m/y>t.width/t.height?t.height/y:t.width/m,j=w?t.width/m:O,H=w?t.height/y:O,z=m*j/v,W=y*H/S;let M=t.cropX*d.width*j,E=t.cropY*d.height*H;t.flipX&&(M=(1-t.cropX-t.cropWidth)*d.width*j),t.flipY&&(E=(1-t.cropY-t.cropHeight)*d.height*H);const F=`clip-${t.id}`,T=t.cornerRadius||0,L=r.replace(/&/g,"&"),C={x:-M,y:-E,width:z,height:W,preserveAspectRatio:"none","clip-path":`url(#${F})`},A=[k("clipPath",{id:F},k("rect",{x:0,y:0,width:t.width,height:t.height,rx:T||void 0,ry:T||void 0}))];l&&s&&A.push(k("mask",{id:l,maskUnits:"userSpaceOnUse","mask-type":"alpha"},k("image",{href:s.replace(/&/g,"&"),x:0,y:0,width:t.width,height:t.height,preserveAspectRatio:"none"}))),a&&A.push(k("mask",{id:a,maskUnits:"userSpaceOnUse","mask-type":"alpha"},k("image",Object.assign({href:L},C))));let B=L;const R={};a&&h&&(B=h.replace(/&/g,"&"),R.mask=`url(#${a})`);const P={};l&&(P.mask=`url(#${l})`);const D=t.borderSize||0,N=D>0&&g.isGradient(t.borderColor),U=N?`border-grad-${t.id}`:null;if(N){const e=b(t.borderColor,U);e&&A.push(e)}const G=D>0?k("rect",{x:D/2,y:D/2,width:Math.max(0,t.width-D),height:Math.max(0,t.height-D),fill:"none",stroke:N?`url(#${U})`:t.borderColor,"stroke-width":D,rx:Math.max(0,T-D)||void 0,ry:Math.max(0,T-D)||void 0}):null,I=k("g",{},k("defs",{},...A),k("image",Object.assign(Object.assign({href:B},C),R)),G);return k("g",P,c?k("g",{transform:c},I):I)},S=({element:t,type:e})=>{const n={"stroke-width":t.height,stroke:t.color,"stroke-linecap":"round","stroke-linejoin":"round"},o=Object.assign(Object.assign({},n),{fill:t.color}),i=Object.assign(Object.assign({},n),{fill:"none"});return"arrow"===e?k("polyline",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},i)):"triangle"===e?k("polygon",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},o)):"bar"===e?k("polyline",Object.assign({points:`0,${2*-t.height} 0,${2*t.height}`},i)):"circle"===e?k("circle",Object.assign({cx:2*t.height,cy:0,r:2*t.height},o)):"square"===e?k("polygon",Object.assign({points:`0,${2*-t.height} ${4*t.height},${2*-t.height} ${4*t.height},${2*t.height} 0,${2*t.height}`},o)):null},O={image:v,svg:v,text:async({element:t,page:e,store:n})=>{const o=g.isGradient(t.fill),i=g.isGradient(t.stroke);if(t.curveEnabled){const e=p(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}),n=h(e,{fontSize:t.fontSize,fontFamily:t.fontFamily}),r=Math.max(t.fontSize,...n.map(e=>{var n;return null!==(n=e.fontSize)&&void 0!==n?n:t.fontSize})),l=f(t.width,t.height,t.curvePower,r),s=z(t.id||"temp"),a=`curve-path-${s}`,d={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:t.fontSize},g=c(n,d),u=c(n,d,{omitColors:!0}),m=t.backgroundPadding*(t.fontSize*t.lineHeight*.5),y=t.backgroundEnabled?k("rect",{x:-m,y:-m,width:t.width+2*m,height:t.height+2*m,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5),ry:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)}):null,x=[k("path",{id:a,d:l,fill:"none"})],w=t.strokeWidth&&(i||o&&!i);if(o){const e=`curve-fill-grad-${s}`,n=b(t.fill,e);n&&x.push(n)}if(i&&t.strokeWidth){const e=`curve-stroke-grad-${s}`,n=b(t.stroke,e);n&&x.push(n)}if(w){const e={"font-size":t.fontSize+"px","text-anchor":"middle","dominant-baseline":"central","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration||void 0,"letter-spacing":t.letterSpacing*r},n=i?`url(#curve-stroke-grad-${s})`:t.stroke,l=k("text",Object.assign(Object.assign({},e),{fill:n,"stroke-width":t.strokeWidth,stroke:n}),k("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:u})),h=o?`url(#curve-fill-grad-${s})`:t.fill,c=k("text",Object.assign(Object.assign({},e),{fill:h}),k("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:g}));return k("g",{},y,k("defs",{},...x),l,c)}return k("g",{},y,k("defs",{},...x),k("text",{fill:o?`url(#curve-fill-grad-${s})`:t.fill,"font-size":t.fontSize+"px","text-anchor":"middle","dominant-baseline":"central","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration||void 0,"letter-spacing":t.letterSpacing*r,"stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?i?`url(#curve-stroke-grad-${s})`:t.stroke:void 0,"paint-order":t.strokeWidth?"stroke fill":void 0},k("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:g})))}let r=null;const l=()=>(r||(r=document.createElement("canvas").getContext("2d")),r),s=(t,e,n,o,i,r=0)=>{const s=l();return s.font=`${i} ${o} ${e}px ${n}`,s.measureText(t).width+Math.max(0,(t?t.length:0)-1)*r*e},a=(e,n,o)=>{let i=n;null!=e.fontSize&&e.fontSize!==t.fontSize&&t.fontSize>0&&(i=e.fontSize*(n/t.fontSize));const r=e.fontFamily||t.fontFamily,l=e.bold?"bold":t.fontWeight||"normal",a=e.italic?"italic":t.fontStyle||"normal";return s(e.text,i,r,l,a,o)},u=/<[a-z][\s\S]*>/i.test(t.text);let $=t.text;!u&&$.includes("\n")&&($=$.split("\n").map(t=>`<p>${t}</p>`).join(""));const v=p($,{fontSize:t.fontSize,fontFamily:t.fontFamily}),S={fontSize:t.fontSize,fontFamily:t.fontFamily},O=[],j=(new DOMParser).parseFromString(v,"text/html"),H=j.body.querySelectorAll("p");H.length>0?H.forEach((t,e)=>{const n=t.innerHTML,o=h(n,S);O.push(...o),e<H.length-1&&O.push({text:"\n"})}):O.push(...h(v,S)),"uppercase"===t.textTransform&&O.forEach(t=>{"\n"!==t.text&&(t.text=t.text.toUpperCase())});const W=t=>{const e=[];let n=[];for(const o of t){if("\n"===o.text){n.length>0&&(e.push(n),n=[]),e.push([Object.assign(Object.assign({},o),{text:"\n"})]);continue}const t=o.text.split(/( )/);for(const i of t){""!==i&&(" "===i?(n.length>0&&(e.push(n),n=[]),e.push([Object.assign(Object.assign({},o),{text:" "})])):n.push(Object.assign(Object.assign({},o),{text:i})))}}return n.length>0&&e.push(n),e},M=(t,e,n,o)=>{const i=[[]];let r=0;for(const l of t){if(1===l.length&&"\n"===l[0].text){i.push([]),r=0;continue}const t=l.reduce((t,e)=>t+a(e,n,o),0);1!==l.length||" "!==l[0].text?(r+t>e+.5&&i[i.length-1].length>0&&(i.push([]),r=0),i[i.length-1].push(...l),r+=t):r+t<=e+.5&&(i[i.length-1].push(...l),r+=t)}return i},E=(t,e,n)=>t.reduce((t,o)=>t+a(o,e,n),0),F=(t,e)=>1===e?t:t.map(t=>t.map(t=>t.fontSize?Object.assign(Object.assign({},t),{fontSize:Math.round(t.fontSize*e*1e3)/1e3}):t));if(j.body.querySelector("ul, ol")){const e=[],n=2.1,r=e=>{const n=e.cloneNode(!0);n.querySelectorAll("ul, ol").forEach(t=>t.remove());const o=h(n.innerHTML,S);return"uppercase"===t.textTransform&&o.forEach(t=>{"\n"!==t.text&&(t.text=t.text.toUpperCase())}),o},a=(t,n)=>{for(const o of Array.from(t.children)){const t=o.tagName.toLowerCase();if("ul"===t||"ol"===t){const i="ol"===t;let l=parseInt(o.getAttribute("start")||"1",10)||1;for(const t of Array.from(o.children)){if("li"!==t.tagName.toLowerCase()){continue}const o=t.getAttribute("value");o&&!Number.isNaN(parseInt(o,10))&&(l=parseInt(o,10));const s=i?{text:`${l}.`,isOrdered:!0}:{text:"•",isOrdered:!1};e.push({segments:r(t),depth:n+1,marker:s}),i&&(l+=1),a(t,n+1)}}else{"p"===t||"div"===t?e.push({segments:r(o),depth:0,marker:null}):e.push({segments:h(o.outerHTML,S),depth:0,marker:null})}}};a(j.body,0);const f=o=>{const i=[],r=[];for(const l of e){const e=l.depth*n*o,s=Math.max(1,t.width-e);(0===l.segments.length?[[]]:M(W(l.segments),s,o,t.letterSpacing)).forEach((t,n)=>{i.push(t),r.push({indent:e,marker:0===n?l.marker:null})})}return{L:i,M:r}};let g=t.fontSize,p=[],u=[];for(;;){const e=f(g);p=e.L,u=e.M;const n=Math.max(0,...p.map((e,n)=>u[n].indent+E(e,g,t.letterSpacing))),o=p.length*g*t.lineHeight;if(n<=t.width&&(!t.height||o<=t.height)){break}if(g-=1,g<4){break}}p=F(p,g/t.fontSize);const w=g*t.lineHeight,$=p.length*w;let v=0;"middle"===t.verticalAlign?v=(t.height-$)/2:"bottom"===t.verticalAlign&&(v=t.height-$);const O=g+v,H={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:g},z=t=>{let e=t.length;for(;e>0&&""===t[e-1].text.trim();){e--}return t.slice(0,e)},T=l(),L=t.fontWeight||"normal",C=t.fontStyle||"normal";T.font=`${C} ${L} ${g}px ${t.fontFamily}`;const A=T.measureText(" ").width,B=u.map((e,n)=>{var o,i,r,l,a;if(!e.marker){return null}const h=O+n*w;let c;if(e.marker.isOrdered){const n=s(e.marker.text,g,t.fontFamily,L,C,t.letterSpacing);c=y(e.indent,h,{markerWidth:n,spaceWidth:A})}else{const t=T.measureText(e.marker.text);c=m(e.indent,h,{ascent:null!==(i=null!==(o=t.fontBoundingBoxAscent)&&void 0!==o?o:t.actualBoundingBoxAscent)&&void 0!==i?i:.8*g,inkRight:null!==(r=t.actualBoundingBoxRight)&&void 0!==r?r:0,inkAscent:null!==(l=t.actualBoundingBoxAscent)&&void 0!==l?l:0,inkDescent:null!==(a=t.actualBoundingBoxDescent)&&void 0!==a?a:0})}return k("tspan",{x:c.x,y:c.y,"letter-spacing":e.marker.isOrdered?t.letterSpacing*g+"px":void 0,innerHTML:d(e.marker.text)})}),R=t=>{const e=[];return p.forEach((n,o)=>{const i=z(n);i.length>0&&e.push(k("tspan",{x:u[o].indent,y:O+o*w,innerHTML:c(i,H,{omitColors:t})})),B[o]&&e.push(B[o])}),e};let P=null;if(t.backgroundEnabled){const e=t.backgroundPadding*(g*t.lineHeight*.5),n=t.backgroundCornerRadius*(g*t.lineHeight*.5);if(t.legacyBackground){P=k("rect",{x:-e,y:-e,width:t.width+2*e,height:t.height+2*e,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:n,ry:n})}else{const o=p.map((e,n)=>{const o=e.length?E(e,g,t.letterSpacing):0,i=n*w;return{left:u[n].indent,right:u[n].indent+o,top:i,bottom:i+w}}).filter(t=>t.right>t.left),i=x({rects:o,padding:e,cornerRadius:n});i&&(P=k("path",{d:i,fill:t.backgroundColor,opacity:t.backgroundOpacity,transform:v?`translate(0,${v})`:void 0}))}}const D=[];if(o){const e=b(t.fill,`text-fill-grad-${t.id}`);e&&D.push(e)}if(i&&t.strokeWidth){const e=b(t.stroke,`text-stroke-grad-${t.id}`);e&&D.push(e)}const N=t.strokeWidth&&(i||o&&!i),U={"font-size":g+"px","text-anchor":"start","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*g+"px"};if(N){const e=R(!0),n=i?`url(#text-stroke-grad-${t.id})`:t.stroke,r=k("text",Object.assign(Object.assign({},U),{fill:n,"stroke-width":t.strokeWidth,stroke:n}),...e.map(t=>k("tspan",t.props,t.props.innerHTML))),l=o?`url(#text-fill-grad-${t.id})`:t.fill,s=o?e:R(!1),a=k("text",Object.assign(Object.assign({},U),{fill:l}),...s.map(t=>k("tspan",t.props,t.props.innerHTML)));return k("g",{},P,D.length>0?k("defs",{},...D):null,r,a)}return k("g",{},P,D.length>0?k("defs",{},...D):null,k("text",Object.assign(Object.assign({},U),{fill:o?`url(#text-fill-grad-${t.id})`:t.fill,"stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?t.stroke:void 0,"paint-order":t.strokeWidth?"stroke fill":void 0}),...R(!1)))}let T=t.fontSize;const L=W(O);let C=[];for(;;){C=M(L,t.width,T,t.letterSpacing);const e=Math.max(...C.map(e=>E(e,T,t.letterSpacing)),0),n=C.length*T*t.lineHeight;if(e<=t.width&&n<=t.height){break}if(T-=1,T<4){break}}C=F(C,T/t.fontSize);const A=T*t.lineHeight,B=C.length*A;let R=T;"middle"===t.verticalAlign?R=(t.height-B)/2+T:"bottom"===t.verticalAlign&&(R=t.height-B+T);const P="center"===t.align?"middle":"right"===t.align?"end":"start",D={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:T},N="center"===t.align?t.width/2:"right"===t.align?t.width:0,U=t=>{let e=t.length;for(;e>0&&""===t[e-1].text.trim();){e--}return t.slice(0,e)},G=C.map((t,e)=>{const n=U(t),o=0===n.length?"":c(n,D);return k("tspan",{x:N,dy:0===e?0:A,innerHTML:o})}),I=t.backgroundPadding*(T*t.lineHeight*.5),X=t.backgroundCornerRadius*(T*t.lineHeight*.5);let Y=null;if(t.backgroundEnabled){if(t.legacyBackground){Y=k("rect",{x:-I,y:-I,width:t.width+2*I,height:t.height+2*I,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:X,ry:X})}else{const e=w({lines:C.map(e=>({width:0===e.length?0:E(e,T,t.letterSpacing)})),lineHeight:A,width:t.width,align:"justify"===t.align?"justify":t.align});let n=0;"middle"===t.verticalAlign?n=(t.height-C.length*A)/2:"bottom"===t.verticalAlign&&(n=t.height-C.length*A);const o=x({rects:e,padding:I,cornerRadius:X});o&&(Y=k("path",{d:o,fill:t.backgroundColor,opacity:t.backgroundOpacity,transform:n?`translate(0,${n})`:void 0}))}}const q=[],V=t.strokeWidth&&(i||o&&!i);if(o){const e=`text-fill-grad-${t.id}`,n=b(t.fill,e);n&&q.push(n)}if(i&&t.strokeWidth){const e=`text-stroke-grad-${t.id}`,n=b(t.stroke,e);n&&q.push(n)}if(V){const e=C.map((t,e)=>{const n=U(t),o=c(n,D,{omitColors:!0});return k("tspan",{x:N,dy:0===e?0:A,innerHTML:o})}),n={y:R,"font-size":T+"px","text-anchor":P,"font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*T+"px"},r=i?`url(#text-stroke-grad-${t.id})`:t.stroke,l=k("text",Object.assign(Object.assign({},n),{fill:r,"stroke-width":t.strokeWidth,stroke:r}),...e.map(t=>k("tspan",t.props,t.props.innerHTML))),s=o?`url(#text-fill-grad-${t.id})`:t.fill,a=o?e:G,h=k("text",Object.assign(Object.assign({},n),{fill:s}),...a.map(t=>k("tspan",t.props,t.props.innerHTML)));return k("g",{},Y,q.length>0?k("defs",{},...q):null,l,h)}return k("g",{},Y,q.length>0?k("defs",{},...q):null,k("text",{fill:o?`url(#text-fill-grad-${t.id})`:t.fill,y:R,"font-size":T+"px","text-anchor":P,"font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*T+"px","stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?t.stroke:void 0,"paint-order":t.strokeWidth?"stroke fill":void 0},...G))},line:async({element:t,page:e,store:n})=>k("g",{},k("line",{x1:0,y1:t.height/2,x2:t.width,y2:t.height/2,stroke:t.color,"stroke-width":t.height,"stroke-dasharray":t.dash&&t.dash.length?t.dash.map(e=>e*t.height).join(" "):void 0}),k("g",{transform:`translate(0 ${t.height/2})`},S({element:t,type:t.startHead})),k("g",{transform:`translate(${t.width} ${t.height/2}) rotate(180)`},S({element:t,type:t.endHead}))),figure:async({element:t,page:e,store:n,elementHook:o})=>{let i=function(t){let e=t.replace(/<svg[^>]*>/,"");return e=e.replace(/<\/svg>/,""),e}(r(t));const l=[];if(t.strokeWidth&&g.isGradient(t.stroke)){const e=`figure-stroke-grad-${t.id}`,n=b(t.stroke,e);if(n){l.push(n);const o=t.stroke.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i=i.replace(new RegExp(`stroke="${o}"`,"g"),`stroke="url(#${e})"`)}}if(g.isGradient(t.fill)){const e=`figure-fill-grad-${t.id}`,n=b(t.fill,e);if(n){l.push(n);const o=t.fill.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i=i.replace(new RegExp(`fill="${o}"`,"g"),`fill="url(#${e})"`)}}if(l.length>0){const e=k("g",{},k("defs",{},...l),k("g",{innerHTML:i}));return o&&o({dom:e,element:t})||e}const s=k("g",{innerHTML:i});return o&&o({dom:s,element:t})||s},group:async({element:t,page:e,store:n,elementHook:o})=>{const i=await Promise.all(t.children.map(t=>j({element:t,page:e,store:n,elementHook:o}))),r=k("g",{style:{"transform-origin":"top left"}},...i);return o&&o({dom:r,element:t})||r},gif:v,table:async({element:t})=>{t.rows;const e=t.cols,n=t.colWidths,o=t.rowHeights,i=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],r=(t.cells||[]).map((n,o)=>{const r=Object.assign(Object.assign({},n),{row:Math.floor(o/e),col:o%e});for(const e of i){void 0===r[e]&&(r[e]=t[e])}return r}),l=[],s=(e,i,r,l)=>{let s=0;for(let o=0;o<i;o++){s+=n[o]*t.width}let a=0;for(let n=0;n<e;n++){a+=o[n]*t.height}let h=0;for(let o=i;o<i+l;o++){h+=(n[o]||0)*t.width}let c=0;for(let n=e;n<e+r;n++){c+=(o[n]||0)*t.height}return{x:s,y:a,width:h,height:c}};for(const a of r){if(!a.mergedInto&&a.cellBackground&&"transparent"!==a.cellBackground){s(a.row,a.col,a.colSpan||1,a.colSpan||1);const{x:t,y:e,width:n,height:o}=s(a.row,a.col,a.rowSpan||1,a.colSpan||1);l.push(k("rect",{x:t,y:e,width:n,height:o,fill:a.cellBackground}))}}const h=(t,e)=>"dashed"===t?`${4*e},${2*e}`:"dotted"===t?`${e},${e}`:void 0,c=(e,n)=>{var o,i,r,l,s;const a=null===(o=e.borders)||void 0===o?void 0:o[n];return{width:null!==(i=null==a?void 0:a.width)&&void 0!==i?i:t.borderWidth,style:null!==(l=null!==(r=null==a?void 0:a.style)&&void 0!==r?r:t.borderStyle)&&void 0!==l?l:"solid",color:null!==(s=null==a?void 0:a.color)&&void 0!==s?s:t.borderColor}};for(const a of r){if(a.mergedInto){continue}const t=s(a.row,a.col,a.rowSpan||1,a.colSpan||1);if(0===a.row){const e=c(a,"top");"none"!==e.style&&e.width>0&&l.push(k("line",{x1:t.x,y1:t.y+e.width/2,x2:t.x+t.width,y2:t.y+e.width/2,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":h(e.style,e.width)}))}if(0===a.col){const e=c(a,"left");"none"!==e.style&&e.width>0&&l.push(k("line",{x1:t.x+e.width/2,y1:t.y,x2:t.x+e.width/2,y2:t.y+t.height,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":h(e.style,e.width)}))}{const e=c(a,"bottom");"none"!==e.style&&e.width>0&&l.push(k("line",{x1:t.x,y1:t.y+t.height-e.width/2,x2:t.x+t.width,y2:t.y+t.height-e.width/2,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":h(e.style,e.width)}))}{const e=c(a,"right");"none"!==e.style&&e.width>0&&l.push(k("line",{x1:t.x+t.width-e.width/2,y1:t.y,x2:t.x+t.width-e.width/2,y2:t.y+t.height,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":h(e.style,e.width)}))}}for(const f of r){if(f.mergedInto){continue}let e=a(f.text||"");if(!e){continue}"uppercase"===f.textTransform&&(e=e.toUpperCase());const i=f.cellPadding||4;let r=0;for(let o=0;o<f.col;o++){r+=n[o]*t.width}let s=0;for(let n=0;n<f.row;n++){s+=o[n]*t.height}const h=n[f.col]*t.width,c=o[f.row]*t.height,g=f.fontSize||12,p=f.align||"left";let u=r+i,m="start";"center"===p?(u=r+h/2,m="middle"):"right"===p&&(u=r+h-i,m="end");let y=s+i+g;const x=f.verticalAlign||"top";"middle"===x?y=s+c/2+g/3:"bottom"===x&&(y=s+c-i),l.push(k("text",{x:u,y,"font-size":g,"font-family":f.fontFamily||"Roboto","font-weight":f.fontWeight||"normal","font-style":f.fontStyle||"normal",fill:f.fill||"black","text-anchor":m,"text-decoration":f.textDecoration||"none","letter-spacing":f.letterSpacing?f.letterSpacing*g+"px":void 0},d(e)))}return k("g",{},...l)}};async function j({element:t,page:e,store:n,elementHook:o}){var i;let r=await O[t.type];r||(r=()=>k("g",{}),console.error(`SVG export does not support ${t.type} type...`));const a=await r({element:t,page:e,store:n}),h=[],c=[];if(t.blurEnabled&&h.push(`blur(${t.blurRadius/2}px)`),t.brightnessEnabled&&h.push(`brightness(${100*t.brightness+100}%)`),t.sepiaEnabled&&h.push("sepia()"),t.grayscaleEnabled&&h.push("grayscale()"),t.shadowEnabled&&h.push(`drop-shadow(${t.shadowOffsetX}px ${t.shadowOffsetY}px ${t.shadowBlur}px ${t.shadowColor})`),t.filters){for(const[f,g]of Object.entries(t.filters)){const t=s(l[f],g.intensity);if(t&&(h.push(t.filter),t.html)){const e=t.html.replace(/<svg([^>]*)>/,"<g$1>").replace(/<\/svg>/,"</g>");c.push(e)}}}const d=k("g",{className:"element",id:t.id,transform:"group"!==t.type?`translate(${t.x}, ${t.y}) rotate(${t.rotation})`:void 0,display:null===(i=t.visible)||void 0===i||i?void 0:"none",opacity:t.opacity,style:{"transform-origin":"top left",filter:h.join(" ")}},a,...c);return o&&o({dom:d,element:t})||d}async function H(t){try{const e=await fetch(t),n=e.headers.get("content-type")||"font/ttf",o=await e.arrayBuffer();return`data:${n};base64,${"undefined"!=typeof Buffer?Buffer.from(o).toString("base64"):function(t){const e=new Uint8Array(t);let n="";for(let o=0;o<e.length;o+=32768){const t=e.subarray(o,o+32768);n+=String.fromCharCode(...t)}if("undefined"!=typeof btoa){return btoa(n)}if("undefined"!=typeof Buffer){return Buffer.from(e).toString("base64")}throw new Error("No base64 encoder available in this environment")}(o)}`}catch(e){return console.error("Error embedding font:",e),t}}export async function jsonToDOM({json:t,elementHook:i,fontEmbedding:r="inline"}){const l=[];forEveryNode({children:t.pages},t=>{if(("text"===t.type||"tablecell"===t.type||"table"===t.type)&&(t.fontFamily&&-1===l.indexOf(t.fontFamily)&&l.push(t.fontFamily),t.text)){for(const e of u(t.text)){-1===l.indexOf(e)&&l.push(e)}}});const s="inline"===r?await async function(t,e){return await Promise.all(t.map(async t=>{var n,o;if("Arial"===t){return null}const i=e.find(e=>e.fontFamily===t);if(i){const e=i.styles||(i.url?[{src:`url("${i.url}")`,fontStyle:"normal",fontWeight:"normal"}]:[]),n=await Promise.all(e.map(async e=>{var n,o;const r=(null===(o=null===(n=e.src)||void 0===n?void 0:n.match(/url\("?(.*?)"?\)/))||void 0===o?void 0:o[1])||i.url,l=await H(r);return`@font-face {\n font-family: '${t}';\n font-style: ${e.fontStyle||"normal"};\n font-weight: ${e.fontWeight||"normal"};\n src: url(${l});\n}`}));return k("style",{},n.join("\n"))}{const e=`https://fonts.googleapis.com/css?family=${encodeURIComponent(t)}:bi,normal,i,b`;try{const i=await fetch(e),r=await i.text(),l=null===(o=null===(n=r.match(/url\((.*?)\)/g))||void 0===n?void 0:n.map(t=>t.replace(/url\((.*?)\)/,"$1")))||void 0===o?void 0:o.filter(t=>t.startsWith("https"));if(!(null==l?void 0:l.length)){throw new Error("No font URLs found")}const s=await Promise.all(l.map(async e=>{const n=await H(e),o=(r.match(/@font-face\s*\{[^}]*?\}/g)||[]).find(t=>t.includes(e))||"",i=o.match(/font-style:\s*(.*?)[;\s}]/),l=o.match(/font-weight:\s*(.*?)[;\s}]/),s=i?i[1].trim():"normal",a=l?l[1].trim():"normal";return`@font-face {\n font-family: '${t}';\n font-style: ${s};\n font-weight: ${a};\n src: url(${n});\n}`}));return k("style",{},s.join("\n"))}catch(r){return console.error("Error embedding Google Font:",r),k("defs",{},k("style",{type:"text/css",innerHTML:`@import url('${e}');`.replace(/&/g,"&")}))}}}))}(l,t.fonts):[],a=await Promise.all(t.pages.map(r=>async function({page:t,store:i,elementHook:r}){const l=[...t.children.filter(t=>!t.alwaysOnTop),...t.children.filter(t=>t.alwaysOnTop)],s=await Promise.all(l.map(e=>j({element:e,page:t,store:i,elementHook:r}))),a=t.background.indexOf("url")>=0||t.background.indexOf("http")>=0||t.background.indexOf(".jpg")>=0||t.background.indexOf(".png")>=0||t.background.indexOf(".jpeg")>=0;let h;if(a){const r=await o(t.background);h=await e(t.background,Object.assign({width:i.width,height:i.height,x:0,y:0},n({width:i.width,height:i.height},{width:r.width,height:r.height})))}return k("g",{className:"page",style:{}},a?k("image",{"xlink:href":h,x:0,y:0,width:i.width,height:i.height,preserveAspectRatio:"none"}):k("rect",{x:0,y:0,width:i.width,height:i.height,fill:a?void 0:t.background}),...s)}({page:r,store:t,elementHook:i})));return k("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:`0 0 ${t.width} ${t.height}`,width:t.width,height:t.height},...s,...a)}function z(t){return String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}const W=({dom:e,nestLevel:n=0})=>{if("string"==typeof e){return e}if(!e){return""}const o=e.props,{innerHTML:i}=o,r=t(o,["innerHTML"]),l=Object.keys(r).map(t=>((t,e)=>"object"==typeof e?`${t}="${Object.keys(e).map(t=>`${t}:${e[t]};`).join(" ")}"`:null==e||""===e?"":`${t}="${z(String(e))}"`)(t,r[t])).filter(t=>t&&t.trim().length>0).join(" "),s=" ".repeat(n);return`${s}<${e.type}${l?" "+l:""}>${i||"\n"+e.children.map(t=>W({dom:t,nestLevel:n+1})).join("")}${s}</${e.type}>\n`};export async function jsonToSVG({json:t,elementHook:e,fontEmbedding:n="inline"}){const o=await jsonToDOM({json:t,elementHook:e,fontEmbedding:n});return W({dom:o})}
|
|
1
|
+
var t=this&&this.__rest||function(t,e){var n={};for(var o in t){Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(n[o]=t[o])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(t);i<o.length;i++){e.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(t,o[i])&&(n[o[i]]=t[o[i]])}}return n};import{cropImage as e,getCrop as n,loadImage as o}from"./image.js";import*as i from"./svg.js";import{figureToSvg as r}from"./figure-to-svg.js";import{Effects as l,shapeFilterToCSS as s}from"./filters.js";import{getElementBlurRadius as a}from"../canvas/apply-filters.js";import{removeTags as h,parseHtmlToSegments as c}from"./text.js";import{segmentsToTspans as d,normalizeStrokeLineJoin as f}from"./text-html.js";import{xmlEscape as g}from"./xml.js";import{getCurvePath as p}from"../canvas/text-element.js";import*as u from"./gradient.js";import{normalizeRichTextHtml as m,extractFontFamiliesFromHtml as y}from"./rich-text-html.js";import{bulletMarkerPosition as x,numberMarkerPosition as k}from"./list-marker-geometry.js";import{generateBackgroundShapeFromRects as w,textLinesToRects as b}from"./background-shape.js";export const forEveryNode=(t,e)=>{if(t.children){for(const n of t.children){if(!0===e(n)){break}forEveryNode(n,e)}}if(t.cells){for(const n of t.cells){if(!0===e(n)){break}}}};const $=(t,e,...n)=>({type:t,props:e,children:n||[]});function v(t,e){if(!u.isGradient(t)){return null}const{stops:n,rotation:o}=u.parseColor(t),i=o*Math.PI/180,r=.5-.5*Math.sin(i),l=.5+.5*Math.cos(i),s=.5+.5*Math.sin(i),a=.5-.5*Math.cos(i),h=n.map(({offset:t,color:e})=>$("stop",{offset:100*t+"%","stop-color":e}));return $("linearGradient",{id:e,x1:100*r+"%",y1:100*l+"%",x2:100*s+"%",y2:100*a+"%"},...h)}export function fixRatio(t){var e=(new DOMParser).parseFromString(t,"image/svg+xml");return e.documentElement.setAttribute("preserveAspectRatio","none"),(new XMLSerializer).serializeToString(e)}const S=async t=>{try{const e=await fetch(t);if("undefined"!=typeof Buffer){const t=await e.arrayBuffer(),n=Buffer.from(t).toString("base64");return`data:${e.headers.get("content-type")||"image/png"};base64,${n}`}{const t=await e.blob();return new Promise((e,n)=>{const o=new FileReader;o.onloadend=()=>e(o.result),o.onerror=n,o.readAsDataURL(t)})}}catch(e){return console.error("Error converting URL to data URL:",e),t}},j=async({element:t,page:e,store:n})=>{let{src:r}=t;if("svg"===t.type){const e=await i.urlToString(r);r=i.replaceColors(e,new Map(Object.entries(t.colorsReplace)))}else{r=await S(r)}let l,s,a,h,c="";if(t.flipX||t.flipY){const e=t.flipX?-1:1,n=t.flipY?-1:1,o=t.width/2,i=t.height/2;c=`translate(${o}, ${i}) scale(${e}, ${n}) translate(${-o}, ${-i})`}t.clipSrc&&(l=`clip-img-mask-${t.id}`,s=await S(t.clipSrc)),t.maskSrc&&(a=`mask-img-${t.id}`,h=await S(t.maskSrc));const d=await o(r),f=d.width*t.cropWidth,g=d.height*t.cropHeight,p=t.width/t.height;let m,y;const x=f/g,k="boolean"==typeof t.stretchEnabled&&t.stretchEnabled||"svg"===t.type;k?(m=f,y=g):p>=x?(m=f,y=f/p):(m=g*p,y=g);const w=m/d.width,b=y/d.height,j=m/y>t.width/t.height?t.height/y:t.width/m,O=k?t.width/m:j,H=k?t.height/y:j,W=m*O/w,z=y*H/b;let M=t.cropX*d.width*O,L=t.cropY*d.height*H;t.flipX&&(M=(1-t.cropX-t.cropWidth)*d.width*O),t.flipY&&(L=(1-t.cropY-t.cropHeight)*d.height*H);const E=`clip-${t.id}`,F=t.cornerRadius||0,T=r.replace(/&/g,"&"),C={x:-M,y:-L,width:W,height:z,preserveAspectRatio:"none","clip-path":`url(#${E})`},A=[$("clipPath",{id:E},$("rect",{x:0,y:0,width:t.width,height:t.height,rx:F||void 0,ry:F||void 0}))];l&&s&&A.push($("mask",{id:l,maskUnits:"userSpaceOnUse","mask-type":"alpha"},$("image",{href:s.replace(/&/g,"&"),x:0,y:0,width:t.width,height:t.height,preserveAspectRatio:"none"}))),a&&A.push($("mask",{id:a,maskUnits:"userSpaceOnUse","mask-type":"alpha"},$("image",Object.assign({href:T},C))));let B=T;const R={};a&&h&&(B=h.replace(/&/g,"&"),R.mask=`url(#${a})`);const P={};l&&(P.mask=`url(#${l})`);const D=t.borderSize||0,N=D>0&&u.isGradient(t.borderColor),U=N?`border-grad-${t.id}`:null;if(N){const e=v(t.borderColor,U);e&&A.push(e)}const G=D>0?$("rect",{x:D/2,y:D/2,width:Math.max(0,t.width-D),height:Math.max(0,t.height-D),fill:"none",stroke:N?`url(#${U})`:t.borderColor,"stroke-width":D,rx:Math.max(0,F-D)||void 0,ry:Math.max(0,F-D)||void 0}):null,I=$("g",{},$("defs",{},...A),$("image",Object.assign(Object.assign({href:B},C),R)),G);return $("g",P,c?$("g",{transform:c},I):I)},O=({element:t,type:e})=>{const n={"stroke-width":t.height,stroke:t.color,"stroke-linecap":"round","stroke-linejoin":"round"},o=Object.assign(Object.assign({},n),{fill:t.color}),i=Object.assign(Object.assign({},n),{fill:"none"});return"arrow"===e?$("polyline",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},i)):"triangle"===e?$("polygon",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},o)):"bar"===e?$("polyline",Object.assign({points:`0,${2*-t.height} 0,${2*t.height}`},i)):"circle"===e?$("circle",Object.assign({cx:2*t.height,cy:0,r:2*t.height},o)):"square"===e?$("polygon",Object.assign({points:`0,${2*-t.height} ${4*t.height},${2*-t.height} ${4*t.height},${2*t.height} 0,${2*t.height}`},o)):null},H={image:j,svg:j,text:async({element:t,page:e,store:n})=>{const o=u.isGradient(t.fill),i=u.isGradient(t.stroke);if(t.curveEnabled){const e=m(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}),n=c(e,{fontSize:t.fontSize,fontFamily:t.fontFamily}),r=Math.max(t.fontSize,...n.map(e=>{var n;return null!==(n=e.fontSize)&&void 0!==n?n:t.fontSize})),l=p(t.width,t.height,t.curvePower,r),s=M(t.id||"temp"),a=`curve-path-${s}`,h={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:t.fontSize},g=d(n,h),u=d(n,h,{omitColors:!0}),y=t.backgroundPadding*(t.fontSize*t.lineHeight*.5),x=t.backgroundEnabled?$("rect",{x:-y,y:-y,width:t.width+2*y,height:t.height+2*y,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5),ry:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)}):null,k=[$("path",{id:a,d:l,fill:"none"})],w=t.strokeWidth&&(i||o&&!i);if(o){const e=`curve-fill-grad-${s}`,n=v(t.fill,e);n&&k.push(n)}if(i&&t.strokeWidth){const e=`curve-stroke-grad-${s}`,n=v(t.stroke,e);n&&k.push(n)}if(w){const e={"font-size":t.fontSize+"px","text-anchor":"middle","dominant-baseline":"central","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration||void 0,"letter-spacing":t.letterSpacing*r},n=i?`url(#curve-stroke-grad-${s})`:t.stroke,l=$("text",Object.assign(Object.assign({},e),{fill:n,"stroke-width":t.strokeWidth,stroke:n,"stroke-linejoin":f(t.strokeLineJoin)}),$("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:u})),h=o?`url(#curve-fill-grad-${s})`:t.fill,c=$("text",Object.assign(Object.assign({},e),{fill:h}),$("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:g}));return $("g",{},x,$("defs",{},...k),l,c)}return $("g",{},x,$("defs",{},...k),$("text",{fill:o?`url(#curve-fill-grad-${s})`:t.fill,"font-size":t.fontSize+"px","text-anchor":"middle","dominant-baseline":"central","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration||void 0,"letter-spacing":t.letterSpacing*r,"stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?i?`url(#curve-stroke-grad-${s})`:t.stroke:void 0,"stroke-linejoin":t.strokeWidth?f(t.strokeLineJoin):void 0,"paint-order":t.strokeWidth?"stroke fill":void 0},$("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:g})))}let r=null;const l=()=>(r||(r=document.createElement("canvas").getContext("2d")),r),s=(t,e,n,o,i,r=0)=>{const s=l();return s.font=`${i} ${o} ${e}px ${n}`,s.measureText(t).width+Math.max(0,(t?t.length:0)-1)*r*e},a=(e,n,o)=>{let i=n;null!=e.fontSize&&e.fontSize!==t.fontSize&&t.fontSize>0&&(i=e.fontSize*(n/t.fontSize));const r=e.fontFamily||t.fontFamily,l=e.bold?"bold":t.fontWeight||"normal",a=e.italic?"italic":t.fontStyle||"normal";return s(e.text,i,r,l,a,o)},h=/<[a-z][\s\S]*>/i.test(t.text);let y=t.text;!h&&y.includes("\n")&&(y=y.split("\n").map(t=>`<p>${t}</p>`).join(""));const S=m(y,{fontSize:t.fontSize,fontFamily:t.fontFamily}),j={fontSize:t.fontSize,fontFamily:t.fontFamily},O=[],H=(new DOMParser).parseFromString(S,"text/html"),W=H.body.querySelectorAll("p");W.length>0?W.forEach((t,e)=>{const n=t.innerHTML,o=c(n,j);O.push(...o),e<W.length-1&&O.push({text:"\n"})}):O.push(...c(S,j)),"uppercase"===t.textTransform&&O.forEach(t=>{"\n"!==t.text&&(t.text=t.text.toUpperCase())});const z=t=>{const e=[];let n=[];for(const o of t){if("\n"===o.text){n.length>0&&(e.push(n),n=[]),e.push([Object.assign(Object.assign({},o),{text:"\n"})]);continue}const t=o.text.split(/( )/);for(const i of t){""!==i&&(" "===i?(n.length>0&&(e.push(n),n=[]),e.push([Object.assign(Object.assign({},o),{text:" "})])):n.push(Object.assign(Object.assign({},o),{text:i})))}}return n.length>0&&e.push(n),e},L=(t,e,n,o)=>{const i=[[]];let r=0;for(const l of t){if(1===l.length&&"\n"===l[0].text){i.push([]),r=0;continue}const t=l.reduce((t,e)=>t+a(e,n,o),0);1!==l.length||" "!==l[0].text?(r+t>e+.5&&i[i.length-1].length>0&&(i.push([]),r=0),i[i.length-1].push(...l),r+=t):r+t<=e+.5&&(i[i.length-1].push(...l),r+=t)}return i},E=(t,e,n)=>t.reduce((t,o)=>t+a(o,e,n),0),F=(t,e)=>1===e?t:t.map(t=>t.map(t=>t.fontSize?Object.assign(Object.assign({},t),{fontSize:Math.round(t.fontSize*e*1e3)/1e3}):t));if(H.body.querySelector("ul, ol")){const e=[],n=2.1,r=e=>{const n=e.cloneNode(!0);n.querySelectorAll("ul, ol").forEach(t=>t.remove());const o=c(n.innerHTML,j);return"uppercase"===t.textTransform&&o.forEach(t=>{"\n"!==t.text&&(t.text=t.text.toUpperCase())}),o},a=(t,n)=>{for(const o of Array.from(t.children)){const t=o.tagName.toLowerCase();if("ul"===t||"ol"===t){const i="ol"===t;let l=parseInt(o.getAttribute("start")||"1",10)||1;for(const t of Array.from(o.children)){if("li"!==t.tagName.toLowerCase()){continue}const o=t.getAttribute("value");o&&!Number.isNaN(parseInt(o,10))&&(l=parseInt(o,10));const s=i?{text:`${l}.`,isOrdered:!0}:{text:"•",isOrdered:!1};e.push({segments:r(t),depth:n+1,marker:s}),i&&(l+=1),a(t,n+1)}}else{"p"===t||"div"===t?e.push({segments:r(o),depth:0,marker:null}):e.push({segments:c(o.outerHTML,j),depth:0,marker:null})}}};a(H.body,0);const h=o=>{const i=[],r=[];for(const l of e){const e=l.depth*n*o,s=Math.max(1,t.width-e);(0===l.segments.length?[[]]:L(z(l.segments),s,o,t.letterSpacing)).forEach((t,n)=>{i.push(t),r.push({indent:e,marker:0===n?l.marker:null})})}return{L:i,M:r}};let p=t.fontSize,u=[],m=[];for(;;){const e=h(p);u=e.L,m=e.M;const n=Math.max(0,...u.map((e,n)=>m[n].indent+E(e,p,t.letterSpacing))),o=u.length*p*t.lineHeight;if(n<=t.width&&(!t.height||o<=t.height)){break}if(p-=1,p<4){break}}u=F(u,p/t.fontSize);const y=p*t.lineHeight,b=u.length*y;let S=0;"middle"===t.verticalAlign?S=(t.height-b)/2:"bottom"===t.verticalAlign&&(S=t.height-b);const O=p+S,W={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:p},M=t=>{let e=t.length;for(;e>0&&""===t[e-1].text.trim();){e--}return t.slice(0,e)},T=l(),C=t.fontWeight||"normal",A=t.fontStyle||"normal";T.font=`${A} ${C} ${p}px ${t.fontFamily}`;const B=T.measureText(" ").width,R=m.map((e,n)=>{var o,i,r,l,a;if(!e.marker){return null}const h=O+n*y;let c;if(e.marker.isOrdered){const n=s(e.marker.text,p,t.fontFamily,C,A,t.letterSpacing);c=k(e.indent,h,{markerWidth:n,spaceWidth:B})}else{const t=T.measureText(e.marker.text);c=x(e.indent,h,{ascent:null!==(i=null!==(o=t.fontBoundingBoxAscent)&&void 0!==o?o:t.actualBoundingBoxAscent)&&void 0!==i?i:.8*p,inkRight:null!==(r=t.actualBoundingBoxRight)&&void 0!==r?r:0,inkAscent:null!==(l=t.actualBoundingBoxAscent)&&void 0!==l?l:0,inkDescent:null!==(a=t.actualBoundingBoxDescent)&&void 0!==a?a:0})}return $("tspan",{x:c.x,y:c.y,"letter-spacing":e.marker.isOrdered?t.letterSpacing*p+"px":void 0,innerHTML:g(e.marker.text)})}),P=t=>{const e=[];return u.forEach((n,o)=>{const i=M(n);i.length>0&&e.push($("tspan",{x:m[o].indent,y:O+o*y,innerHTML:d(i,W,{omitColors:t})})),R[o]&&e.push(R[o])}),e};let D=null;if(t.backgroundEnabled){const e=t.backgroundPadding*(p*t.lineHeight*.5),n=t.backgroundCornerRadius*(p*t.lineHeight*.5);if(t.legacyBackground){D=$("rect",{x:-e,y:-e,width:t.width+2*e,height:t.height+2*e,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:n,ry:n})}else{const o=u.map((e,n)=>{const o=e.length?E(e,p,t.letterSpacing):0,i=n*y;return{left:m[n].indent,right:m[n].indent+o,top:i,bottom:i+y}}).filter(t=>t.right>t.left),i=w({rects:o,padding:e,cornerRadius:n});i&&(D=$("path",{d:i,fill:t.backgroundColor,opacity:t.backgroundOpacity,transform:S?`translate(0,${S})`:void 0}))}}const N=[];if(o){const e=v(t.fill,`text-fill-grad-${t.id}`);e&&N.push(e)}if(i&&t.strokeWidth){const e=v(t.stroke,`text-stroke-grad-${t.id}`);e&&N.push(e)}const U=t.strokeWidth&&(i||o&&!i),G={"font-size":p+"px","text-anchor":"start","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*p+"px"};if(U){const e=P(!0),n=i?`url(#text-stroke-grad-${t.id})`:t.stroke,r=$("text",Object.assign(Object.assign({},G),{fill:n,"stroke-width":t.strokeWidth,stroke:n,"stroke-linejoin":f(t.strokeLineJoin)}),...e.map(t=>$("tspan",t.props,t.props.innerHTML))),l=o?`url(#text-fill-grad-${t.id})`:t.fill,s=o?e:P(!1),a=$("text",Object.assign(Object.assign({},G),{fill:l}),...s.map(t=>$("tspan",t.props,t.props.innerHTML)));return $("g",{},D,N.length>0?$("defs",{},...N):null,r,a)}return $("g",{},D,N.length>0?$("defs",{},...N):null,$("text",Object.assign(Object.assign({},G),{fill:o?`url(#text-fill-grad-${t.id})`:t.fill,"stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?t.stroke:void 0,"stroke-linejoin":t.strokeWidth?f(t.strokeLineJoin):void 0,"paint-order":t.strokeWidth?"stroke fill":void 0}),...P(!1)))}let T=t.fontSize;const C=z(O);let A=[];for(;;){A=L(C,t.width,T,t.letterSpacing);const e=Math.max(...A.map(e=>E(e,T,t.letterSpacing)),0),n=A.length*T*t.lineHeight;if(e<=t.width&&n<=t.height){break}if(T-=1,T<4){break}}A=F(A,T/t.fontSize);const B=T*t.lineHeight,R=A.length*B;let P=T;"middle"===t.verticalAlign?P=(t.height-R)/2+T:"bottom"===t.verticalAlign&&(P=t.height-R+T);const D="center"===t.align?"middle":"right"===t.align?"end":"start",N={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:T},U="center"===t.align?t.width/2:"right"===t.align?t.width:0,G=t=>{let e=t.length;for(;e>0&&""===t[e-1].text.trim();){e--}return t.slice(0,e)},I=A.map((t,e)=>{const n=G(t),o=0===n.length?"":d(n,N);return $("tspan",{x:U,dy:0===e?0:B,innerHTML:o})}),X=t.backgroundPadding*(T*t.lineHeight*.5),J=t.backgroundCornerRadius*(T*t.lineHeight*.5);let Y=null;if(t.backgroundEnabled){if(t.legacyBackground){Y=$("rect",{x:-X,y:-X,width:t.width+2*X,height:t.height+2*X,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:J,ry:J})}else{const e=b({lines:A.map(e=>({width:0===e.length?0:E(e,T,t.letterSpacing)})),lineHeight:B,width:t.width,align:"justify"===t.align?"justify":t.align});let n=0;"middle"===t.verticalAlign?n=(t.height-A.length*B)/2:"bottom"===t.verticalAlign&&(n=t.height-A.length*B);const o=w({rects:e,padding:X,cornerRadius:J});o&&(Y=$("path",{d:o,fill:t.backgroundColor,opacity:t.backgroundOpacity,transform:n?`translate(0,${n})`:void 0}))}}const q=[],V=t.strokeWidth&&(i||o&&!i);if(o){const e=`text-fill-grad-${t.id}`,n=v(t.fill,e);n&&q.push(n)}if(i&&t.strokeWidth){const e=`text-stroke-grad-${t.id}`,n=v(t.stroke,e);n&&q.push(n)}if(V){const e=A.map((t,e)=>{const n=G(t),o=d(n,N,{omitColors:!0});return $("tspan",{x:U,dy:0===e?0:B,innerHTML:o})}),n={y:P,"font-size":T+"px","text-anchor":D,"font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*T+"px"},r=i?`url(#text-stroke-grad-${t.id})`:t.stroke,l=$("text",Object.assign(Object.assign({},n),{fill:r,"stroke-width":t.strokeWidth,stroke:r,"stroke-linejoin":f(t.strokeLineJoin)}),...e.map(t=>$("tspan",t.props,t.props.innerHTML))),s=o?`url(#text-fill-grad-${t.id})`:t.fill,a=o?e:I,h=$("text",Object.assign(Object.assign({},n),{fill:s}),...a.map(t=>$("tspan",t.props,t.props.innerHTML)));return $("g",{},Y,q.length>0?$("defs",{},...q):null,l,h)}return $("g",{},Y,q.length>0?$("defs",{},...q):null,$("text",{fill:o?`url(#text-fill-grad-${t.id})`:t.fill,y:P,"font-size":T+"px","text-anchor":D,"font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*T+"px","stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?t.stroke:void 0,"stroke-linejoin":t.strokeWidth?f(t.strokeLineJoin):void 0,"paint-order":t.strokeWidth?"stroke fill":void 0},...I))},line:async({element:t,page:e,store:n})=>$("g",{},$("line",{x1:0,y1:t.height/2,x2:t.width,y2:t.height/2,stroke:t.color,"stroke-width":t.height,"stroke-dasharray":t.dash&&t.dash.length?t.dash.map(e=>e*t.height).join(" "):void 0}),$("g",{transform:`translate(0 ${t.height/2})`},O({element:t,type:t.startHead})),$("g",{transform:`translate(${t.width} ${t.height/2}) rotate(180)`},O({element:t,type:t.endHead}))),figure:async({element:t,page:e,store:n,elementHook:o})=>{let i=function(t){let e=t.replace(/<svg[^>]*>/,"");return e=e.replace(/<\/svg>/,""),e}(r(t));const l=[];if(t.strokeWidth&&u.isGradient(t.stroke)){const e=`figure-stroke-grad-${t.id}`,n=v(t.stroke,e);if(n){l.push(n);const o=t.stroke.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i=i.replace(new RegExp(`stroke="${o}"`,"g"),`stroke="url(#${e})"`)}}if(u.isGradient(t.fill)){const e=`figure-fill-grad-${t.id}`,n=v(t.fill,e);if(n){l.push(n);const o=t.fill.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i=i.replace(new RegExp(`fill="${o}"`,"g"),`fill="url(#${e})"`)}}if(l.length>0){const e=$("g",{},$("defs",{},...l),$("g",{innerHTML:i}));return o&&o({dom:e,element:t})||e}const s=$("g",{innerHTML:i});return o&&o({dom:s,element:t})||s},group:async({element:t,page:e,store:n,elementHook:o})=>{const i=await Promise.all(t.children.map(t=>W({element:t,page:e,store:n,elementHook:o}))),r=$("g",{style:{"transform-origin":"top left"}},...i);return o&&o({dom:r,element:t})||r},gif:j,table:async({element:t})=>{t.rows;const e=t.cols,n=t.colWidths,o=t.rowHeights,i=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],r=(t.cells||[]).map((n,o)=>{const r=Object.assign(Object.assign({},n),{row:Math.floor(o/e),col:o%e});for(const e of i){void 0===r[e]&&(r[e]=t[e])}return r}),l=[],s=(e,i,r,l)=>{let s=0;for(let o=0;o<i;o++){s+=n[o]*t.width}let a=0;for(let n=0;n<e;n++){a+=o[n]*t.height}let h=0;for(let o=i;o<i+l;o++){h+=(n[o]||0)*t.width}let c=0;for(let n=e;n<e+r;n++){c+=(o[n]||0)*t.height}return{x:s,y:a,width:h,height:c}};for(const h of r){if(!h.mergedInto&&h.cellBackground&&"transparent"!==h.cellBackground){s(h.row,h.col,h.colSpan||1,h.colSpan||1);const{x:t,y:e,width:n,height:o}=s(h.row,h.col,h.rowSpan||1,h.colSpan||1);l.push($("rect",{x:t,y:e,width:n,height:o,fill:h.cellBackground}))}}const a=(t,e)=>"dashed"===t?`${4*e},${2*e}`:"dotted"===t?`${e},${e}`:void 0,c=(e,n)=>{var o,i,r,l,s;const a=null===(o=e.borders)||void 0===o?void 0:o[n];return{width:null!==(i=null==a?void 0:a.width)&&void 0!==i?i:t.borderWidth,style:null!==(l=null!==(r=null==a?void 0:a.style)&&void 0!==r?r:t.borderStyle)&&void 0!==l?l:"solid",color:null!==(s=null==a?void 0:a.color)&&void 0!==s?s:t.borderColor}};for(const h of r){if(h.mergedInto){continue}const t=s(h.row,h.col,h.rowSpan||1,h.colSpan||1);if(0===h.row){const e=c(h,"top");"none"!==e.style&&e.width>0&&l.push($("line",{x1:t.x,y1:t.y+e.width/2,x2:t.x+t.width,y2:t.y+e.width/2,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":a(e.style,e.width)}))}if(0===h.col){const e=c(h,"left");"none"!==e.style&&e.width>0&&l.push($("line",{x1:t.x+e.width/2,y1:t.y,x2:t.x+e.width/2,y2:t.y+t.height,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":a(e.style,e.width)}))}{const e=c(h,"bottom");"none"!==e.style&&e.width>0&&l.push($("line",{x1:t.x,y1:t.y+t.height-e.width/2,x2:t.x+t.width,y2:t.y+t.height-e.width/2,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":a(e.style,e.width)}))}{const e=c(h,"right");"none"!==e.style&&e.width>0&&l.push($("line",{x1:t.x+t.width-e.width/2,y1:t.y,x2:t.x+t.width-e.width/2,y2:t.y+t.height,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":a(e.style,e.width)}))}}for(const d of r){if(d.mergedInto){continue}let e=h(d.text||"");if(!e){continue}"uppercase"===d.textTransform&&(e=e.toUpperCase());const i=d.cellPadding||4;let r=0;for(let o=0;o<d.col;o++){r+=n[o]*t.width}let s=0;for(let n=0;n<d.row;n++){s+=o[n]*t.height}const a=n[d.col]*t.width,c=o[d.row]*t.height,f=d.fontSize||12,p=d.align||"left";let u=r+i,m="start";"center"===p?(u=r+a/2,m="middle"):"right"===p&&(u=r+a-i,m="end");let y=s+i+f;const x=d.verticalAlign||"top";"middle"===x?y=s+c/2+f/3:"bottom"===x&&(y=s+c-i),l.push($("text",{x:u,y,"font-size":f,"font-family":d.fontFamily||"Roboto","font-weight":d.fontWeight||"normal","font-style":d.fontStyle||"normal",fill:d.fill||"black","text-anchor":m,"text-decoration":d.textDecoration||"none","letter-spacing":d.letterSpacing?d.letterSpacing*f+"px":void 0},g(e)))}return $("g",{},...l)}};async function W({element:t,page:e,store:n,elementHook:o}){var i;let r=await H[t.type];r||(r=()=>$("g",{}),console.error(`SVG export does not support ${t.type} type...`));const h=await r({element:t,page:e,store:n}),c=[],d=[];if(t.blurEnabled&&c.push(`blur(${a(t)/2}px)`),t.brightnessEnabled&&c.push(`brightness(${100*t.brightness+100}%)`),t.sepiaEnabled&&c.push("sepia()"),t.grayscaleEnabled&&c.push("grayscale()"),t.shadowEnabled&&c.push(`drop-shadow(${t.shadowOffsetX}px ${t.shadowOffsetY}px ${t.shadowBlur}px ${t.shadowColor})`),t.filters){for(const[a,g]of Object.entries(t.filters)){const t=s(l[a],g.intensity);if(t&&(c.push(t.filter),t.html)){const e=t.html.replace(/<svg([^>]*)>/,"<g$1>").replace(/<\/svg>/,"</g>");d.push(e)}}}const f=$("g",{className:"element",id:t.id,transform:"group"!==t.type?`translate(${t.x}, ${t.y}) rotate(${t.rotation})`:void 0,display:null===(i=t.visible)||void 0===i||i?void 0:"none",opacity:t.opacity,style:{"transform-origin":"top left",filter:c.join(" ")}},h,...d);return o&&o({dom:f,element:t})||f}async function z(t){try{const e=await fetch(t),n=e.headers.get("content-type")||"font/ttf",o=await e.arrayBuffer();return`data:${n};base64,${"undefined"!=typeof Buffer?Buffer.from(o).toString("base64"):function(t){const e=new Uint8Array(t);let n="";for(let o=0;o<e.length;o+=32768){const t=e.subarray(o,o+32768);n+=String.fromCharCode(...t)}if("undefined"!=typeof btoa){return btoa(n)}if("undefined"!=typeof Buffer){return Buffer.from(e).toString("base64")}throw new Error("No base64 encoder available in this environment")}(o)}`}catch(e){return console.error("Error embedding font:",e),t}}export async function jsonToDOM({json:t,elementHook:i,fontEmbedding:r="inline"}){const l=[];forEveryNode({children:t.pages},t=>{if(("text"===t.type||"tablecell"===t.type||"table"===t.type)&&(t.fontFamily&&-1===l.indexOf(t.fontFamily)&&l.push(t.fontFamily),t.text)){for(const e of y(t.text)){-1===l.indexOf(e)&&l.push(e)}}});const s="inline"===r?await async function(t,e){return await Promise.all(t.map(async t=>{var n,o;if("Arial"===t){return null}const i=e.find(e=>e.fontFamily===t);if(i){const e=i.styles||(i.url?[{src:`url("${i.url}")`,fontStyle:"normal",fontWeight:"normal"}]:[]),n=await Promise.all(e.map(async e=>{var n,o;const r=(null===(o=null===(n=e.src)||void 0===n?void 0:n.match(/url\("?(.*?)"?\)/))||void 0===o?void 0:o[1])||i.url,l=await z(r);return`@font-face {\n font-family: '${t}';\n font-style: ${e.fontStyle||"normal"};\n font-weight: ${e.fontWeight||"normal"};\n src: url(${l});\n}`}));return $("style",{},n.join("\n"))}{const e=`https://fonts.googleapis.com/css?family=${encodeURIComponent(t)}:bi,normal,i,b`;try{const i=await fetch(e),r=await i.text(),l=null===(o=null===(n=r.match(/url\((.*?)\)/g))||void 0===n?void 0:n.map(t=>t.replace(/url\((.*?)\)/,"$1")))||void 0===o?void 0:o.filter(t=>t.startsWith("https"));if(!(null==l?void 0:l.length)){throw new Error("No font URLs found")}const s=await Promise.all(l.map(async e=>{const n=await z(e),o=(r.match(/@font-face\s*\{[^}]*?\}/g)||[]).find(t=>t.includes(e))||"",i=o.match(/font-style:\s*(.*?)[;\s}]/),l=o.match(/font-weight:\s*(.*?)[;\s}]/),s=i?i[1].trim():"normal",a=l?l[1].trim():"normal";return`@font-face {\n font-family: '${t}';\n font-style: ${s};\n font-weight: ${a};\n src: url(${n});\n}`}));return $("style",{},s.join("\n"))}catch(r){return console.error("Error embedding Google Font:",r),$("defs",{},$("style",{type:"text/css",innerHTML:`@import url('${e}');`.replace(/&/g,"&")}))}}}))}(l,t.fonts):[],a=await Promise.all(t.pages.map(r=>async function({page:t,store:i,elementHook:r}){const l=[...t.children.filter(t=>!t.alwaysOnTop),...t.children.filter(t=>t.alwaysOnTop)],s=await Promise.all(l.map(e=>W({element:e,page:t,store:i,elementHook:r}))),a=t.background.indexOf("url")>=0||t.background.indexOf("http")>=0||t.background.indexOf(".jpg")>=0||t.background.indexOf(".png")>=0||t.background.indexOf(".jpeg")>=0;let h;if(a){const r=await o(t.background);h=await e(t.background,Object.assign({width:i.width,height:i.height,x:0,y:0},n({width:i.width,height:i.height},{width:r.width,height:r.height})))}return $("g",{className:"page",style:{}},a?$("image",{"xlink:href":h,x:0,y:0,width:i.width,height:i.height,preserveAspectRatio:"none"}):$("rect",{x:0,y:0,width:i.width,height:i.height,fill:a?void 0:t.background}),...s)}({page:r,store:t,elementHook:i})));return $("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:`0 0 ${t.width} ${t.height}`,width:t.width,height:t.height},...s,...a)}function M(t){return String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}const L=({dom:e,nestLevel:n=0})=>{if("string"==typeof e){return e}if(!e){return""}const o=e.props,{innerHTML:i}=o,r=t(o,["innerHTML"]),l=Object.keys(r).map(t=>((t,e)=>"object"==typeof e?`${t}="${Object.keys(e).map(t=>`${t}:${e[t]};`).join(" ")}"`:null==e||""===e?"":`${t}="${M(String(e))}"`)(t,r[t])).filter(t=>t&&t.trim().length>0).join(" "),s=" ".repeat(n);return`${s}<${e.type}${l?" "+l:""}>${i||"\n"+e.children.map(t=>L({dom:t,nestLevel:n+1})).join("")}${s}</${e.type}>\n`};export async function jsonToSVG({json:t,elementHook:e,fontEmbedding:n="inline"}){const o=await jsonToDOM({json:t,elementHook:e,fontEmbedding:n});return L({dom:o})}
|
package/utils/validate-key.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"mobx";import{getAPI as o}from"./api.js";import{setRemoveBackgroundEnabled as t}from"./flags.js";const n=e.observable({value:!1}),a=e.observable({value:"v1"});export const ___=()=>a.value;const i=e.observable({value:0});export const ____=()=>i.value;export const isCreditVisible=()=>n.value;const r=e.action(()=>{n.value=!0});let s="";export const getKey=()=>s||"";export const setKey=e=>{s=e||""};let l="undefined"!=typeof window?window.location.origin:"";const c="undefined"!=typeof navigator&&navigator.userAgent.indexOf("Headless")>-1,d="undefined"!=typeof navigator&&navigator.userAgent.indexOf("Electron")>-1;"file://"===l&&c&&(l="headless"),"file://"===l&&d&&(l="electron");const p=`%cPolotno error! Current domain is not allowed. It may lead to unexpected behavior and stop working. Please add "${l}" here: https://polotno.com/cabinet`;let u=fetch;export const __=e=>{u=e};export async function isKeyPaid(n){for(let s=0;s<5;s++){try{const r=await u(o()+"/validate-key",{method:"POST",body:JSON.stringify({key:n,site:location.host,skdVersion:"4.
|
|
1
|
+
import*as e from"mobx";import{getAPI as o}from"./api.js";import{setRemoveBackgroundEnabled as t}from"./flags.js";const n=e.observable({value:!1}),a=e.observable({value:"v1"});export const ___=()=>a.value;const i=e.observable({value:0});export const ____=()=>i.value;export const isCreditVisible=()=>n.value;const r=e.action(()=>{n.value=!0});let s="";export const getKey=()=>s||"";export const setKey=e=>{s=e||""};let l="undefined"!=typeof window?window.location.origin:"";const c="undefined"!=typeof navigator&&navigator.userAgent.indexOf("Headless")>-1,d="undefined"!=typeof navigator&&navigator.userAgent.indexOf("Electron")>-1;"file://"===l&&c&&(l="headless"),"file://"===l&&d&&(l="electron");const p=`%cPolotno error! Current domain is not allowed. It may lead to unexpected behavior and stop working. Please add "${l}" here: https://polotno.com/cabinet`;let u=fetch;export const __=e=>{u=e};export async function isKeyPaid(n){for(let s=0;s<5;s++){try{const r=await u(o()+"/validate-key",{method:"POST",body:JSON.stringify({key:n,site:location.host,skdVersion:"4.3.0"})});if(e.runInAction(()=>{a.value=r.headers.get("x-api-version")||""}),!n){return console.error("Polotno API is initialized without API key. It may lead to unexpected behavior and stop working. Please create API key here: https://polotno.com/cabinet"),e.runInAction(()=>{i.value=1}),!1}if(200!==r.status){await new Promise(e=>setTimeout(e,3e3));continue}const s=await r.json();return s.is_valid||(console.error("Polotno API key is not valid. Please get new API key here: https://polotno.com/cabinet"),e.runInAction(()=>{i.value=1})),s.is_paid||(console.log("%cPolotno Free Version. For development usage only. https://polotno.com/","background: rgb(0, 161, 255); color: white; padding: 5px; margin: 5px;"),e.runInAction(()=>{0===i.value&&(i.value=2)})),s.is_domain_valid||console.log(p,"background: rgba(247, 101, 68, 1); color: white; padding: 5px; margin: 5px;"),t(s.remove_background_enabled),s.is_paid||!1}catch(r){await new Promise(e=>setTimeout(e,3e3))}}return console.error("Can not validate Polotno API key. Please report to anton@polotno.com immediately."),!0}export async function validateKey(e){await isKeyPaid(s)&&!e||r()}
|
package/utils/video.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export async function getVideoSize(
|
|
1
|
+
import{polotnoError as e}from"./errors.js";export async function getVideoSize(t){return new Promise((n,o)=>{const r=document.createElement("video");r.crossOrigin="anonymous",r.src=t,r.addEventListener("loadedmetadata",()=>{const{videoWidth:e,videoHeight:t}=r;n({width:e,height:t})}),r.addEventListener("error",n=>{const r=t.slice(0,100);o(e("VIDEO_FAILED",`Failed to load video: ${r}`,{src:r,reason:"load"}))})})}export async function getVideoDuration(e){return new Promise(t=>{const n=document.createElement("video");n.crossOrigin="anonymous",n.src=e,n.addEventListener("loadedmetadata",()=>{const{duration:e}=n;t(e)})})}export async function getVideoPreview(t,n=5){return new Promise((o,r)=>{var i=document.createElement("video"),d=document.createElement("canvas");d.width=480,d.height=360;var a=d.getContext("2d");i.crossOrigin="anonymous",i.src=t,i.addEventListener("error",n=>{const o=String(t).slice(0,100);r(e("VIDEO_FAILED",`Failed to load video: ${o}`,{src:o,reason:"load"},n))}),i.addEventListener("loadeddata",function(){const e=i.videoWidth/i.videoHeight;d.width=480,d.height=480/e,i.currentTime=n}),i.addEventListener("seeked",function(){a.drawImage(i,0,0,d.width,d.height);try{var e=d.toDataURL();o(e)}catch(t){r(t)}})})}export async function getVideoObjectPreview(e,t,n){return new Promise((o,r)=>{const i=t.getContext("2d"),d=()=>{try{i.drawImage(e,0,0,t.width,t.height);const n=t.toDataURL();o(n),e.removeEventListener("seeked",d)}catch(n){r(n),e.removeEventListener("seeked",d)}};e.addEventListener("seeked",d),e.currentTime=n})}
|