From 6dfc646385ad9250ff7f18f0ae28e865b3393878 Mon Sep 17 00:00:00 2001 From: DonV <2465204327@qq.com> Date: Wed, 31 Jul 2024 15:47:33 +0800 Subject: [PATCH] docs: add keyboard control switch theme (#17664) * feat(docs): add keyboard control switch theme * chore: optimizing the code --------- Co-authored-by: qiang --- .../components/common/vp-theme-toggler.vue | 105 +++++++++--------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/docs/.vitepress/vitepress/components/common/vp-theme-toggler.vue b/docs/.vitepress/vitepress/components/common/vp-theme-toggler.vue index 9387be762d..a50e896bd7 100644 --- a/docs/.vitepress/vitepress/components/common/vp-theme-toggler.vue +++ b/docs/.vitepress/vitepress/components/common/vp-theme-toggler.vue @@ -3,8 +3,10 @@ import { nextTick, ref, watch } from 'vue' import { isDark, toggleDark } from '../../composables/dark' import DarkIcon from '../icons/dark.vue' import LightIcon from '../icons/light.vue' +import type { SwitchInstance } from 'element-plus' const darkMode = ref(isDark.value) +const switchRef = ref() watch( () => darkMode.value, @@ -13,64 +15,63 @@ watch( } ) -let resolveFn: (value: boolean | PromiseLike) => void -const switchTheme = (event: MouseEvent) => { - const isAppearanceTransition = - // @ts-expect-error - document.startViewTransition && - !window.matchMedia('(prefers-reduced-motion: reduce)').matches - if (!isAppearanceTransition || !event) { - resolveFn(true) - return - } - const x = event.clientX - const y = event.clientY - const endRadius = Math.hypot( - Math.max(x, innerWidth - x), - Math.max(y, innerHeight - y) - ) - // @ts-expect-error: Transition API - const transition = document.startViewTransition(async () => { - resolveFn(true) - await nextTick() - }) - transition.ready.then(() => { - const clipPath = [ - `circle(0px at ${x}px ${y}px)`, - `circle(${endRadius}px at ${x}px ${y}px)`, - ] - document.documentElement.animate( - { - clipPath: isDark.value ? [...clipPath].reverse() : clipPath, - }, - { - duration: 400, - easing: 'ease-in', - pseudoElement: isDark.value - ? '::view-transition-old(root)' - : '::view-transition-new(root)', - } +const beforeChange = () => { + return new Promise((resolve) => { + const isAppearanceTransition = + // @ts-expect-error + document.startViewTransition && + !window.matchMedia('(prefers-reduced-motion: reduce)').matches + if (!isAppearanceTransition) { + resolve(true) + return + } + + const switchElement = switchRef.value?.$el + const rect = switchElement.getBoundingClientRect() + const x = rect.left + rect.width / 2 + const y = rect.top + rect.height / 2 + + const endRadius = Math.hypot( + Math.max(x, innerWidth - x), + Math.max(y, innerHeight - y) ) - }) -} -const beforeChange = (): Promise => { - return new Promise((resolve) => { - resolveFn = resolve + // @ts-expect-error: Transition API + const transition = document.startViewTransition(async () => { + resolve(true) + await nextTick() + }) + transition.ready.then(() => { + const clipPath = [ + `circle(0px at ${x}px ${y}px)`, + `circle(${endRadius}px at ${x}px ${y}px)`, + ] + document.documentElement.animate( + { + clipPath: isDark.value ? [...clipPath].reverse() : clipPath, + }, + { + duration: 400, + easing: 'ease-in', + pseudoElement: isDark.value + ? '::view-transition-old(root)' + : '::view-transition-new(root)', + } + ) + }) }) }