前言
👏CSS 实现七彩圆环loading动画,速速来Get吧~
1.实现效果
2.实现步骤
- 定义父容器宽度为–w,每个圆环之间的gap间距为–gap,圆环的border边框宽为–border;
:root { --border: 5px; --gap: 30px; --w: 200px; }
- 如何绘制一个半圆环?
- 定义一个div元素,假设宽为200px,高为200px/2(即为宽度的一半),圆角,设置border边框
div{ width: 200px; height: 100px; border: 5px solid #e94545; border-radius: 50%; }
- 修改border-radius为50% 50% 0 0/100% 100% 0 0
+ border-radius: 50% 50% 0 0/100% 100% 0 0; + border-radius: 50%;
- 去掉底部边框,就可以得到一个半圆环了
+ border-bottom: none;
- 在父容器内定义七个半圆环,为每个圆环添加自定义变量,–c表示当前圆环的边框颜色,–i表示当前圆环的索引位置(从0开始,依次+1)
<section> <div class="loader-item" style="--c: #e94545; --i: 0"></div> <div class="loader-item" style="--c: #eb8f34; --i: 1"></div> <div class="loader-item" style="--c: #eecf69; --i: 2"></div> <div class="loader-item" style="--c: #215221; --i: 3"></div> <div class="loader-item" style="--c: #87bb80; --i: 4"></div> <div class="loader-item" style="--c: #87ceeb; --i: 5"></div> <div class="loader-item" style="--c: #c393eb; --i: 6"></div> </section>
section { width: var(--w); height: var(--w); position: relative; }
- 为每个半圆环添加样式,基于父容器absolute定位,水平居中,left为50% - 宽度的一半
- 第一个圆环的宽度为–w,每个圆环的高度都为宽度的一半
- 每个圆环间的gap为–gap,所以第二个圆环的宽度为w-gap*2
- 第三个半圆环的宽度为w-gap22
- 可以得到,每个圆环的宽度为calc(var(–w) - var(–gap) * 2 * var(–i)),i为当前圆环的索引位置(从0开始,依次+1)
.loader-item { --width: calc(var(--w) - var(--gap) * 2 * var(--i)); width: var(--width); height: calc(var(--width) / 2); border: var(--border) solid var(--c); border-radius: 50% 50% 0 0/100% 100% 0 0; border-bottom: none; position: absolute; left: calc(50% - var(--width) / 2); }
- 为每个半圆环设置top,第一个圆环为0,第二个为gap,第三个为gap*2,可得到top为 calc(var(–gap) * var(–i))
.loader-item{ + top: calc(var(--gap) * var(--i)); }
- 为每个圆环添加旋转动画,哎嘛呀,这转的也太不和谐了
.loader-item{ + animation: rotate 2s cubic-bezier(0.11, 0.85, 0.22, 1.3) infinite; } @keyframes rotate { 0%, 25% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
- 添加transform-origin,设置为 50% 100%,这才对了,和谐多了
.loader-item{ + transform-origin: 50% 100%; }
- 设置动画延迟,第一个圆环延迟-0ms,第二个延迟-60ms,第三个延迟-120ms,即calc(-60ms * var(–i)),i为当前圆环的索引位置(从0开始,依次+1)
.loader-item{ + animation-delay: calc(-60ms * var(--i)); }
- 父容器添加hover事件,当hover时候,将每个圆环的亮度提示,并暂停动画,就完成了啦~
section:hover .loader-item { filter: brightness(1.5); animation-play-state: paused; }
- 每个半圆环,添加0.5的transition过渡效果
.loader-item{ + transition: all 0.5s; }
3.实现代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <link rel="stylesheet" href="../common.css" /> <style> :root { --border: 5px; --gap: 15px; --w: 200px; } section { width: var(--w); height: var(--w); position: relative; } .loader-item { --width: calc(var(--w) - var(--gap) * 2 * var(--i)); width: var(--width); height: calc(var(--width) / 2); border: var(--border) solid var(--c); border-radius: 50% 50% 0 0/100% 100% 0 0; border-bottom: none; position: absolute; left: calc(50% - var(--width) / 2); top: calc(var(--gap) * var(--i)); transform-origin: 50% 100%; animation: rotate 2s cubic-bezier(0.11, 0.85, 0.22, 1.3) infinite; animation-delay: calc(-60ms * var(--i)); transition: all 0.5s; } section:hover .loader-item { filter: brightness(1.5); animation-play-state: paused; } @keyframes rotate { 0%, 25% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style> <body> <section> <div class="loader-item" style="--c: #e94545; --i: 0"></div> <div class="loader-item" style="--c: #eb8f34; --i: 1"></div> <div class="loader-item" style="--c: #eecf69; --i: 2"></div> <div class="loader-item" style="--c: #215221; --i: 3"></div> <div class="loader-item" style="--c: #87bb80; --i: 4"></div> <div class="loader-item" style="--c: #87ceeb; --i: 5"></div> <div class="loader-item" style="--c: #c393eb; --i: 6"></div> </section> </body> </html>