D3.js在具有不同持续时间的每个元素上重复过渡

水平

我正在尝试沿圆形路径变换点。每个转换都有不同的持续时间。最后,一旦速度持续时间最短的转换结束,所有点的过渡将再次开始。如何独立重新开始每个点的过渡?

const graphWidth = 500;
const graphHeight = 500;
const svg = d3.select("svg")
  .attr("width", graphWidth)
  .attr("height", graphHeight);
const testData = [{
    "country": "Netherlands",
    "speed": 4000
  },
  {
    "country": "Belgium",
    "speed": 2000
  },
  {
    "country": "Austria",
    "speed": 1000
  },
  {
    "country": "Germany",
    "speed": 5000
  },
  {
    "country": "USA",
    "speed": 4000
  }
];

const dots = svg.selectAll('circle')
  .data(testData)
  .enter()
  .append('circle')
  .attr('transform', `translate(${graphWidth / 2}, ${graphHeight / 2})`)
  .attr('cx', 223)
  .attr('r', 5)
  .attr('fill', 'yellow')
  .attr('stroke', 'black');


function transition() {
  svg.selectAll('circle').each(function(d) {
    d3.select(this)
      .transition()
      .ease(d3.easeLinear)
      .duration(d.speed)
      .attrTween('transform', rotTween)
      .on('end', transition);
  })
}
transition();

function rotTween() {
  var i = d3.interpolate(0, 360);
  return function(t) {
    return `translate(${graphWidth / 2}, ${graphHeight / 2}) rotate(${i(t)}, 0, 0)`;
  };
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

鲁本·赫斯鲁特(Ruben Helsloot)

最简单的方法是transition通过.each()移出函数来函数更改为仅处理一个圆的一个过渡

const graphWidth = 500;
const graphHeight = 500;
const svg = d3.select("svg")
  .attr("width", graphWidth)
  .attr("height", graphHeight);
const testData = [{
    "country": "Netherlands",
    "speed": 4000
  },
  {
    "country": "Belgium",
    "speed": 2000
  },
  {
    "country": "Austria",
    "speed": 1000
  },
  {
    "country": "Germany",
    "speed": 5000
  },
  {
    "country": "USA",
    "speed": 4000
  }
];

const dots = svg.selectAll('circle')
  .data(testData)
  .enter()
  .append('circle')
  .attr('transform', `translate(${graphWidth / 2}, ${graphHeight / 2})`)
  .attr('cx', 223)
  .attr('r', 5)
  .attr('fill', 'yellow')
  .attr('stroke', 'black');


function transition(circle, d) {
  d3.select(circle)
    .transition()
    .ease(d3.easeLinear)
    .duration(d.speed)
    .attrTween('transform', rotTween)
    .on('end', function() {
      transition(circle, d);
    });
}

svg.selectAll('circle').each(function(d) {
  transition(this, d);
});

function rotTween() {
  var i = d3.interpolate(0, 360);
  return function(t) {
    return `translate(${graphWidth / 2}, ${graphHeight / 2}) rotate(${i(t)}, 0, 0)`;
  };
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

或者,您可以命名要传递给的匿名函数.each()(在本例中,我将其命名为repeat),然后在.on("end"子句中再次调用该函数。

const graphWidth = 500;
const graphHeight = 500;
const svg = d3.select("svg")
  .attr("width", graphWidth)
  .attr("height", graphHeight);
const testData = [{
    "country": "Netherlands",
    "speed": 4000
  },
  {
    "country": "Belgium",
    "speed": 2000
  },
  {
    "country": "Austria",
    "speed": 1000
  },
  {
    "country": "Germany",
    "speed": 5000
  },
  {
    "country": "USA",
    "speed": 4000
  }
];

const dots = svg.selectAll('circle')
  .data(testData)
  .enter()
  .append('circle')
  .attr('transform', `translate(${graphWidth / 2}, ${graphHeight / 2})`)
  .attr('cx', 223)
  .attr('r', 5)
  .attr('fill', 'yellow')
  .attr('stroke', 'black');

svg.selectAll('circle')
  .each(function repeat(d) {
    d3.select(this)
      .transition()
      .ease(d3.easeLinear)
      .duration(function(d) { return d.speed; })
      .attrTween('transform', rotTween)
      .on("end", repeat);
  });

function rotTween() {
  var i = d3.interpolate(0, 360);
  return function(t) {
    return `translate(${graphWidth / 2}, ${graphHeight / 2}) rotate(${i(t)}, 0, 0)`;
  };
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章