Skip to content

Commit

Permalink
feat: add toggle theme
Browse files Browse the repository at this point in the history
  • Loading branch information
gjssss committed Feb 19, 2024
1 parent 38a1416 commit 3aeed36
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
21 changes: 21 additions & 0 deletions app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,25 @@ html.dark {
background: #222;
color: white;
}
html {
background: #fff;
}
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-old(root) {
z-index: 1;
}
::view-transition-new(root) {
z-index: 9999;
}
.dark::view-transition-old(root) {
z-index: 9999;
}
.dark::view-transition-new(root) {
z-index: 1;
}
</style>
17 changes: 15 additions & 2 deletions components/Navigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,34 @@ const { data: navigation } = await useAsyncData('nav', async () => {
const data = await fetchContentNavigation()
return data.filter(item => item.children)
})
const colorMode = useColorMode()
</script>

<template>
<div class="flex justify-between p-8">
<div class="flex items-center justify-between p-8">
<NuxtLink href="/">
首页
</NuxtLink>
<div class="flex gap-1.2rem">
<div class="flex items-center gap-1.2rem">
<NuxtLink v-for="item in navigation" :key="item._id" :href="item._path">
{{ item.title }}
</NuxtLink>
<Transition name="spin" mode="out-in">
<div v-if="colorMode.preference === 'dark'" class="i-carbon-moon cursor-pointer text-5" @click="toggleDark" />
<div v-else class="i-carbon-sun cursor-pointer text-5" @click="toggleDark" />
</Transition>
</div>
</div>
</template>

<style>
.spin-enter-active,
.spin-leave-active {
transition: transform 0.3s ease;
}
.spin-enter-from,
.spin-leave-to {
transform: rotateZ(180deg) scale(0.1);
}
</style>
52 changes: 52 additions & 0 deletions composables/toggleTheme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const colorMode = useColorMode()

function toggle() {
colorMode.preference = colorMode.preference === 'dark' ? 'light' : 'dark'
}
/**
* Credit to [@hooray](https://github.com/hooray)
* @see https://github.com/vuejs/vitepress/pull/2347
*/
export function toggleDark(event: MouseEvent) {
// @ts-expect-error experimental API
const isAppearanceTransition = document.startViewTransition
&& !window.matchMedia('(prefers-reduced-motion: reduce)').matches

if (!isAppearanceTransition) {
toggle()
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 () => {
toggle()
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: colorMode.preference === 'dark'
? [...clipPath].reverse()
: clipPath,
},
{
duration: 400,
easing: 'ease-out',
pseudoElement: colorMode.preference === 'dark'
? '::view-transition-old(root)'
: '::view-transition-new(root)',
},
)
})
}

0 comments on commit 3aeed36

Please sign in to comment.