基于D3.js的圆形路径环绕动画呼吸应用开发问询
需求说明
我希望开发一款基于D3.js的呼吸应用,实现两个核心功能:
- 一个小圆形沿圆形路径循环运动,且能通过调整时间间隔控制运动速度;
- 中心母圆实现“呼吸”效果——持续缩放变化。
下面是我当前的基础代码:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script> <html> <head> <title>multibar d3</title> <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> <style> </style> </head> <body> <script> var width = 960; var height = 600; var margin = {top: 20, right: 5, bottom: 30, left: 20}; var svg = d3.select("body") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr('class', 'circleorbits') .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var originX = 200; var originY = 200; var innerCircleRadius = 40; var outerCircleRadius = 60; var group = svg.append("g"); var outerCircle = svg.append("circle") .attr("cx", originX) .attr("cy", originY) .attr("opacity", 0) .attr("r", outerCircleRadius) .attr("fill", "none") .attr("stroke", "black"); var chairOriginX = originX + ((60) * Math.sin(0)); var chairOriginY = originY - ((60) * Math.cos(0)); var pointOnOuterCircle = svg.append("circle") .attr("cx", chairOriginX) .attr("cy", chairOriginY) .attr("opacity", 0) .attr("r", 5) .attr("fill", "black"); // ANIMATIONS // drawing outer circle outerCircle.transition().delay(500).duration(500).style("opacity", 1); // drawing point on outer circle pointOnOuterCircle.transition().delay(1000).duration(500).style("opacity", 1); // rotating the chair var tween = function (d, i, a) { return d3.interpolateString("rotate(0, 200, 200)", "rotate(360, 200, 200)"); } var duration = 5000; pointOnOuterCircle.transition().delay(2000).duration(duration).attrTween("transform", tween); function newLoop(){ pointOnOuterCircle.transition().delay(2000).duration(5000).attrTween("transform", tween); } setInterval(newLoop, duration); </script> </body> </html>
修改方案与完整代码
1. 核心修改点
- 重构小圆形公转逻辑:移除
setInterval,改用D3过渡的.each("end")实现无缝循环,避免动画延迟叠加问题 - 新增母圆呼吸动画:通过嵌套过渡实现半径在区间内循环缩放
- 集中可配置参数:将速度、幅度等参数放在顶部,方便快速调整
完整修改后代码
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> <html> <head> <title>D3呼吸动画应用</title> <style> .center-circle { fill: #e0f7fa; stroke: #00796b; } .orbit-circle { fill: none; stroke: #757575; } .moving-point { fill: #d32f2f; } </style> </head> <body> <script> // 基础配置 var width = 960; var height = 600; var margin = {top: 20, right: 5, bottom: 30, left: 20}; var originX = 200; var originY = 200; // 动画可配置参数 var orbitDuration = 4000; // 小圆形公转一圈时长(ms),值越小速度越快 var breathDuration = 3000; // 母圆一次呼吸时长(ms) var centerMinRadius = 30; // 母圆最小半径 var centerMaxRadius = 50; // 母圆最大半径 var orbitRadius = 60; // 公转轨道半径 // 创建SVG容器 var svg = d3.select("body") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr('class', 'circleorbits') .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // 添加中心母圆 var centerCircle = svg.append("circle") .attr("cx", originX) .attr("cy", originY) .attr("r", centerMinRadius) .attr("class", "center-circle"); // 添加公转轨道圆 var orbitCircle = svg.append("circle") .attr("cx", originX) .attr("cy", originY) .attr("r", orbitRadius) .attr("class", "orbit-circle"); // 添加沿轨道运动的小圆形 var movingCircle = svg.append("circle") .attr("cx", originX + orbitRadius) .attr("cy", originY) .attr("r", 6) .attr("class", "moving-point"); // 定义公转动画补间函数 function orbitTween() { return d3.interpolateString( `rotate(0, ${originX}, ${originY})`, `rotate(360, ${originX}, ${originY})` ); } // 启动公转循环动画 function startOrbit() { movingCircle.transition() .duration(orbitDuration) .ease(d3.easeLinear) // 匀速运动 .attrTween("transform", orbitTween) .each("end", startOrbit); } // 启动母圆呼吸循环动画 function startBreath() { centerCircle.transition() .duration(breathDuration) .ease(d3.easeInOutSine) // 平滑过渡 .attr("r", centerMaxRadius) .transition() .duration(breathDuration) .ease(d3.easeInOutSine) .attr("r", centerMinRadius) .each("end", startBreath); } // 初始化启动所有动画 startOrbit(); startBreath(); </script> </body> </html>
使用说明
- 调整
orbitDuration可控制小圆形公转速度,数值越小速度越快 - 修改
breathDuration、centerMinRadius、centerMaxRadius可调整母圆呼吸的速度和缩放幅度 - 动画采用D3内置缓动函数:
d3.easeLinear保证公转匀速,d3.easeInOutSine让呼吸过渡更自然
内容的提问来源于stack exchange,提问作者The Old County
相关产品推荐
相关产品推荐

