前言
还记得去年更新了几个 Dark Mode 的动画,比如这个按钮动画:
还有这个拉绳动画:
今年掘金出了一个码上掘金的playground,就顺势再更新几个吧~
本次灵感来源于第一个按钮动画,当时看着挺满意的,现在就觉得差点意思,完全可以不用加 span
做遮挡,svg好像也是多余的,直接用CSS画出来可能会更好... 反正做一个小小的改进吧,成果如下
有手就行的代码,但还是简单说一下思路,毕竟有字数限制🤷♂️
HTML+CSS
因为涉及到状态的切换,所以 HTML 部分我们依然使用 checkbox
的选中和未选中两种状态来代表明暗两种模式。
<h1>Mancuoj</h1> <input type="checkbox" id="dark-checkbox" /> <label for="dark-checkbox"></label> 复制代码
然后我们需要在CSS部分将 checkbox
隐藏,用 label
替代并画出按钮。
/* 一些预设跳过了 */ label { display: block; position: relative; width: 90px; height: 50px; border-radius: 50px; background-color: $bg-color; cursor: pointer; &:before, &:after { display: block; position: absolute; content: ""; width: 36px; height: 36px; border-radius: 50%; top: 7px; left: 7px; transition: all 1s; } &:before { background: linear-gradient(#fcd670, #f2784b); } } 复制代码
这里我们用 :before
和 after
画出两个圆,将其中一个⚪加上颜色代表☀,然后两个⚪取交集部分作为🌙,如图所示:
隐藏复选框,然后移动⚪位置即可,也可以在这一步再把 :after
的内容画出来,不用移动位置:
#dark-checkbox { display: none; &:checked + label { &:before { background: linear-gradient(#f8f4ed, #e9ddb6); transform: translateX(40px); } &:after { background-color: $bg-color; transform: translateX(24px); } } } 复制代码
然后是与 JS 联动的部分:
.dark { background-color: $dark-color; color: $light-color; transition: all 1s; } 复制代码
JS
因为想要用 localStorage
记录用户的设置,所以就显得比较麻烦:
const changeTheme = () => { const darkCheck = document.getElementById("dark-checkbox"); darkCheck.addEventListener("click", () => { if (darkCheck.checked) { document.body.classList.add("dark"); localStorage.setItem("css", "dark"); } else { document.body.classList.remove("dark"); localStorage.removeItem("css"); } }); if (localStorage.getItem("css")) { document.body.className = "dark"; darkCheck.checked = true; } }; changeTheme(); 复制代码
如果不用 localStorage
直接用一个 toggle()
一行就够了,你甚至可以不用JS,都随你~