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

如何使用D3.js实现过渡进度的拖拽控制?

D3.js实现可拖拽控制进度的矩形过渡动画

问题说明

现有一个初始宽度为10的SVG矩形,需要通过D3.js实现宽度从10过渡到100的动画,同时满足以下需求:

  • 通过range滑块拖拽实时控制动画进度,拖动时直观看到宽度变化
  • 勾选“auto play”复选框时自动播放动画,同时隐藏控制UI

当前基础代码如下:

d3.select("#bar")
  .transition()
  .duration(2000)
  .attr("width", 100);
<svg width="400" height="400">
  <rect id="bar" x="50" y="50" height="10" width="10" fill="blue"></rect>
</svg>

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

此前尝试CSS动画方案无法适配复杂逻辑,参考的旧方案会从指定位置从头播放过渡,不符合实时控制进度的需求,因此需要正确的D3实现方式。

完整解决方案

HTML结构

<form id="controlForm">
  <!-- 自动播放开关 -->
  <input name="autoPlay" id="autoPlay" type="checkbox">
  <label for="autoPlay">auto play</label>

  <!-- 进度控制控件 -->
  <div class="control-group">
    <input name="progress" type="range" min="0" max="100" step="0.1" value="0" />
    <output name="result">0</output>
  </div>
</form>

<svg width="400" height="400">
  <rect id="bar" x="50" y="50" height="10" width="10" fill="blue"></rect>
</svg>

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

CSS样式

.control-group {
  margin: 10px 0;
}

/* 自动播放时隐藏控制控件 */
#autoPlay:checked ~ .control-group {
  display: none;
}

JavaScript逻辑

// 动画基础配置
const widthStart = 10;
const widthEnd = 100;
const duration = 2000;

// 获取DOM元素
const bar = d3.select("#bar");
const form = document.getElementById("controlForm");
const progressInput = form.progress;
const resultOutput = form.result;
const autoPlayCheckbox = form.autoPlay;

// 创建宽度插值函数,用于计算任意进度对应的宽度值
const widthInterpolate = d3.interpolate(widthStart, widthEnd);

// 滑块进度变更处理
function handleProgressChange() {
  const progress = parseFloat(this.value) / 100;
  resultOutput.value = this.value;
  // 根据进度实时更新矩形宽度
  bar.attr("width", widthInterpolate(progress));
}

// 自动播放逻辑
function toggleAutoPlay() {
  if (this.checked) {
    // 重置初始宽度,开始正向过渡
    bar.attr("width", widthStart);
    bar.transition()
      .duration(duration)
      .attr("width", widthEnd)
      .on("end", function() {
        // 正向结束后反向过渡,循环往复
        bar.transition()
          .duration(duration)
          .attr("width", widthStart)
          .on("end", function() {
            if (autoPlayCheckbox.checked) toggleAutoPlay.call(autoPlayCheckbox);
          });
      });
  } else {
    // 取消自动播放时立即终止所有过渡,保留当前状态
    bar.interrupt();
  }
}

// 绑定事件监听
progressInput.addEventListener("input", handleProgressChange);
autoPlayCheckbox.addEventListener("change", toggleAutoPlay);

实现说明

  1. 实时进度控制:利用D3的d3.interpolate生成线性插值函数,将滑块的0-100数值转换为0-1的进度比例,直接计算对应宽度并更新矩形,实现拖拽时的即时视觉反馈。
  2. 自动播放循环:勾选复选框后启动D3过渡动画,正向完成后自动触发反向过渡,形成循环;取消勾选时调用interrupt()终止所有过渡,保留当前矩形状态。
  3. UI状态切换:通过CSS相邻选择器,在自动播放开启时隐藏进度控制控件,符合需求中的UI交互逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 00:45:35