CSS实现SVG花瓣平滑循环动画的问题及优化咨询
解决SVG花瓣填充动画的闪烁与循环卡顿问题
问题根源分析
- 初始闪烁:SVG路径默认
fill-opacity:1,而动画起始状态为透明,设置的animation-delay会让花瓣在延迟期间保持默认显示状态,延迟结束后突然跳转到透明,引发闪烁。 - 循环卡顿:总动画时长与各花瓣延迟的总和不匹配,最后一片花瓣动画结束到下一轮启动的间隔过长,造成衔接断层。
优化方案
1. 修复初始闪烁
- 给所有花瓣设置初始
fill-opacity:0,与动画起始状态对齐,避免初始显示全部花瓣。 - 调整延迟计算,让第一片花瓣无需等待直接启动动画,后续花瓣按顺序延迟。
2. 实现流畅循环
- 重新计算总动画时长:总时长 = 单花瓣动画周期 × 花瓣数量,确保每轮动画无缝衔接。
- 调整关键帧百分比,让每个花瓣的填充/透明阶段在总时长内均匀分配,消除空白间隔。
优化后的完整代码
:root { --petal-count: 5; /* 花瓣数量 */ --single-petal-duration: 0.5s; /* 单花瓣从透明到填充再到透明的时长 */ --total-animation-duration: calc(var(--petal-count) * var(--single-petal-duration)); /* 总循环时长 */ } body { background: black; } .icon__flower { display: block; height: 105px; margin: auto; width: 110px; } /* 初始化所有花瓣为透明 */ .icon__flower path { fill-opacity: 0; animation: fillAnimation var(--total-animation-duration) infinite linear; } /* 关键帧调整:让每个花瓣的填充阶段在对应时间段内生效 */ @keyframes fillAnimation { 0%, 100% { fill-opacity: 0; } /* 计算每个花瓣填充的起始和结束百分比:(n-1)/petal-count *100% 到 n/petal-count *100% */ 10%, 30% { fill-opacity: 1; } } /* 为每个花瓣设置精准延迟,确保顺序触发 */ .icon__flower path:nth-child(1) { animation-delay: calc(0 * var(--single-petal-duration)); } .icon__flower path:nth-child(2) { animation-delay: calc(1 * var(--single-petal-duration)); } .icon__flower path:nth-child(3) { animation-delay: calc(2 * var(--single-petal-duration)); } .icon__flower path:nth-child(4) { animation-delay: calc(3 * var(--single-petal-duration)); } .icon__flower path:nth-child(5) { animation-delay: calc(4 * var(--single-petal-duration)); }
<div class="loading-animation"> <svg class="icon icon__flower" viewBox="0 0 110 105" xmlns="http://www.w3.org/2000/svg"> <path d="M55.483.264 66.29 17.751a21.32 21.32 0 0 1 0 22.498L55.483 57.736a.573.573 0 0 1-.966 0L43.71 40.249a21.32 21.32 0 0 1 0-22.498L54.517.264a.573.573 0 0 1 .966 0Z" fill="#fff"></path> <path d="M109.866 40.542 96.529 55.967c-5.28 6.11-13.475 8.79-21.313 6.973l-19.793-4.588a.55.55 0 0 1-.289-.894l13.337-15.425c5.28-6.11 13.475-8.79 21.313-6.973l19.793 4.588a.549.549 0 0 1 .289.894Z" fill="#fff"></path> <path d="M88.253 104.956 69.78 96.999c-7.314-3.15-12.318-10.13-13.017-18.15l-1.762-20.255a.54.54 0 0 1 .745-.55L74.22 66c7.314 3.15 12.318 10.13 13.017 18.15l1.762 20.255a.54.54 0 0 1-.745.55Z" fill="#fff"></path> <path d="m20.003 104.405 1.813-20.255c.717-8.02 5.87-14.999 13.4-18.149l19.014-7.957a.55.55 0 0 1 .768.55L53.184 78.85c-.717 8.02-5.87 14.999-13.4 18.149l-19.014 7.957a.55.55 0 0 1-.767-.551Z" fill="#fff"></path> <path d="m.423 39.648 19.793-4.588c7.838-1.817 16.032.863 21.313 6.973l13.337 15.425a.55.55 0 0 1-.288.894L34.782 62.94c-7.837 1.817-16.031-.863-21.312-6.973L.134 40.542a.55.55 0 0 1 .289-.894Z" fill="#fff"></path> </svg> </div>
额外说明
- 使用
linear动画缓动函数,确保每个阶段速度一致,避免快慢不均。 - 通过CSS变量统一管理花瓣数量和时长,后续修改更便捷。
内容的提问来源于stack exchange,提问作者dustin
相关产品推荐
相关产品推荐

