【问题标题】:D3.js animate a circle along x, y coordinatesD3.js 沿 x,y 坐标为圆设置动画
【发布时间】:2022-01-21 17:07:25
【问题描述】:

我想沿 x,y 坐标为圆设置动画。我希望圆圈沿着提供的 x,y 坐标移动。到目前为止,我的代码只是为每个 x,y 点绘制多个圆圈。圆圈遵循 x,y 坐标,但我想要的只是一个圆圈沿着这些点移动。我提供了几个数据点的样本。该数据集有数千个 x,y 点。

//Sample data
var dataPoints = [
      { "x": 58.83, "y": 26.67 },
      { "x": 58.83, "y": 26.69 },
      { "x": 58.82, "y": 26.71 },
      { "x": 58.82, "y": 26.72 },
      { "x": 58.81, "y": 26.73 },
      { "x": 58.8, "y": 26.71 },
      { "x": 58.8, "y": 26.7 },
      { "x": 58.8, "y": 26.68 },
      { "x": 58.79, "y": 26.66 },
      { "x": 58.79, "y": 26.63 },
      { "x": 58.8, "y": 26.61 },
      { "x": 58.8, "y": 26.59 },
      { "x": 58.8, "y": 26.56 },
      { "x": 58.81, "y": 26.53 },
      { "x": 58.81, "y": 26.51 },
      { "x": 58.82, "y": 26.48 },
      { "x": 58.83, "y": 26.46 },
      { "x": 58.84, "y": 26.45 },
      { "x": 58.84, "y": 26.46 },
      { "x": 58.84, "y": 26.47 },
      { "x": 58.83, "y": 26.49 },
      { "x": 58.83, "y": 26.51 },
      { "x": 58.83, "y": 26.53 },
      { "x": 58.82, "y": 26.55 },
      { "x": 58.82, "y": 26.58 },
      { "x": 58.81, "y": 26.6 },
      { "x": 58.81, "y": 26.62 },
      { "x": 58.81, "y": 26.64 },
      { "x": 58.81, "y": 26.67 },
      { "x": 58.8, "y": 26.69 },
      { "x": 58.8, "y": 26.7 },
      { "x": 58.8, "y": 26.71 },
      { "x": 58.81, "y": 26.72 },
      { "x": 58.8, "y": 26.71 },
      { "x": 58.8, "y": 26.7 },
      { "x": 58.8, "y": 26.67 },
      { "x": 58.8, "y": 26.63 },
      { "x": 58.8, "y": 26.6 },
      { "x": 58.8, "y": 26.57 },
      { "x": 58.81, "y": 26.53 },
      { "x": 58.82, "y": 26.51 },
      { "x": 58.83, "y": 26.48 },
      { "x": 58.84, "y": 26.45 },
      { "x": 58.85, "y": 26.43 },
      { "x": 58.85, "y": 26.42 },
      { "x": 58.86, "y": 26.41 },
      { "x": 58.86, "y": 26.4 },
      { "x": 58.85, "y": 26.41 },
      { "x": 58.85, "y": 26.42 },
      { "x": 58.84, "y": 26.43 },
      { "x": 58.84, "y": 26.45 },
      { "x": 58.84, "y": 26.47 },
      { "x": 58.84, "y": 26.49 },
      { "x": 58.84, "y": 26.52 },
      { "x": 58.83, "y": 26.56 },
      { "x": 58.82, "y": 26.59 },
      { "x": 58.82, "y": 26.64 },
      { "x": 58.81, "y": 26.67 },
      { "x": 58.8, "y": 26.7 },
      { "x": 58.79, "y": 26.73 },
      { "x": 58.79, "y": 26.75 },
      { "x": 58.78, "y": 26.76 },
      { "x": 58.78, "y": 26.74 },
      { "x": 58.78, "y": 26.71 },
      { "x": 58.78, "y": 26.69 },
      { "x": 58.78, "y": 26.65 },
      { "x": 58.78, "y": 26.6 },
      { "x": 58.78, "y": 26.56 },
      { "x": 58.79, "y": 26.52 },
      { "x": 58.79, "y": 26.48 }
    ]

