主题切换时,从点击处扩散切换的动画效果
<script setup>
const isDark = ref(false)
async function switchBtn(e) {
const { clientX: x, clientY: y } = e
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)`,
]
await document.startViewTransition(async () => {
isDark.value = !isDark.value
document.documentElement.classList.toggle('dark')
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)`,
},
)
}
</script>
<template>
<el-button @click="switchBtn">
toggle
</el-button>
</template>
<style lang='scss'>
:root {
--bg-color: #fff;
}
:root.dark {
--bg-color: #000;
}
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
}
::view-transition-old(root),
.dark::view-transition-new(root) {
z-index: 1;
}
::view-transition-new(root),
.dark::view-transition-old(root) {
z-index: 9999;
}
body {
background-color: var(--bg-color);
}
</style>