align svg exports with canvas exports
This commit is contained in:
parent
cd8bfb06b5
commit
e49db1dd3c
@ -50,9 +50,6 @@ const ChartPreviewBtn = (props: {
|
|||||||
},
|
},
|
||||||
files: null,
|
files: null,
|
||||||
},
|
},
|
||||||
config: {
|
|
||||||
skipInliningFonts: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
svg.querySelector(".style-fonts")?.remove();
|
svg.querySelector(".style-fonts")?.remove();
|
||||||
previewNode.replaceChildren();
|
previewNode.replaceChildren();
|
||||||
|
@ -140,9 +140,6 @@ const SingleLibraryItem = ({
|
|||||||
},
|
},
|
||||||
files: null,
|
files: null,
|
||||||
},
|
},
|
||||||
config: {
|
|
||||||
skipInliningFonts: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
node.innerHTML = svg.outerHTML;
|
node.innerHTML = svg.outerHTML;
|
||||||
})();
|
})();
|
||||||
|
@ -19,10 +19,6 @@ const exportLibraryItemToSvg = async (elements: LibraryItem["elements"]) => {
|
|||||||
},
|
},
|
||||||
files: null,
|
files: null,
|
||||||
},
|
},
|
||||||
config: {
|
|
||||||
renderEmbeddables: false,
|
|
||||||
skipInliningFonts: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,14 +29,14 @@ import {
|
|||||||
getInitializedImageElements,
|
getInitializedImageElements,
|
||||||
updateImageCache,
|
updateImageCache,
|
||||||
} from "../element/image";
|
} from "../element/image";
|
||||||
import { restore, restoreAppState } from "../data/restore";
|
import { restoreAppState } from "../data/restore";
|
||||||
import {
|
import {
|
||||||
getElementsOverlappingFrame,
|
getElementsOverlappingFrame,
|
||||||
getFrameLikeElements,
|
getFrameLikeElements,
|
||||||
getFrameLikeTitle,
|
getFrameLikeTitle,
|
||||||
getRootElements,
|
getRootElements,
|
||||||
} from "../frame";
|
} from "../frame";
|
||||||
import { getNonDeletedElements, newTextElement } from "../element";
|
import { newTextElement } from "../element";
|
||||||
import { type Mutable } from "../utility-types";
|
import { type Mutable } from "../utility-types";
|
||||||
import { newElementWith } from "../element/mutateElement";
|
import { newElementWith } from "../element/mutateElement";
|
||||||
import { isFrameLikeElement } from "../element/typeChecks";
|
import { isFrameLikeElement } from "../element/typeChecks";
|
||||||
@ -164,13 +164,13 @@ type ExportToCanvasAppState = Partial<
|
|||||||
Omit<AppState, "offsetTop" | "offsetLeft">
|
Omit<AppState, "offsetTop" | "offsetLeft">
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type ExportToCanvasData = {
|
export type ExportSceneData = {
|
||||||
elements: readonly NonDeletedExcalidrawElement[];
|
elements: readonly NonDeletedExcalidrawElement[];
|
||||||
appState?: ExportToCanvasAppState;
|
appState?: ExportToCanvasAppState;
|
||||||
files: BinaryFiles | null;
|
files: BinaryFiles | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ExportToCanvasConfig = {
|
export type ExportSceneConfig = {
|
||||||
theme?: Theme;
|
theme?: Theme;
|
||||||
/**
|
/**
|
||||||
* Canvas background. Valid values are:
|
* Canvas background. Valid values are:
|
||||||
@ -339,8 +339,8 @@ const configExportDimension = async ({
|
|||||||
data,
|
data,
|
||||||
config,
|
config,
|
||||||
}: {
|
}: {
|
||||||
data: ExportToCanvasData;
|
data: ExportSceneData;
|
||||||
config?: ExportToCanvasConfig;
|
config?: ExportSceneConfig;
|
||||||
}) => {
|
}) => {
|
||||||
// clone
|
// clone
|
||||||
const cfg = Object.assign({}, config);
|
const cfg = Object.assign({}, config);
|
||||||
@ -626,8 +626,8 @@ export const exportToCanvas = async ({
|
|||||||
data,
|
data,
|
||||||
config,
|
config,
|
||||||
}: {
|
}: {
|
||||||
data: ExportToCanvasData;
|
data: ExportSceneData;
|
||||||
config?: ExportToCanvasConfig;
|
config?: ExportSceneConfig;
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
config: cfg,
|
config: cfg,
|
||||||
@ -706,7 +706,7 @@ export const exportToCanvas = async ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
type ExportToSvgConfig = Pick<
|
type ExportToSvgConfig = Pick<
|
||||||
ExportToCanvasConfig,
|
ExportSceneConfig,
|
||||||
"canvasBackgroundColor" | "padding" | "theme" | "exportingFrame"
|
"canvasBackgroundColor" | "padding" | "theme" | "exportingFrame"
|
||||||
> & {
|
> & {
|
||||||
/**
|
/**
|
||||||
@ -721,108 +721,75 @@ export const exportToSvg = async ({
|
|||||||
data,
|
data,
|
||||||
config,
|
config,
|
||||||
}: {
|
}: {
|
||||||
data: {
|
data: ExportSceneData;
|
||||||
elements: readonly NonDeletedExcalidrawElement[];
|
config?: ExportSceneConfig;
|
||||||
appState: {
|
}) => {
|
||||||
exportBackground: boolean;
|
const {
|
||||||
exportScale?: number;
|
config: cfg,
|
||||||
viewBackgroundColor: string;
|
normalizedPadding,
|
||||||
exportWithDarkMode?: boolean;
|
exportWidth,
|
||||||
exportEmbedScene?: boolean;
|
exportHeight,
|
||||||
frameRendering?: AppState["frameRendering"];
|
exportScale,
|
||||||
gridModeEnabled?: boolean;
|
x,
|
||||||
};
|
y,
|
||||||
files: BinaryFiles | null;
|
elementsForRender,
|
||||||
};
|
appState,
|
||||||
config?: ExportToSvgConfig;
|
|
||||||
}): Promise<SVGSVGElement> => {
|
|
||||||
// clone
|
|
||||||
const cfg = Object.assign({}, config);
|
|
||||||
|
|
||||||
cfg.exportingFrame = cfg.exportingFrame ?? null;
|
|
||||||
|
|
||||||
const { elements: restoredElements } = restore(
|
|
||||||
{ ...data, files: data.files || {} },
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
const elements = getNonDeletedElements(restoredElements);
|
|
||||||
|
|
||||||
const frameRendering = getFrameRenderingConfig(
|
|
||||||
cfg?.exportingFrame ?? null,
|
|
||||||
data.appState.frameRendering ?? null,
|
|
||||||
);
|
|
||||||
|
|
||||||
let {
|
|
||||||
exportWithDarkMode = false,
|
|
||||||
viewBackgroundColor,
|
|
||||||
exportScale = 1,
|
|
||||||
exportEmbedScene,
|
|
||||||
} = data.appState;
|
|
||||||
|
|
||||||
let padding = cfg.padding ?? 0;
|
|
||||||
|
|
||||||
const elementsForRender = prepareElementsForRender({
|
|
||||||
elements,
|
|
||||||
exportingFrame: cfg.exportingFrame,
|
|
||||||
exportWithDarkMode,
|
|
||||||
frameRendering,
|
frameRendering,
|
||||||
});
|
} = await configExportDimension({ data, config });
|
||||||
|
|
||||||
if (cfg.exportingFrame) {
|
const offsetX = -(x - normalizedPadding);
|
||||||
padding = 0;
|
const offsetY = -(y - normalizedPadding);
|
||||||
|
|
||||||
|
const { elements } = data;
|
||||||
|
|
||||||
|
// initialize SVG root
|
||||||
|
const svgRoot = document.createElementNS(SVG_NS, "svg");
|
||||||
|
svgRoot.setAttribute("version", "1.1");
|
||||||
|
svgRoot.setAttribute("xmlns", SVG_NS);
|
||||||
|
svgRoot.setAttribute(
|
||||||
|
"viewBox",
|
||||||
|
`0 0 ${exportWidth / exportScale} ${exportHeight / exportScale}`,
|
||||||
|
);
|
||||||
|
svgRoot.setAttribute("width", `${exportWidth}`);
|
||||||
|
svgRoot.setAttribute("height", `${exportHeight}`);
|
||||||
|
if (cfg.theme === THEME.DARK) {
|
||||||
|
svgRoot.setAttribute("filter", THEME_FILTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fontFaces = cfg.loadFonts
|
||||||
|
? await Fonts.generateFontFaceDeclarations(elements)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const delimiter = "\n "; // 6 spaces
|
||||||
|
|
||||||
let metadata = "";
|
let metadata = "";
|
||||||
|
|
||||||
// we need to serialize the "original" elements before we put them through
|
// we need to serialize the "original" elements before we put them through
|
||||||
// the tempScene hack which duplicates and regenerates ids
|
// the tempScene hack which duplicates and regenerates ids
|
||||||
if (exportEmbedScene) {
|
if (appState.exportEmbedScene) {
|
||||||
try {
|
try {
|
||||||
metadata = (await import("../data/image")).encodeSvgMetadata({
|
metadata = (await import("../data/image")).encodeSvgMetadata({
|
||||||
// when embedding scene, we want to embed the origionally supplied
|
// when embedding scene, we want to embed the origionally supplied
|
||||||
// elements which don't contain the temp frame labels.
|
// elements which don't contain the temp frame labels.
|
||||||
// But it also requires that the exportToSvg is being supplied with
|
// But it also requires that the exportToSvg is being supplied with
|
||||||
// only the elements that we're exporting, and no extra.
|
// only the elements that we're exporting, and no extra.
|
||||||
text: serializeAsJSON(
|
text: serializeAsJSON(elements, appState, data.files || {}, "local"),
|
||||||
elements,
|
|
||||||
data.appState,
|
|
||||||
data.files || {},
|
|
||||||
"local",
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let [minX, minY, width, height] = getCanvasSize(
|
let exportContentClipPath = "";
|
||||||
cfg.exportingFrame
|
if (cfg.width != null && cfg.height != null) {
|
||||||
? [cfg.exportingFrame]
|
exportContentClipPath = `<clipPath id="content">
|
||||||
: getRootElements(elementsForRender),
|
<rect x="${offsetX}" y="${offsetY}" width="${exportWidth}" height="${exportWidth}"></rect>
|
||||||
);
|
</clipPath>`;
|
||||||
|
|
||||||
width += padding * 2;
|
|
||||||
height += padding * 2;
|
|
||||||
|
|
||||||
// initialize SVG root
|
|
||||||
const svgRoot = document.createElementNS(SVG_NS, "svg");
|
|
||||||
svgRoot.setAttribute("version", "1.1");
|
|
||||||
svgRoot.setAttribute("xmlns", SVG_NS);
|
|
||||||
svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
||||||
svgRoot.setAttribute("width", `${width * exportScale}`);
|
|
||||||
svgRoot.setAttribute("height", `${height * exportScale}`);
|
|
||||||
if (exportWithDarkMode) {
|
|
||||||
svgRoot.setAttribute("filter", THEME_FILTER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const offsetX = -minX + padding;
|
|
||||||
const offsetY = -minY + padding;
|
|
||||||
|
|
||||||
const frameElements = getFrameLikeElements(elements);
|
|
||||||
|
|
||||||
let exportingFrameClipPath = "";
|
let exportingFrameClipPath = "";
|
||||||
const elementsMap = arrayToMap(elements);
|
const elementsMap = arrayToMap(elements);
|
||||||
|
const frameElements = getFrameLikeElements(elements);
|
||||||
for (const frame of frameElements) {
|
for (const frame of frameElements) {
|
||||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(frame, elementsMap);
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(frame, elementsMap);
|
||||||
const cx = (x2 - x1) / 2 - (frame.x - x1);
|
const cx = (x2 - x1) / 2 - (frame.x - x1);
|
||||||
@ -844,36 +811,33 @@ export const exportToSvg = async ({
|
|||||||
</clipPath>`;
|
</clipPath>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fontFaces = !cfg?.skipInliningFonts
|
|
||||||
? await Fonts.generateFontFaceDeclarations(elements)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const delimiter = "\n "; // 6 spaces
|
|
||||||
|
|
||||||
svgRoot.innerHTML = `
|
svgRoot.innerHTML = `
|
||||||
${SVG_EXPORT_TAG}
|
${SVG_EXPORT_TAG}
|
||||||
${metadata}
|
${metadata}
|
||||||
<defs>
|
<defs>
|
||||||
<style class="style-fonts">${delimiter}${fontFaces.join(delimiter)}
|
<style class="style-fonts">${delimiter}${fontFaces.join(delimiter)}</style>
|
||||||
</style>
|
${exportContentClipPath}
|
||||||
${exportingFrameClipPath}
|
${exportingFrameClipPath}
|
||||||
</defs>
|
</defs>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// render background rect
|
// render background rect
|
||||||
if (data.appState.exportBackground && viewBackgroundColor) {
|
if (appState.exportBackground && appState.viewBackgroundColor) {
|
||||||
const rect = svgRoot.ownerDocument!.createElementNS(SVG_NS, "rect");
|
const rect = svgRoot.ownerDocument!.createElementNS(SVG_NS, "rect");
|
||||||
rect.setAttribute("x", "0");
|
rect.setAttribute("x", "0");
|
||||||
rect.setAttribute("y", "0");
|
rect.setAttribute("y", "0");
|
||||||
rect.setAttribute("width", `${width}`);
|
rect.setAttribute("width", `${exportWidth / exportScale}`);
|
||||||
rect.setAttribute("height", `${height}`);
|
rect.setAttribute("height", `${exportHeight / exportScale}`);
|
||||||
rect.setAttribute("fill", viewBackgroundColor);
|
rect.setAttribute(
|
||||||
|
"fill",
|
||||||
|
cfg.canvasBackgroundColor || appState.viewBackgroundColor,
|
||||||
|
);
|
||||||
svgRoot.appendChild(rect);
|
svgRoot.appendChild(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
const rsvg = rough.svg(svgRoot);
|
const rsvg = rough.svg(svgRoot);
|
||||||
|
|
||||||
const renderEmbeddables = cfg.renderEmbeddables ?? false;
|
// const renderEmbeddables = appState.embe ?? false;
|
||||||
|
|
||||||
renderSceneToSvg(
|
renderSceneToSvg(
|
||||||
elementsForRender,
|
elementsForRender,
|
||||||
@ -885,18 +849,18 @@ export const exportToSvg = async ({
|
|||||||
offsetX,
|
offsetX,
|
||||||
offsetY,
|
offsetY,
|
||||||
isExporting: true,
|
isExporting: true,
|
||||||
exportWithDarkMode,
|
exportWithDarkMode: cfg.theme === THEME.DARK,
|
||||||
renderEmbeddables,
|
renderEmbeddables: false,
|
||||||
frameRendering,
|
frameRendering,
|
||||||
canvasBackgroundColor: viewBackgroundColor,
|
canvasBackgroundColor: appState.viewBackgroundColor,
|
||||||
embedsValidationStatus: renderEmbeddables
|
embedsValidationStatus: false
|
||||||
? new Map(
|
? new Map(
|
||||||
elementsForRender
|
elementsForRender
|
||||||
.filter((element) => isFrameLikeElement(element))
|
.filter((element) => isFrameLikeElement(element))
|
||||||
.map((element) => [element.id, true]),
|
.map((element) => [element.id, true]),
|
||||||
)
|
)
|
||||||
: new Map(),
|
: new Map(),
|
||||||
reuseImages: cfg?.reuseImages ?? true,
|
reuseImages: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -916,7 +880,7 @@ export const getCanvasSize = (
|
|||||||
|
|
||||||
export { MIME_TYPES };
|
export { MIME_TYPES };
|
||||||
|
|
||||||
type ExportToBlobConfig = ExportToCanvasConfig & {
|
type ExportToBlobConfig = ExportSceneConfig & {
|
||||||
mimeType?: string;
|
mimeType?: string;
|
||||||
quality?: number;
|
quality?: number;
|
||||||
};
|
};
|
||||||
@ -925,7 +889,7 @@ export const exportToBlob = async ({
|
|||||||
data,
|
data,
|
||||||
config,
|
config,
|
||||||
}: {
|
}: {
|
||||||
data: ExportToCanvasData;
|
data: ExportSceneData;
|
||||||
config?: ExportToBlobConfig;
|
config?: ExportToBlobConfig;
|
||||||
}): Promise<Blob> => {
|
}): Promise<Blob> => {
|
||||||
let { mimeType = MIME_TYPES.png, quality } = config || {};
|
let { mimeType = MIME_TYPES.png, quality } = config || {};
|
||||||
@ -990,7 +954,7 @@ export const exportToClipboard = async ({
|
|||||||
data,
|
data,
|
||||||
config,
|
config,
|
||||||
}: {
|
}: {
|
||||||
data: ExportToCanvasData;
|
data: ExportSceneData;
|
||||||
} & (
|
} & (
|
||||||
| { type: "png"; config?: ExportToBlobConfig }
|
| { type: "png"; config?: ExportToBlobConfig }
|
||||||
| { type: "svg"; config?: ExportToSvgConfig }
|
| { type: "svg"; config?: ExportToSvgConfig }
|
||||||
|
@ -6,7 +6,7 @@ exports[`Test <MermaidToExcalidraw/> > should open mermaid popup when active too
|
|||||||
B --> C{Let me think}
|
B --> C{Let me think}
|
||||||
C -->|One| D[Laptop]
|
C -->|One| D[Laptop]
|
||||||
C -->|Two| E[iPhone]
|
C -->|Two| E[iPhone]
|
||||||
C -->|Three| F[Car]</textarea><div class="ttd-dialog-panel-button-container invisible" style="display: flex; align-items: center;"><button type="button" class="excalidraw-button ttd-dialog-panel-button"><div class=""></div></button></div></div><div class="ttd-dialog-panel"><div class="ttd-dialog-panel__header"><label>Preview</label></div><div class="ttd-dialog-output-wrapper"><div style="opacity: 1;" class="ttd-dialog-output-canvas-container"><canvas width="9" height="0" dir="ltr"></canvas></div></div><div class="ttd-dialog-panel-button-container" style="display: flex; align-items: center;"><button type="button" class="excalidraw-button ttd-dialog-panel-button"><div class="">Insert<span><svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 20 20" class="" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><g stroke-width="1.25"><path d="M4.16602 10H15.8327"></path><path d="M12.5 13.3333L15.8333 10"></path><path d="M12.5 6.66666L15.8333 9.99999"></path></g></svg></span></div></button><div class="ttd-dialog-submit-shortcut"><div class="ttd-dialog-submit-shortcut__key">Ctrl</div><div class="ttd-dialog-submit-shortcut__key">Enter</div></div></div></div></div></div></div></div></div></div></div>"
|
C -->|Three| F[Car]</textarea><div class="ttd-dialog-panel-button-container invisible" style="display: flex; align-items: center;"><button type="button" class="excalidraw-button ttd-dialog-panel-button"><div class=""></div></button></div></div><div class="ttd-dialog-panel"><div class="ttd-dialog-panel__header"><label>Preview</label></div><div class="ttd-dialog-output-wrapper"><div style="opacity: 1;" class="ttd-dialog-output-canvas-container"><canvas width="300" height="0" dir="ltr"></canvas></div></div><div class="ttd-dialog-panel-button-container" style="display: flex; align-items: center;"><button type="button" class="excalidraw-button ttd-dialog-panel-button"><div class="">Insert<span><svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 20 20" class="" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><g stroke-width="1.25"><path d="M4.16602 10H15.8327"></path><path d="M12.5 13.3333L15.8333 10"></path><path d="M12.5 6.66666L15.8333 9.99999"></path></g></svg></span></div></button><div class="ttd-dialog-submit-shortcut"><div class="ttd-dialog-submit-shortcut__key">Ctrl</div><div class="ttd-dialog-submit-shortcut__key">Enter</div></div></div></div></div></div></div></div></div></div></div>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Test <MermaidToExcalidraw/> > should show error in preview when mermaid library throws error 1`] = `
|
exports[`Test <MermaidToExcalidraw/> > should show error in preview when mermaid library throws error 1`] = `
|
||||||
|
@ -6,8 +6,8 @@ exports[`export > exporting svg containing transformed images > svg export outpu
|
|||||||
|
|
||||||
<defs>
|
<defs>
|
||||||
<style class="style-fonts">
|
<style class="style-fonts">
|
||||||
|
</style>
|
||||||
</style>
|
|
||||||
|
|
||||||
</defs>
|
</defs>
|
||||||
<clipPath id="image-clipPath-id1" data-id="id1"><rect width="100" height="100" rx="25" ry="25"></rect></clipPath><g transform="translate(20.710678118654755 20.710678118654755) rotate(315 50 50)" clip-path="url(#image-clipPath-id1)" data-id="id1"><use href="#image-file_A" width="100" height="100" opacity="1"></use></g><clipPath id="image-clipPath-id2" data-id="id2"><rect width="50" height="50" rx="12.5" ry="12.5"></rect></clipPath><g transform="translate(120.71067811865476 20.710678118654755) rotate(45 25 25)" clip-path="url(#image-clipPath-id2)" data-id="id2"><use href="#image-file_A" width="50" height="50" opacity="1" transform="translate(25 25) scale(-1 1) translate(-25 -25)"></use></g><clipPath id="image-clipPath-id3" data-id="id3"><rect width="100" height="100" rx="25" ry="25"></rect></clipPath><g transform="translate(20.710678118654755 120.71067811865476) rotate(45 50 50)" clip-path="url(#image-clipPath-id3)" data-id="id3"><use href="#image-file_A" width="100" height="100" opacity="1" transform="translate(50 50) scale(1 -1) translate(-50 -50)"></use></g><clipPath id="image-clipPath-id4" data-id="id4"><rect width="50" height="50" rx="12.5" ry="12.5"></rect></clipPath><g transform="translate(120.71067811865476 120.71067811865476) rotate(315 25 25)" clip-path="url(#image-clipPath-id4)" data-id="id4"><use href="#image-file_A" width="50" height="50" opacity="1" transform="translate(25 25) scale(-1 -1) translate(-25 -25)"></use></g></svg>"
|
<clipPath id="image-clipPath-id1" data-id="id1"><rect width="100" height="100" rx="25" ry="25"></rect></clipPath><g transform="translate(20.710678118654755 20.710678118654755) rotate(315 50 50)" clip-path="url(#image-clipPath-id1)" data-id="id1"><use href="#image-file_A" width="100" height="100" opacity="1"></use></g><clipPath id="image-clipPath-id2" data-id="id2"><rect width="50" height="50" rx="12.5" ry="12.5"></rect></clipPath><g transform="translate(120.71067811865476 20.710678118654755) rotate(45 25 25)" clip-path="url(#image-clipPath-id2)" data-id="id2"><use href="#image-file_A" width="50" height="50" opacity="1" transform="translate(25 25) scale(-1 1) translate(-25 -25)"></use></g><clipPath id="image-clipPath-id3" data-id="id3"><rect width="100" height="100" rx="25" ry="25"></rect></clipPath><g transform="translate(20.710678118654755 120.71067811865476) rotate(45 50 50)" clip-path="url(#image-clipPath-id3)" data-id="id3"><use href="#image-file_A" width="100" height="100" opacity="1" transform="translate(50 50) scale(1 -1) translate(-50 -50)"></use></g><clipPath id="image-clipPath-id4" data-id="id4"><rect width="50" height="50" rx="12.5" ry="12.5"></rect></clipPath><g transform="translate(120.71067811865476 120.71067811865476) rotate(315 25 25)" clip-path="url(#image-clipPath-id4)" data-id="id4"><use href="#image-file_A" width="50" height="50" opacity="1" transform="translate(25 25) scale(-1 -1) translate(-25 -25)"></use></g></svg>"
|
||||||
|
File diff suppressed because one or more lines are too long
@ -117,9 +117,7 @@ describe("exportToSvg", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(svgElement.getAttribute("filter")).toMatchInlineSnapshot(
|
expect(svgElement.getAttribute("filter")).toMatchInlineSnapshot(`null`);
|
||||||
`"_themeFilter_1883f3"`,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("with exportPadding", async () => {
|
it("with exportPadding", async () => {
|
||||||
@ -149,10 +147,12 @@ describe("exportToSvg", () => {
|
|||||||
elements: ELEMENTS,
|
elements: ELEMENTS,
|
||||||
appState: {
|
appState: {
|
||||||
...DEFAULT_OPTIONS,
|
...DEFAULT_OPTIONS,
|
||||||
exportScale: SCALE,
|
|
||||||
},
|
},
|
||||||
files: null,
|
files: null,
|
||||||
},
|
},
|
||||||
|
config: {
|
||||||
|
scale: SCALE,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(svgElement).toHaveAttribute(
|
expect(svgElement).toHaveAttribute(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user