feat: stop using CSS filters for dark mode (static canvas) (#10578)

* feat: stop using CSS filters for dark mode (static canvas)

* fix comment

* remove conditional dark mode export

* make shape cache theme-aware

* refactor

* refactor

* fixes and notes
This commit is contained in:
David Luzar
2026-01-04 15:16:35 +01:00
committed by GitHub
parent b5fc873323
commit 63e1148280
30 changed files with 1070 additions and 389 deletions
+9 -5
View File
@@ -6,13 +6,13 @@ import {
FONT_FAMILY,
SVG_NS,
THEME,
THEME_FILTER,
MIME_TYPES,
EXPORT_DATA_TYPES,
arrayToMap,
distance,
getFontString,
toBrandedType,
applyDarkModeFilter,
} from "@excalidraw/common";
import { getCommonBounds, getElementAbsoluteCoords } from "@excalidraw/element";
@@ -268,6 +268,7 @@ export const exportToCanvas = async (
embedsValidationStatus: new Map(),
elementsPendingErasure: new Set(),
pendingFlowchartNodes: null,
theme: appState.exportWithDarkMode ? THEME.DARK : THEME.LIGHT,
},
});
@@ -348,9 +349,6 @@ export const exportToSvg = async (
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 defsElement = svgRoot.ownerDocument.createElementNS(SVG_NS, "defs");
@@ -455,7 +453,12 @@ export const exportToSvg = async (
rect.setAttribute("y", "0");
rect.setAttribute("width", `${width}`);
rect.setAttribute("height", `${height}`);
rect.setAttribute("fill", viewBackgroundColor);
rect.setAttribute(
"fill",
exportWithDarkMode
? applyDarkModeFilter(viewBackgroundColor)
: viewBackgroundColor,
);
svgRoot.appendChild(rect);
}
@@ -489,6 +492,7 @@ export const exportToSvg = async (
)
: new Map(),
reuseImages: opts?.reuseImages ?? true,
theme: exportWithDarkMode ? THEME.DARK : THEME.LIGHT,
},
);
+11 -2
View File
@@ -36,6 +36,7 @@ export type StaticCanvasRenderConfig = {
embedsValidationStatus: EmbedsValidationStatus;
elementsPendingErasure: ElementsPendingErasure;
pendingFlowchartNodes: PendingExcalidrawElements | null;
theme: AppState["theme"];
};
export type SVGRenderConfig = {
@@ -54,6 +55,7 @@ export type SVGRenderConfig = {
* @default true
*/
reuseImages: boolean;
theme: AppState["theme"];
};
export type InteractiveCanvasRenderConfig = {
@@ -148,7 +150,14 @@ export type ScrollBars = {
} | null;
};
export type ElementShape = Drawable | Drawable[] | null;
export type SVGPathString = string & { __brand: "SVGPathString" };
export type ElementShape =
| Drawable
| Drawable[]
| Path2D
| (Drawable | SVGPathString)[]
| null;
export type ElementShapes = {
rectangle: Drawable;
@@ -156,7 +165,7 @@ export type ElementShapes = {
diamond: Drawable;
iframe: Drawable;
embeddable: Drawable;
freedraw: Drawable | null;
freedraw: (Drawable | SVGPathString)[];
arrow: Drawable[];
line: Drawable[];
text: null;