From adac1e37337c50b15e6fb358fca6efd98cbe30a3 Mon Sep 17 00:00:00 2001
From: taskylizard <75871323+taskylizard@users.noreply.github.com>
Date: Sat, 23 Dec 2023 03:02:38 +0000
Subject: [PATCH] transitions on appearance switch
---
.vitepress/theme/Layout.vue | 64 +++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/.vitepress/theme/Layout.vue b/.vitepress/theme/Layout.vue
index 2de3a90d1..ed1359982 100644
--- a/.vitepress/theme/Layout.vue
+++ b/.vitepress/theme/Layout.vue
@@ -2,6 +2,44 @@
import DefaultTheme from "vitepress/theme";
import Sidebar from "./components/SidebarCard.vue";
import Announcement from "./components/Announcement.vue";
+import { useData } from "vitepress";
+import { nextTick, provide } from "vue";
+
+const { isDark } = useData();
+
+const enableTransitions = () =>
+ "startViewTransition" in document &&
+ window.matchMedia("(prefers-reduced-motion: no-preference)").matches;
+
+provide("toggle-appearance", async ({ clientX: x, clientY: y }: MouseEvent) => {
+ if (!enableTransitions()) {
+ isDark.value = !isDark.value;
+ return;
+ }
+
+ const clipPath = [
+ `circle(0px at ${x}px ${y}px)`,
+ `circle(${Math.hypot(
+ Math.max(x, innerWidth - x),
+ Math.max(y, innerHeight - y),
+ )}px at ${x}px ${y}px)`,
+ ];
+
+ // @ts-expect-error
+ await document.startViewTransition(async () => {
+ isDark.value = !isDark.value;
+ await nextTick();
+ }).ready;
+
+ document.documentElement.animate(
+ { clipPath: isDark.value ? clipPath.reverse() : clipPath },
+ {
+ duration: 300,
+ easing: "ease-in",
+ pseudoElement: `::view-transition-${isDark.value ? "old" : "new"}(root)`,
+ },
+ );
+});
const { Layout } = DefaultTheme;
@@ -17,3 +55,29 @@ const { Layout } = DefaultTheme;
+
+