-
-
Save bartkl/0134c6ce4a5d532464b40d3bfbcb64e4 to your computer and use it in GitHub Desktop.
diff --git a/quartz/components/scripts/darkmode.inline.ts b/quartz/components/scripts/darkmode.inline.ts | |
index c42a367..06767b5 100644 | |
--- a/quartz/components/scripts/darkmode.inline.ts | |
+++ b/quartz/components/scripts/darkmode.inline.ts | |
@@ -1,5 +1,6 @@ | |
-const userPref = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark" | |
-const currentTheme = localStorage.getItem("theme") ?? userPref | |
+import { getUserPreferredColorScheme, renderExcalidrawLinks } from "./util" | |
+ | |
+const currentTheme = localStorage.getItem("theme") ?? getUserPreferredColorScheme() | |
document.documentElement.setAttribute("saved-theme", currentTheme) | |
document.addEventListener("nav", () => { | |
@@ -11,6 +12,7 @@ document.addEventListener("nav", () => { | |
document.documentElement.setAttribute("saved-theme", "light") | |
localStorage.setItem("theme", "light") | |
} | |
+ renderExcalidrawLinks(localStorage.getItem("theme")) | |
} | |
// Darkmode toggle |
diff --git a/quartz/components/scripts/util.ts b/quartz/components/scripts/util.ts | |
index 5fcabad..444e145 100644 | |
--- a/quartz/components/scripts/util.ts | |
+++ b/quartz/components/scripts/util.ts | |
@@ -23,3 +23,31 @@ export function removeAllChildren(node: HTMLElement) { | |
node.removeChild(node.firstChild) | |
} | |
} | |
+ | |
+export function renderExcalidrawLinks(theme: "dark" | "light") { | |
+ let currentTheme = theme == "dark" ? "light" : "dark" | |
+ Object.values(document.getElementsByTagName("img")).forEach(img => { | |
+ if (img.src.endsWith(`.excalidraw.${currentTheme}.svg`)) { | |
+ let srcParts = img.src.split(".") | |
+ srcParts.splice(-2, 1, theme) | |
+ img.src = srcParts.join(".") | |
+ } | |
+ }) | |
+} | |
+ | |
+export function getUserPreferredColorScheme() { | |
+ return window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark" | |
+} | |
+ | |
+// Have SVG images in the article adhere to the correct color scheme. | |
+document.addEventListener("nav", (e) => { | |
+ let theme = localStorage.getItem("theme") ?? getUserPreferredColorScheme() | |
+ Object.values(document.getElementsByTagName("article")[0] | |
+ .getElementsByTagName("a")).forEach(a => { | |
+ if (a.href.endsWith(".excalidraw")) { | |
+ let img = document.createElement("img") | |
+ img.src = `${a.href}.${theme}.svg` | |
+ a.replaceWith(img) | |
+ } | |
+ }) | |
+}) |
@bartkl Thanks for the update. I pointed to this gist in an ongoing quartz pull request.
I think your example helped with the light/dark switching. I'm not really a quartz developer so I can't say much else about the code.
Thanks for this code.
I was a little disappointed by your approach. I'm saving all my images in light mode and let the browser revert colors with css filter.
darkmode.inline.ts
// https://francoisbest.com/posts/2020/dark-mode-for-excalidraw
function applyDarkModeFilter(): void {
const savedTheme = document.documentElement.getAttribute("saved-theme");
const images: HTMLCollectionOf<HTMLImageElement> = document.getElementsByTagName('img');
for (let i = 0; i < images.length; i++) {
const image = images[i];
if (image.src && image.src.endsWith('excalidraw.svg')) {
// It consider image as light by default
if (savedTheme === "dark")
image.classList.add('image-dark');
else
image.classList.remove('image-dark');
}
}
}
document.addEventListener('DOMContentLoaded', applyDarkModeFilter);
document.addEventListener('themechange', applyDarkModeFilter);
darkmode.scss
.image-dark {
filter: invert(100%) hue-rotate(180deg);
}
@Guillaume-Fernandez that's an interesting alternative way of doing it. I'm not mainly a front-end developer, so I wouldn't have thought of a CSS solution like that :).
However, I don't think if I prefer your solution:
- You are moving rendering logic to the client (the color inversion) and I'm not sure if this could become noticable on slower clients for example for bigger images. (This might be nitpicky, just thinking out loud.)
- I'm not sure if simply inverting the colors is the best way to get a dark mode flavour of the images. I honestly doubt that's all the Excalidraw dark mode rendering does. Anyway, I rather rely on them for implementing that logic.
@bartkl
You made me curious!
I just checked, this is how excalidraw dark mode works.
I will test my approach for few days. I think it's simpler and does not need two excalidraw exports (light and dark).
I'm using quartz with VSCode Foam, this is why I can't easily export both images from Obsidian.
@Guillaume-Fernandez Nice find! That's really interesting.
The version of the code I'm currently using can be found in my repo:
https://github.com/bartkl/bartkl.github.io/blob/v4/quartz/components/RenderExcalidraw.tsx
This component is configured in the
quartz.layout.tsx
file in the header of the page I believe. Anyways, you can look that up in the repo as well.Sadly I'm very busy currently so I don't have the time to help making this more accessible or make improvements/enhancements.