You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SVG制作带动画的环形图(Doughnut Graph)遇阻求助

优化的带动画SVG环形图实现方案

你当前用多个<circle>叠加的实现容易出现分段重叠、位置偏移的问题,更高效的方式是通过精准控制stroke-dashoffset和stroke-dasharray的累加关系来实现分段环形,同时修正SVG元素的基础位置错误。以下是两种目标环形图的完整实现:

核心优化要点

  • 统一所有环形元素的圆心坐标(修正你代码中donut-hole的cx/cy错误)
  • 用stroke-dashoffset的累加值控制分段起始位置,避免重叠
  • 动画从stroke-dasharray: 0 100过渡到目标分段长度,保证平滑展开
  • 两种环形图分别通过调整分段颜色、动画节奏和环形样式实现

第一种环形图(对应目标样式1)

.svg-item {
  width: 50%;
  animation: donutfade 1s forwards;
  opacity: 0;
}

.donut-ring {
  stroke: #F4E2E2;
}

.donut-segment-1 {
  stroke: #EA0001;
  animation: donut1 3s forwards;
}

.donut-segment-2 {
  stroke: #0066FF;
  animation: donut2 3s forwards;
}

.donut-segment-3 {
  stroke: #FF66B2;
  animation: donut3 3s forwards;
}

/* 整体淡入动画 */
@keyframes donutfade {
  to { opacity: 1; }
}

/* 分段动画:从0展开到目标长度 */
@keyframes donut1 {
  0% { stroke-dasharray: 0 100; }
  100% { stroke-dasharray: 17 83; }
}

@keyframes donut2 {
  0% { stroke-dasharray: 0 100; }
  100% { stroke-dasharray: 33 67; }
}

@keyframes donut3 {
  0% { stroke-dasharray: 0 100; }
  100% { stroke-dasharray: 50 50; }
}
<div class="svg-item">
  <svg width="100%" viewBox="0 0 44 44" class="donut">
    <!-- 修正圆心位置,与其他环形保持一致 -->
    <circle class="donut-hole" cx="22" cy="22" r="15.915" fill="transparent"></circle>
    <!-- 基础环形背景 -->
    <circle class="donut-ring" cx="22" cy="22" r="15.915" fill="none" stroke-width="12"></circle>
    <!-- 分段1:起始偏移0,占比17% -->
    <circle class="donut-segment donut-segment-1" cx="22" cy="22" r="15.915" fill="none" stroke-width="12" stroke-dasharray="17 83" stroke-dashoffset="0"></circle>
    <!-- 分段2:起始偏移17(等于分段1的长度),占比33% -->
    <circle class="donut-segment donut-segment-2" cx="22" cy="22" r="15.915" fill="none" stroke-width="12" stroke-dasharray="33 67" stroke-dashoffset="17"></circle>
    <!-- 分段3:起始偏移17+33=50,占比50% -->
    <circle class="donut-segment donut-segment-3" cx="22" cy="22" r="15.915" fill="none" stroke-width="12" stroke-dasharray="50 50" stroke-dashoffset="50"></circle>
  </svg>
</div>

第二种环形图(对应目标样式2,带中间文本+错峰动画)

.svg-item-2 {
  width: 50%;
  animation: donutfade 1s forwards;
  opacity: 0;
}

.donut-ring-2 {
  stroke: #E8F4F8;
}

.donut-segment-a {
  stroke: #00C896;
  animation: donutA 2.5s forwards 0.2s;
  stroke-dasharray: 25 75;
  stroke-dashoffset: 0;
}

.donut-segment-b {
  stroke: #FF9F43;
  animation: donutB 2.5s forwards 0.4s;
  stroke-dasharray: 40 60;
  stroke-dashoffset: 25;
}

.donut-segment-c {
  stroke: #FF6B6B;
  animation: donutC 2.5s forwards 0.6s;
  stroke-dasharray: 35 65;
  stroke-dashoffset: 65;
}

.donut-text {
  font-size: 8px;
  font-family: sans-serif;
  text-anchor: middle;
  dominant-baseline: middle;
  fill: #333;
}

@keyframes donutA {
  0% { stroke-dasharray: 0 100; }
}

@keyframes donutB {
  0% { stroke-dasharray: 0 100; }
}

@keyframes donutC {
  0% { stroke-dasharray: 0 100; }
}
<div class="svg-item-2">
  <svg width="100%" viewBox="0 0 44 44" class="donut">
    <circle cx="22" cy="22" r="15.915" fill="transparent"></circle>
    <circle class="donut-ring-2" cx="22" cy="22" r="15.915" fill="none" stroke-width="10"></circle>
    <circle class="donut-segment-a" cx="22" cy="22" r="15.915" fill="none" stroke-width="10"></circle>
    <circle class="donut-segment-b" cx="22" cy="22" r="15.915" fill="none" stroke-width="10"></circle>
    <circle class="donut-segment-c" cx="22" cy="22" r="15.915" fill="none" stroke-width="10"></circle>
    <!-- 中间文本 -->
    <text class="donut-text" x="22" y="22">100%</text>
  </svg>
</div>

关键说明

  1. 所有环形元素的cx/cy必须统一为SVG画布中心(22,22),避免位置偏移
  2. stroke-dashoffset的数值等于前面所有分段的长度之和,确保分段依次排列不重叠
  3. 动画中stroke-dasharray从0 100过渡到目标值,实现从无到有的展开效果
  4. 第二种环形图通过添加延迟动画、调整stroke-width和中间文本,匹配不同视觉需求

内容的提问来源于stack exchange,提问作者Kenken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:36:14