✨ 支持主题切换动画
This commit is contained in:
parent
5dddc31bfa
commit
5ec31ccef7
@ -26,14 +26,14 @@ html, body, div, ul, section, textarea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::view-transition-new(root),
|
||||||
|
::view-transition-old(root) {
|
||||||
|
/* 关闭默认动画,否则影响自定义动画的执行 */
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
// 全局背景
|
// 全局背景
|
||||||
body {
|
body {
|
||||||
// background-position: center center;
|
|
||||||
// background-attachment: fixed;
|
|
||||||
// background-size: cover;
|
|
||||||
// background-repeat: no-repeat;
|
|
||||||
// // background-image: url(../bg.jpg), linear-gradient(to bottom, #010179, #F5C4C1, #151799);
|
|
||||||
background-color: #E7EBF4;
|
background-color: #E7EBF4;
|
||||||
background-image: url(https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg);
|
background-image: url(https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -111,17 +111,55 @@ const useStore = defineStore({
|
|||||||
console.error('clients websocket 连接出错: ', message)
|
console.error('clients websocket 连接出错: ', message)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setTheme(isDark) {
|
setTheme(isDark, animate = true) {
|
||||||
// $store.setThemeConfig({ isDark: val })
|
// $store.setThemeConfig({ isDark: val })
|
||||||
const html = document.documentElement
|
const html = document.documentElement
|
||||||
document.startViewTransition(() => {
|
if(animate) {
|
||||||
|
let transition = document.startViewTransition(() => {
|
||||||
// 在 startViewTransition 中修改 DOM 状态产生动画
|
// 在 startViewTransition 中修改 DOM 状态产生动画
|
||||||
document.documentElement.classList.toggle('dark')
|
document.documentElement.classList.toggle('dark')
|
||||||
})
|
})
|
||||||
if (isDark) html.setAttribute('class', 'dark')
|
transition.ready.then(() => {
|
||||||
else html.setAttribute('class', '')
|
// 由于我们要从鼠标点击的位置开始做动画,所以我们需要先获取到鼠标的位置
|
||||||
localStorage.setItem('isDark', isDark)
|
// 假设 'e' 是从某个事件监听器传入的事件对象
|
||||||
this.$patch({ isDark })
|
|
||||||
|
// 窗口中心点
|
||||||
|
// const screenWidth = window.innerWidth
|
||||||
|
// const screenHeight = window.innerHeight
|
||||||
|
// const centerX = screenWidth / 2
|
||||||
|
// const centerY = screenHeight / 2
|
||||||
|
const centerX = 0
|
||||||
|
const centerY = 0
|
||||||
|
|
||||||
|
// 现在 centerX 和 centerY 包含了屏幕中心的坐标
|
||||||
|
console.log('Screen center X:', centerX, 'Screen center Y:', centerY)
|
||||||
|
|
||||||
|
// 计算半径,以鼠标点击的位置为圆心,到四个角的距离中最大的那个作为半径
|
||||||
|
const radius = Math.hypot(
|
||||||
|
Math.max(centerX, innerWidth - centerX),
|
||||||
|
Math.max(centerY, innerHeight - centerY)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 自定义动画
|
||||||
|
document.documentElement.animate(
|
||||||
|
{
|
||||||
|
clipPath: [
|
||||||
|
`circle(0% at ${ centerX }px ${ centerY }px)`,
|
||||||
|
`circle(${ radius }px at ${ centerX }px ${ centerY }px)`,
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
duration: 500,
|
||||||
|
pseudoElement: '::view-transition-new(root)'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isDark) html.setAttribute('class', 'dark')
|
||||||
|
else html.setAttribute('class', '')
|
||||||
|
localStorage.setItem('isDark', isDark)
|
||||||
|
this.$patch({ isDark })
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setDefaultTheme() {
|
setDefaultTheme() {
|
||||||
let isDark = false
|
let isDark = false
|
||||||
@ -133,7 +171,7 @@ const useStore = defineStore({
|
|||||||
console.log('当前系统使用的是深色模式:', systemTheme ? '是' : '否')
|
console.log('当前系统使用的是深色模式:', systemTheme ? '是' : '否')
|
||||||
isDark = systemTheme
|
isDark = systemTheme
|
||||||
}
|
}
|
||||||
this.setTheme(isDark)
|
this.setTheme(isDark, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user