大家好,我是开源小星呀!我的目标是每天分享超有用的开源项目。
今天我带大家来实现一个精美炫酷的CSS主题切换动画按钮,免费开源。
动画介绍
这是一个用于主题切换的 SVG 图标动画,该动画通过 SVG 和 CSS 实现,允许用户在浅色和深色主题之间切换,同时图标本身也具有光晕效果和轨迹效果的动画。最终效果是一个具有视觉吸引力和交互性的主题切换按钮。
动画预览
图片
实现过程
项目包含三个主要文件:
- index.html:定义页面结构和svg按钮图标。
- style.css:包含所有明暗主题的 CSS 样式和动画定义。
- script.js:实现主题切换的 JavaScript 逻辑。
按钮的SVG定义
SVG 文件定义了一个复杂的月亮形状图标,包含多个嵌套的元素,每个元素都有特定的样式和动画效果。
下面的代码定义了月亮图标的主体轮廓,是绘制月亮形状的核心部分:
<svg class="main" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g>
<path class="outline" d="M9.8815 1.36438L9.88141 1.36429C9.70639 1.18942 9.48342 1.07041 9.24073 1.02235C8.99803 0.974286 8.74653 0.999323 8.51808 1.09429L8.51753 1.09452C4.54484 2.75146 1.75 6.6732 1.75 11.25C1.75 17.3262 6.67489 22.25 12.75 22.25C14.9217 22.2501 17.0448 21.6075 18.852 20.4032C20.6591 19.1989 22.0695 17.4868 22.9055 15.4825L22.9058 15.4818C23.0007 15.2532 23.0256 15.0015 22.9774 14.7587C22.9291 14.5159 22.8099 14.2929 22.6348 14.118C22.4597 13.9431 22.2366 13.8241 21.9937 13.7761C21.7509 13.7281 21.4993 13.7533 21.2708 13.8484L21.2707 13.8485C20.2346 14.2801 19.1231 14.5016 18.0007 14.5H18C15.7457 14.5 13.5837 13.6045 11.9896 12.0104C10.3955 10.4163 9.5 8.25433 9.5 5.99999L9.5 5.99927C9.49838 4.8769 9.71983 3.76541 10.1515 2.72938C10.2468 2.50072 10.2721 2.24888 10.224 2.00584C10.1759 1.76281 10.0567 1.53954 9.8815 1.36438Z" fill="black" stroke="black" stroke-width="2"/>
<!-- 其他路径和元素 -->
</g>
</svg>
下面这部分代码定义了月亮图标内部的形状和细节:
<g class="inner">
<path class="inner-face" fill-rule="evenodd" clip-rule="evenodd" d="M9.528 1.71799C9.63312 1.82308 9.70465 1.95704 9.73349 2.10286C9.76234 2.24868 9.7472 2.39979 9.69 2.53699C9.23282 3.6342 8.99828 4.81134 9 5.99999C9 8.38694 9.94821 10.6761 11.636 12.3639C13.3239 14.0518 15.6131 15 18 15C19.1886 15.0017 20.3658 14.7672 21.463 14.31C21.6001 14.2529 21.7511 14.2378 21.8968 14.2666C22.0425 14.2954 22.1763 14.3668 22.2814 14.4717C22.3865 14.5767 22.458 14.7105 22.487 14.8562C22.5159 15.0018 22.501 15.1528 22.444 15.29C21.646 17.2032 20.2997 18.8376 18.5747 19.9871C16.8496 21.1367 14.823 21.7501 12.75 21.75C6.951 21.75 2.25 17.05 2.25 11.25C2.25 6.88199 4.917 3.13799 8.71 1.55599C8.84707 1.49901 8.99797 1.48399 9.14359 1.51282C9.28921 1.54166 9.42299 1.61307 9.528 1.71799Z"/>
<!-- 其他内部形状元素 -->
</g>
最终效果如下图所示:
图片
图片
按钮的CSS样式定义
这个动画按钮的核心在于CSS样式。
css文件中定义的是实现光晕效果、轨迹效果以及主题切换的动画效果的核心CSS代码。
首先在 :root 伪类中定义了一些 CSS 变量,这些变量用于控制动画的时序和过渡效果:
:root {
--step: 0.5s;
--ease: linear(
00%,
0.234212.49%,
0.437424.99%,
0.609337.49%,
0.683543.74%,
0.749949.99%,
0.808656.25%,
0.859362.5%,
0.902368.75%,
0.937575%,
0.964881.25%,
0.984487.5%,
0.996193.75%,
1100%
);
}
- --step:定义了动画的基本时间步长为 0.5 秒。
- --ease:定义了一个自定义的缓动函数,用于实现平滑的过渡效果。
接下来定义光晕效果,光晕效果的动画主要通过改变 SVG 元素的 opacity 属性来实现:
.glow {
opacity: 1;
transition-property: opacity;
transition-duration: 1.25s;
transition-timing-function: linear(
00%,
0.00396.25%,
0.015612.5%,
0.035218.75%,
0.062525%,
0.097731.25%,
0.140737.5%,
0.191443.74%,
0.249949.99%,
0.316456.25%,
0.390662.5%,
0.562575%,
0.765687.5%,
1100%
);
}
- opacity: 1:初始时光晕效果是完全可见的。
- transition-property: opacity:指定动画的属性为 opacity。
- ransition-duration: 1.25s:动画持续时间为 1.25 秒。
- transition-timing-function:使用自定义的缓动函数,使光晕效果的透明度变化更加平滑和自然。
然后是轨迹效果,轨迹效果的动画通过改变 SVG 元素的 stroke-dashoffset 和 opacity 属性来实现:
.trail {
stroke-dasharray: 10 80;
stroke-dashoffset: 10;
opacity: 0;
transition-property: stroke-dashoffset, opacity;
transition-duration: calc(var(--step) * 3), calc(var(--step) * 0.5);
transition-timing-function: var(--ease);
}
- stroke-dasharray: 10 80:定义了轨迹的虚线样式,每段虚线的长度为 10,间隔为 80。
- stroke-dashoffset: 10:初始时轨迹的偏移量为 10,使轨迹从中间开始绘制。
- opacity: 0:初始时轨迹是完全透明的。
- transition-property: stroke-dashoffset, opacity:指定动画的属性为 stroke-dashoffset 和 opacity。
- transition-duration: calc(var(--step) * 3), calc(var(--step) * 0.5):动画持续时间分别为 --step 的 3 倍和 0.5 倍。
- transition-timing-function: var(--ease):使用自定义的缓动函数,使轨迹效果的动画更加平滑和自然。
通过光晕和轨迹的实现,我们的月亮图标出现如下图的效果,一条青蓝色的轨迹线环绕月亮外边框闪动:
图片
最后是主题切换动画,主题切换动画主要通过改变页面的 data-theme 属性来触发,从而改变背景颜色、文字颜色等样式:
[data-theme='light'] {
--line: hsl(00%10% / 0.3);
color-scheme: light only;
}
[data-theme='dark'] {
--line: hsl(00%100% / 0.3);
color-scheme: dark only;
}
这部分代码就不多做解释了,非常简单,相信大家应该都可以看懂,无非就是两种主题下的线面颜色定义。
主题切换的JS实现
到JS部分就简单多了,无非就是给按钮绑定点击事件,实现按钮点击后的主题切换效果。
首先定义一个配置对象 config,包含主题信息:
const config = {
theme: 'dark'
};
然后定义主题更新方法,创建 update 函数,用于根据当前主题更新页面的 data-theme 属性:
const update = () => {
document.documentElement.dataset.theme = config.theme;
};
最后给按钮绑定点击事件,实现主题切换:
const toggle = document.querySelector('.toggle');
const handleToggle = () => {
const light = !!toggle.matches('[aria-pressed="false"]');
toggle.setAttribute('aria-pressed', light);
config.theme = light ? 'light' : 'dark';
update();
};
toggle.addEventListener('click', handleToggle);
这个CSS主题切换动画按钮就介绍到这里了,希望大家喜欢。