持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
之前有做过躺8字的效果,可以参考文章:(七)巧用CSS3之躺“8”字,今天在网上看到一个8字循环的效果,感觉很炫酷,所以自己就尝试着实现了一下。
8字循环
结构
<div class="loop">
<div class="circle">
<span style="--i:1"></span>
......
<span style="--i:12"></span>
</div>
<div class="circle">
<span style="--i:0"></span>
......
<span style="--i:11"></span>
</div>
</div>
很简单的代码结构,但是为什么自定义--i
值的起始数据会偏差1
呢,这个为了实现丝滑的效果,可以想象一下动画的下一帧刚好完美的衔接,具体的可能需要你动手去实践才会理解。
样式
首先,我们需要准备容器。这里我们定义了圆圈的大小、点的大小、初始颜色、动画延迟间隔、点的数量,容器的大小设置可以逆推,也可以正推,我选择的是逆推,根据圆的大小来定义容器的大小。此处不需要太关注animation
,你只需要记住它的动画时长是圆圈动画时长的两倍。
.loop {
--circleSize: 10rem;
--borderSize: 1rem;
--color: cyan;
--delay: 0.1s;
--n: 12;
width: calc(var(--circleSize) * 2 - var(--borderSize));
height: var(--circleSize);
position: relative;
animation: _animateColor calc(var(--delay) * var(--n) *4) linear infinite;
}
其次,我们需要定义圆圈的样式,这里就不赘述了,可以查看下面的详情,主要是第二个圆圈需要反转180deg
,也是为了丝滑的效果,具体需要自己实践中体会。
.loop .circle:nth-child(2) {
right: 0;
transform: rotate(-180deg);
}
最后,我们需要定义圆点。圆点是通过伪元素实现的,这是因为我们借助圆点容器(span
)可以更好的排列远点的位置。calc(360deg / var(--n) * var(--i))
是来计算旋转角度的,--n
代表点的数量,也就是说如果点的数量增加的话,这个值也要改变。
.loop .circle span {
display: inline-block;
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
transform: rotate(calc(360deg / var(--n) * var(--i)));
}
.loop .circle span::before {
width: var(--borderSize);
height: var(--borderSize);
border-radius: 50%;
content: '';
position: absolute;
right: 0;
top: calc(50% - var(--borderSize) * 0.5);
background-color: var(--color);
box-shadow: 0 0 var(--borderSize) var(--color), 0 0 calc(var(--borderSize) * 2) var(--color), 0 0 calc(var(--borderSize) * 3) var(--color);
transform: scale(0.1);
animation: _animateScale calc(var(--delay) * var(--n) * 2) linear infinite;
}
效果
详情请查看代码片段,如下:
总结
样式里面用了很多变量,这个方便灵活改变,如果想改变尺寸、颜色、点的数量只需要改对应的参数就好了。
实现这个效果,我们需要注意动画的起始点和进入下一圈的衔接点,了解这个才能让动画更丝滑。