Element-Plus官網(wǎng)黑夜模式切換動(dòng)畫效果的實(shí)現(xiàn)
前言
在使用Element-Plus時(shí),發(fā)現(xiàn)有兩個(gè)很有趣的效果,一個(gè)是header的背景模糊效果,另一個(gè)是黑夜模式切換動(dòng)畫,在此我們先來研究一下黑夜模式切換動(dòng)畫效果是如何實(shí)現(xiàn)的。
代碼
html部分
<div id="box">
<input type="checkbox" id="checkBox">
<label for="checkBox"></label>
</div>
<iframe src="https://www.baidu.com"></iframe>
css部分
html,
body {
background-color: #fff;
height: 100vh;
display: flex;
flex-direction: column;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
iframe {
flex: 1;
}
html.dark {
filter: invert(1) hue-rotate(180deg);
img,
video,
.avatar,
.image,
.thumb,
#box {
filter: invert(1) hue-rotate(180deg);
}
}
::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: 2147483646;
}
html.dark::view-transition-old(root) {
z-index: 2147483646;
}
html.dark::view-transition-new(root) {
z-index: 1;
}
#checkBox {
opacity: 0;
width: 0;
}
#box>label {
display: block;
width: 70px;
height: 30px;
border-radius: 30px;
border: 1px solid #dcdfe6;
background-color: #f2f2f2;
position: relative;
transition: all 0.3s;
display: flex;
align-items: center;
}
#checkBox:checked+label {
background-color: #2c2c2c;
border: 1px solid #4c4d4f;
}
#box>label::before {
content: '??';
position: absolute;
left: 0;
line-height: 25px;
font-size: 18px;
text-align: center;
background-color: #fff;
border-radius: 18px;
border: 1px solid #dcdfe6;
transition: all 0.3s;
}
#checkBox:checked+label::before {
display: none;
}
#checkBox+label::after {
content: '??';
position: absolute;
display: none;
left: 0;
line-height: 25px;
font-size: 18px;
text-align: center;
background-color: #141414;
border-radius: 18px;
border: 1px solid #4c4d4f;
transition: all 0.3s;
}
#checkBox:checked+label::after {
left: calc(100% - 26px);
right: 0;
display: block;
border: 1px solid #4c4d4f;
transition: all 0.3s;
}
js部分
document.getElementById('checkBox').addEventListener('click', function (event) {
toggleTheme(event);
});
// 切換主題
function toggleTheme(event) {
// 檢查瀏覽器是否支持 View Transition API
if (!document.startViewTransition) {
// 不支持則直接切換主題,不添加動(dòng)畫
document.documentElement.classList.toggle('dark')
return
}
const transition = document.startViewTransition(() => {
document.documentElement.classList.toggle('dark')
})
transition.ready.then(() => {
const { clientX, clientY } = event
const endRadius = Math.hypot(Math.max(clientX, innerWidth - clientX), Math.max(clientY, innerHeight - clientY))
const clipPath = [`circle(0px at ${clientX}px ${clientY}px)`, `circle(${endRadius}px at ${clientX}px ${clientY}px)`]
const isDark = document.documentElement.classList.contains('dark')
document.documentElement.animate(
{
clipPath: isDark ? clipPath.reverse() : clipPath
},
{
duration: 450,
easing: 'ease-in',
pseudoElement: isDark ? '::view-transition-old(root)' : '::view-transition-new(root)'
}
)
})
}
上面切換動(dòng)畫效果的實(shí)現(xiàn)用到了View Transition API,同時(shí),用到了filter: invert(1) hue-rotate(180deg)來實(shí)現(xiàn)濾鏡反色,以確保不同主題下背景和內(nèi)容之間的對(duì)比度。
大家快去實(shí)現(xiàn)一下吧!
人心如良苗,得養(yǎng)乃滋長(zhǎng)。苗以泉水灌,心以理義養(yǎng)。一日不讀書,胸臆無佳想。一月不讀書,耳目失精爽。

浙公網(wǎng)安備 33010602011771號(hào)