fix(theme): 用整页快照过渡消除明暗割裂
- 支持 View Transition 时整页旧/新快照交叉淡入 160ms,背景图与底色不再各自过渡 - 不支持或减少动画偏好时回退到原来的颜色过渡
This commit is contained in:
@@ -1422,3 +1422,17 @@ html.theme-transition .site-background {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* 明暗切换:支持的浏览器直接对整页做快照交叉淡入,避免背景图和底色各变各的 */
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation-duration: 160ms;
|
||||
animation-timing-function: var(--su-ease-in-out);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,8 +308,26 @@ export default function AppNext() {
|
||||
useEffect(() => {
|
||||
const root = document.documentElement
|
||||
if (root.dataset.scheme === scheme) return
|
||||
|
||||
const apply = () => {
|
||||
root.dataset.scheme = scheme
|
||||
}
|
||||
const doc = document as Document & {
|
||||
startViewTransition?: (callback: () => void) => unknown
|
||||
}
|
||||
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||
|
||||
if (!reduceMotion && typeof doc.startViewTransition === 'function') {
|
||||
try {
|
||||
doc.startViewTransition(apply)
|
||||
return
|
||||
} catch {
|
||||
// 浏览器正在跑另一段过渡时退回 CSS 过渡
|
||||
}
|
||||
}
|
||||
|
||||
root.classList.add('theme-transition')
|
||||
root.dataset.scheme = scheme
|
||||
apply()
|
||||
const timer = window.setTimeout(() => root.classList.remove('theme-transition'), 180)
|
||||
return () => {
|
||||
window.clearTimeout(timer)
|
||||
|
||||
Reference in New Issue
Block a user