如何简化代码实现循环往返的高亮闪烁圆点效果并隐藏圆点黑色背景
如何简化代码实现循环往返的高亮闪烁圆点效果并隐藏圆点黑色背景
嘿,我来帮你搞定这个问题!你的需求其实可以通过CSS变量和更聪明的动画策略轻松解决,既简化冗余代码,又能实现往返循环闪烁,还能去掉黑色背景,咱们一步步来:
1. 先解决黑色背景隐藏问题
原代码里的黑色圆点是.dots本身的背景,只要把它设为透明就行,这样就只会看到闪烁的白色光晕啦:
.dots { background-color: transparent; /* 替换原来的黑色背景 */ width: 20px; height: 20px; border-radius: 50%; position: relative; /* 加这个让伪元素相对圆点定位,避免偏移 */ }
2. 简化重复的CSS代码(告别n个nth-of-type)
你之前为每个圆点写了一套重复的::after样式,只有延迟不同。咱们用CSS变量来统一处理,通过JS给每个圆点动态设置延迟值,这样不管你生成多少个圆点,CSS只需要写一套:
修改JS代码,给每个圆点加延迟变量:
const dotCount = 40; for (let i = 0; i < dotCount; i++) { const dots = document.createElement("div"); // 给每个圆点设置CSS变量:延迟值 dots.style.setProperty('--delay', `${i * 0.25}s`); document.body.appendChild(dots).classList.add("dots"); }
统一CSS的伪元素样式:
把之前重复的n个.dots:nth-of-type(n)::after合并成一套,用变量取延迟值:
.dots::after { content: ""; position: absolute; inset: 0; /* 替代width/height,和父元素圆点完全重合 */ border-radius: 50%; background-color: rgb(255, 255, 255); box-shadow: 0 0 3px 3px rgb(255, 255, 255), 0 0 5px 5px rgb(255, 255, 255), 0 0 12px 12px rgb(255, 255, 255); opacity: 0; /* 基础闪烁动画 + 往返序列动画 */ animation: bright 0.3s linear, moveSequence 20.1s linear infinite alternate; animation-delay: var(--delay); }
3. 实现循环往返的闪烁效果
要让闪烁从左到右再从右到左循环,我们需要一个总序列动画来控制延迟的反转。计算总时长:40个圆点,每个间隔0.25s,正向走完需要(40-1)*0.25 + 0.3 = 10.05s,反向同样10.05s,总周期就是20.1s。然后通过moveSequence动画在反向阶段把每个圆点的延迟反转:
@keyframes bright { 0%, 100% { opacity: 0; } 50% { opacity: 1; } } @keyframes moveSequence { 0% { /* 正向阶段,使用原来的延迟 */ } 50% { /* 反向阶段,延迟改为:总间隔时长 - 当前圆点的延迟 */ animation-delay: calc((39 * 0.25s) - var(--delay)); } 100% { animation-delay: calc((39 * 0.25s) - var(--delay)); } }
这样整个闪烁序列就会先从左到右亮一遍,再从右到左亮一遍,无限循环啦!
完整代码汇总
const dotCount = 40; for (let i = 0; i < dotCount; i++) { const dots = document.createElement("div"); dots.style.setProperty('--delay', `${i * 0.25}s`); document.body.appendChild(dots).classList.add("dots"); }
body { background-color: #737373; display: flex; justify-content: space-evenly; align-items: center; min-height: 100vh; overflow: hidden; } .dots { background-color: transparent; width: 20px; height: 20px; border-radius: 50%; position: relative; } .dots::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background-color: rgb(255, 255, 255); box-shadow: 0 0 3px 3px rgb(255, 255, 255), 0 0 5px 5px rgb(255, 255, 255), 0 0 12px 12px rgb(255, 255, 255); opacity: 0; animation: bright 0.3s linear, moveSequence 20.1s linear infinite alternate; animation-delay: var(--delay); } @keyframes bright { 0%, 100% { opacity: 0; } 50% { opacity: 1; } } @keyframes moveSequence { 0% {} 50% { animation-delay: calc((39 * 0.25s) - var(--delay)); } 100% { animation-delay: calc((39 * 0.25s) - var(--delay)); } }
备注:内容来源于stack exchange,提问作者Szymon Howorus
相关产品推荐
相关产品推荐

