fix: align svg frame bg with canvas

This commit is contained in:
Ryan Di
2026-03-18 19:41:14 +11:00
parent 8d003a1d21
commit 3f405ab833
2 changed files with 46 additions and 4 deletions
@@ -24,6 +24,7 @@ import { getBoundTextElement, getContainerElement } from "@excalidraw/element";
import { getLineHeightInPx } from "@excalidraw/element";
import {
isArrowElement,
isFrameElement,
isFrameLikeElement,
isIframeLikeElement,
isInitializedImageElement,
@@ -40,6 +41,7 @@ import { getElementAbsoluteCoords } from "@excalidraw/element";
import type {
ExcalidrawElement,
ExcalidrawFrameElement,
ExcalidrawFrameLikeElement,
ExcalidrawTextElementWithContainer,
NonDeletedExcalidrawElement,
@@ -723,10 +725,10 @@ export const renderSceneToSvg = (
const nonIframeElements = elements.filter((el) => !isIframeLikeElement(el));
const frameBackgroundByElementId = new Map<
ExcalidrawElement["id"],
ExcalidrawFrameLikeElement
ExcalidrawFrameElement
>();
const renderFrameBackgroundNode = (frame: ExcalidrawFrameLikeElement) => {
const renderFrameBackgroundNode = (frame: ExcalidrawFrameElement) => {
if (
!frame ||
!frame.backgroundColor ||
@@ -773,7 +775,10 @@ export const renderSceneToSvg = (
(renderConfig.frameRendering.outline || renderConfig.exportingFrame)
) {
const renderedFrameBackgrounds = new Set<string>();
if (renderConfig.exportingFrame) {
if (
renderConfig.exportingFrame &&
isFrameElement(renderConfig.exportingFrame)
) {
renderFrameBackgroundNode(renderConfig.exportingFrame);
renderedFrameBackgrounds.add(renderConfig.exportingFrame.id);
}
@@ -786,7 +791,7 @@ export const renderSceneToSvg = (
: getContainingFrame(element, elementsMap);
if (
!frame ||
!isFrameElement(frame) ||
renderedFrameBackgrounds.has(frame.id) ||
!frame.backgroundColor ||
isTransparent(frame.backgroundColor)
@@ -577,6 +577,43 @@ describe("exporting frames", () => {
).toBeTruthy();
});
it("should not render magicframe background", async () => {
const magicframe = API.createElement({
type: "magicframe",
width: 100,
height: 100,
x: 0,
y: 0,
backgroundColor: "#ffc9c9",
});
const frameChild = API.createElement({
type: "rectangle",
width: 50,
height: 50,
x: 10,
y: 10,
frameId: magicframe.id,
});
const { exportedElements, exportingFrame } = prepareElementsForExport(
[frameChild, magicframe],
{
selectedElementIds: {},
},
false,
);
const svg = await exportToSvg({
elements: exportedElements,
files: null,
exportPadding: 0,
exportingFrame,
});
expect(svg.querySelector(`[data-id="${magicframe.id}"]`)).not.toBeNull();
expect(svg.querySelector('rect[fill="#ffc9c9"]')).toBeNull();
});
it("should not export frame-overlapping elements belonging to different frame", async () => {
const frame1 = API.createElement({
type: "frame",