diff --git a/src/env.d.ts b/src/env.d.ts index 64a32cc..fb8d191 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -14,3 +14,11 @@ interface ImportMetaEnv { interface ImportMeta { readonly env: ImportMetaEnv } + +interface Document { + startViewTransition?: (callback: () => void | Promise) => { + ready: Promise + finished: Promise + updateCallbackDone: Promise + } +} diff --git a/src/shared/components/Header.vue b/src/shared/components/Header.vue index d400925..b9519cd 100644 --- a/src/shared/components/Header.vue +++ b/src/shared/components/Header.vue @@ -20,6 +20,35 @@ const { isMobile, isDesktop } = useBreakpoints() const isDark = useDark() +function toggleDark(event: MouseEvent) { + const { clientX: x, clientY: y } = event + const radius = Math.hypot( + Math.max(x, window.innerWidth - x), + Math.max(y, window.innerHeight - y), + ) + if (!document.startViewTransition) { + isDark.value = !isDark.value + return + } + document.startViewTransition(() => { + isDark.value = !isDark.value + }).ready.then(() => { + document.documentElement.animate( + { + clipPath: [ + `circle(0px at ${x}px ${y}px)`, + `circle(${radius}px at ${x}px ${y}px)`, + ], + }, + { + duration: 400, + easing: "ease-in-out", + pseudoElement: "::view-transition-new(root)", + }, + ) + }).catch(() => {}) +} + // 从 store 中获取屏幕模式状态 const { screenMode } = storeToRefs(screenModeStore) @@ -270,7 +299,7 @@ function handleMenuSelect(key: string) { - +