فهرست منبع

fix: Regression - invert SVGs in Dark Mode (#10695)

* initial implementation

* lint

* removed separate getThemeFilterValue function from renderElement

* removed BinaryFileData changes

* filter instead of css filter
zsviczian 1 ماه پیش
والد
کامیت
60759d314d
3فایلهای تغییر یافته به همراه27 افزوده شده و 1 حذف شده
  1. 2 0
      packages/common/src/constants.ts
  2. 16 1
      packages/element/src/renderElement.ts
  3. 9 0
      packages/excalidraw/renderer/staticSvgScene.ts

+ 2 - 0
packages/common/src/constants.ts

@@ -190,6 +190,8 @@ export const THEME = {
   DARK: "dark",
 } as const;
 
+export const DARK_THEME_FILTER = "invert(93%) hue-rotate(180deg)";
+
 export const FRAME_STYLE = {
   strokeColor: "#bbb" as ExcalidrawElement["strokeColor"],
   strokeWidth: 2 as ExcalidrawElement["strokeWidth"],

+ 16 - 1
packages/element/src/renderElement.ts

@@ -14,6 +14,7 @@ import {
   DEFAULT_REDUCED_GLOBAL_ALPHA,
   ELEMENT_READY_TO_ERASE_OPACITY,
   FRAME_STYLE,
+  DARK_THEME_FILTER,
   MIME_TYPES,
   THEME,
   distance,
@@ -433,9 +434,22 @@ const drawElementOnCanvas = (
       break;
     }
     case "image": {
+      context.save();
+      const cacheEntry =
+        element.fileId !== null
+          ? renderConfig.imageCache.get(element.fileId)
+          : null;
       const img = isInitializedImageElement(element)
-        ? renderConfig.imageCache.get(element.fileId)?.image
+        ? cacheEntry?.image
         : undefined;
+
+      const shouldInvertImage =
+        renderConfig.theme === THEME.DARK &&
+        cacheEntry?.mimeType === MIME_TYPES.svg;
+
+      if (shouldInvertImage) {
+        context.filter = DARK_THEME_FILTER;
+      }
       if (img != null && !(img instanceof Promise)) {
         if (element.roundness && context.roundRect) {
           context.beginPath();
@@ -472,6 +486,7 @@ const drawElementOnCanvas = (
       } else {
         drawImagePlaceholder(element, context);
       }
+      context.restore();
       break;
     }
     default: {

+ 9 - 0
packages/excalidraw/renderer/staticSvgScene.ts

@@ -3,11 +3,13 @@ import {
   MAX_DECIMALS_FOR_SVG_EXPORT,
   SVG_NS,
   THEME,
+  DARK_THEME_FILTER,
   getFontFamilyString,
   isRTL,
   isTestEnv,
   getVerticalOffset,
   applyDarkModeFilter,
+  MIME_TYPES,
 } from "@excalidraw/common";
 import { normalizeLink, toValidURL } from "@excalidraw/common";
 import { hashString } from "@excalidraw/element";
@@ -520,6 +522,13 @@ const renderElementToSvg = (
 
         const g = svgRoot.ownerDocument.createElementNS(SVG_NS, "g");
 
+        if (
+          renderConfig.theme === THEME.DARK &&
+          fileData.mimeType === MIME_TYPES.svg
+        ) {
+          g.setAttribute("filter", DARK_THEME_FILTER);
+        }
+
         if (element.crop) {
           const mask = svgRoot.ownerDocument.createElementNS(SVG_NS, "mask");
           mask.setAttribute("id", `mask-image-crop-${element.id}`);