SVG圆形边框单向进度增长后逐步消失效果实现问题
实现方案
你不需要额外新增幽灵圆做遮盖,仅通过调整stroke-dasharray和stroke-dashoffset两个属性就可以实现需求,逻辑如下:
- 圆形总周长记为
circumference,18%进度对应的弧长记为segLength = circumference * 0.18 - 第一阶段(进度增长):固定
stroke-dashoffset为0,动态调整stroke-dasharray的实线长度从0增加到segLength,即可实现进度从顶部0点增长到18%位置的效果 - 第二阶段(进度消失):固定
stroke-dasharray为${segLength} ${circumference},动态调整stroke-dashoffset从0增加到segLength,即可保持实线段终点位置不变,起点逐步向终点移动直到完全消失
HTML代码
<div class="circles"> <svg class="animated-circle animated-circle--fixed" width="400" height="400"> <circle class="animated-circle__circle" stroke="lightblue" stroke-width="2" fill="transparent" r="199" cx="200" cy="200" /> </svg> <svg class="animated-circle animated-circle--animated" width="400" height="400"> <circle class="animated-circle__circle progress-circle" stroke="blue" stroke-width="2" fill="transparent" r="199" cx="200" cy="200" /> <circle class="circle-icon__circle" stroke="transparent" stroke-width="0" fill="red" r="15" cx="375" cy="110" /> </svg> </div>
CSS代码
.circles { position: relative; } .animated-circle--fixed { position: absolute; top: 0; left: 0; z-index: 1; } .animated-circle--animated { position: relative; z-index: 50; } .animated-circle__circle { transition: 0.06s stroke-dashoffset, 0.06s stroke-dasharray; transform: rotate(-90deg); transform-origin: 50% 50%; }
JS代码
const circle = document.querySelector('.progress-circle'); const radius = circle.r.baseVal.value; const circumference = radius * 2 * Math.PI; const segLength = circumference * 0.18; // 18%进度对应的弧长 let progress = 0; // 第一阶段:进度增长 function animateGrow() { if (progress < 18) { progress++; const currentSeg = circumference * progress / 100; circle.style.strokeDasharray = `${currentSeg} ${circumference}`; circle.style.strokeDashoffset = '0'; setTimeout(animateGrow, 60); } else { animateShrink(); // 增长完成进入消失阶段 } } let offset = 0; // 第二阶段:进度消失,终点位置保持不变 function animateShrink() { if (offset < segLength) { offset += segLength / 18; // 保持和增长阶段一致的动画速度 circle.style.strokeDasharray = `${segLength} ${circumference}`; circle.style.strokeDashoffset = `${offset}`; setTimeout(animateShrink, 60); } } // 启动动画 animateGrow();
内容的提问来源于stack exchange,提问作者Jérémy Dutheil
相关产品推荐
相关产品推荐