这是在 D3 中绘制圆圈的代码部分。

   var myCircle = this.svg.append('g');
  
 // Add circles 
   myCircle.selectAll("circle")
      .data(
        dataPoints
      )
      .enter()
      .append("circle")

      .attr("cx", function (d: { x: d3.NumberValue; }) {

        return x(d.x);
      })
      .attr("cy", function (d: { y: d3.NumberValue; }) {
        return y(d.y);
      })
      .attr("r", 5)
      .style("opacity", .9)

      .style("fill", this.myColor)
      .transition()
      .delay(3000)
      .duration(3000)

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    这是一个基于one from Mike Bostock 的示例。您可以创建一条路径,然后使用attrTween 沿着路径移动圆圈。

    <!-- Updated example from https://bl.ocks.org/mbostock/1705868 -->
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <script src="https://d3js.org/d3.v7.js"></script>
    </head>
    
    <body>
        <div id="chart"></div>
    
        <script>
          // set up
          const margin = { top: 10, bottom: 10, left: 10, right: 10 };
    
          const width = 175 - margin.left - margin.right;
          const height = 175 - margin.top - margin.bottom;
    
          const svg = d3.select('#chart')
            .append('svg')
              .attr('width', width + margin.left + margin.right)
              .attr('height', height + margin.top + margin.bottom);
    
          const g = svg.append('g')
              .attr('transform', `translate(${margin.left},${margin.top})`);
    
          // data
          const dataPoints = [
            { "x": 58.83, "y": 26.67 },
            { "x": 58.83, "y": 26.69 },
            { "x": 58.82, "y": 26.71 },
            { "x": 58.82, "y": 26.72 },
            { "x": 58.81, "y": 26.73 },
            { "x": 58.8, "y": 26.71 },
            { "x": 58.8, "y": 26.7 },
            { "x": 58.8, "y": 26.68 },
            { "x": 58.79, "y": 26.66 },
            { "x": 58.79, "y": 26.63 },
            { "x": 58.8, "y": 26.61 },
            { "x": 58.8, "y": 26.59 },
            { "x": 58.8, "y": 26.56 },
            { "x": 58.81, "y": 26.53 },
            { "x": 58.81, "y": 26.51 },
            { "x": 58.82, "y": 26.48 },
            { "x": 58.83, "y": 26.46 },
            { "x": 58.84, "y": 26.45 },
            { "x": 58.84, "y": 26.46 },
            { "x": 58.84, "y": 26.47 },
            { "x": 58.83, "y": 26.49 },
            { "x": 58.83, "y": 26.51 },
            { "x": 58.83, "y": 26.53 },
            { "x": 58.82, "y": 26.55 },
            { "x": 58.82, "y": 26.58 },
            { "x": 58.81, "y": 26.6 },
            { "x": 58.81, "y": 26.62 },
            { "x": 58.81, "y": 26.64 },
            { "x": 58.81, "y": 26.67 },
            { "x": 58.8, "y": 26.69 },
            { "x": 58.8, "y": 26.7 },
            { "x": 58.8, "y": 26.71 },
            { "x": 58.81, "y": 26.72 },
            { "x": 58.8, "y": 26.71 },
            { "x": 58.8, "y": 26.7 },
            { "x": 58.8, "y": 26.67 },
            { "x": 58.8, "y": 26.63 },
            { "x": 58.8, "y": 26.6 },
            { "x": 58.8, "y": 26.57 },
            { "x": 58.81, "y": 26.53 },
            { "x": 58.82, "y": 26.51 },
            { "x": 58.83, "y": 26.48 },
            { "x": 58.84, "y": 26.45 },
            { "x": 58.85, "y": 26.43 },
            { "x": 58.85, "y": 26.42 },
            { "x": 58.86, "y": 26.41 },
            { "x": 58.86, "y": 26.4 },
            { "x": 58.85, "y": 26.41 },
            { "x": 58.85, "y": 26.42 },
            { "x": 58.84, "y": 26.43 },
            { "x": 58.84, "y": 26.45 },
            { "x": 58.84, "y": 26.47 },
            { "x": 58.84, "y": 26.49 },
            { "x": 58.84, "y": 26.52 },
            { "x": 58.83, "y": 26.56 },
            { "x": 58.82, "y": 26.59 },
            { "x": 58.82, "y": 26.64 },
            { "x": 58.81, "y": 26.67 },
            { "x": 58.8, "y": 26.7 },
            { "x": 58.79, "y": 26.73 },
            { "x": 58.79, "y": 26.75 },
            { "x": 58.78, "y": 26.76 },
            { "x": 58.78, "y": 26.74 },
            { "x": 58.78, "y": 26.71 },
            { "x": 58.78, "y": 26.69 },
            { "x": 58.78, "y": 26.65 },
            { "x": 58.78, "y": 26.6 },
            { "x": 58.78, "y": 26.56 },
            { "x": 58.79, "y": 26.52 },
            { "x": 58.79, "y": 26.48 }
          ];
    
          // scales
          const x = d3.scaleLinear()
              .domain(d3.extent(dataPoints, d => d.x))
              .range([0, width]);
    
          const y = d3.scaleLinear()
              .domain(d3.extent(dataPoints, d => d.y))
              .range([height, 0]);
    
          // line generator
          const line = d3.line()
              .x(d => x(d.x))
              .y(d => y(d.y));
    
          // add path
          const path = g.append('path')
              .attr('d', line(dataPoints))
              .attr('stroke', 'none')
              .attr('fill', 'none');
    
          // draw circle at initial location
          const circle = g.append('circle')
              .attr('fill', 'red')
              .attr('r', 5)
              .attr('transform', `translate(${x(dataPoints[0].x)},${y(dataPoints[0].y)})`);
    
          // animate
          circle.transition()
              .ease(d3.easeLinear)
              .duration(5000)
              .attrTween('transform', translateAlong(path.node()));
    
          // https://bl.ocks.org/mbostock/1705868
          function translateAlong(path) {
            const length = path.getTotalLength();
            return function() {
              return function(t) {
                const {x, y} = path.getPointAtLength(t * length);
                return `translate(${x},${y})`;
              }
            }
          }
        </script>
    </body>
    </html>

    【讨论】:

      猜你喜欢
      • 2020-11-03
      • 2016-09-17
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多