主题快照
# 摘要
五一的时候在B站看了下 antfu (opens new window) 大佬直播,内容是一个**屏幕快照功能 (opens new window)**,看了下,代码不多,蛮简单的,但是特效好啊😂。
不过只有最新浏览器才支持,比如火狐浏览器暂时是不支持的😅。
# 内容
ts
你你可以把它当成一个 Hook
/**
* 主题动画切换
* @see https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
* @see https://github.com/vuejs/vitepress/pull/2347/files
* @param event event
*/
const toggleColorMode = (event?: MouseEvent): void => {
// @ts-expect-error experimental API
const isAppearanceTransition = document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches
// 如果不支持
if (!isAppearanceTransition || !event) {
// 在这里修改主题 themeUpdate()
themeUpdate()
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 () => {
// 在这里修改主题 themeUpdate()
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: isDarkMode.value
? [...clipPath].reverse()
: clipPath,
},
{
duration: 400,
easing: 'ease-out',
pseudoElement: isDarkMode.value
? '::view-transition-old(root)'
: '::view-transition-new(root)',
},
)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
css
吧下面代码块放在 index.css
这种
/* 主题动画切换 */
::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: 100;
}
.dark::view-transition-old(root) {
z-index: 100;
}
.dark::view-transition-new(root) {
z-index: 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
注意: 如果出现样式问题,请调整 z-index
使用方式
<script setup>
// 引入hook
import { toggleColorMode } from 'xxxx'
</script>
<template>
<button @click="toggleColorMode">
click me!
</button>
</tempalte>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 演示
# 相关连接
编辑 (opens new window)
上次更新: 2024-05-21, 09:50:09