如何在d3中模拟简单的轨道行为

时间:2014-08-09 10:49:55

标签: javascript svg d3.js

我的问题在于这个小提琴中可见的怪异眨眼:http://jsfiddle.net/jn97Lt4e/2/

var addRandomDebris, i, render, satellites, source;

var getRandomFromBetween = function(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
};

source = {
  size: 20
};

satellites = [];

addRandomSatellites = function() {
  satellites.push({
    distance: getRandomFromBetween(50, 375),
    size: getRandomFromBetween(2, 6),
    speed: getRandomFromBetween(5, 30),
    angle: getRandomFromBetween(1, 359)
  });
};

i = getRandomFromBetween(32, 64);

while (i-- > 0) {
  addRandomSatellites();
}

render = function(satellites, source) {
  var animateFrames, container, dimensions, svg, timeZero;

  dimensions = {
    width: 800,
    height: 800
  };

  timeZero = Date.now();

  svg = d3.select('#svg')
    .insert('svg')
    .attr('viewBox', '0, 0, 800, 800')
    .attr('class', 'game-planetarium');

  svg.append('circle')
    .attr('r', source.size)
    .attr('cx', dimensions.width * 0.5)
    .attr('cy', dimensions.height * 0.5)
    .attr('class', 'source');

  container = svg.append('g')
    .attr('transform', 'translate(' + dimensions.width * 0.5 + ',' + dimensions.height * 0.5 + ')');

  container.selectAll('g.satellite')
    .data(satellites)
    .enter()
    .append('g')
    .attr('class', 'satellite')
    .each(function(d, i) {
      d3.select(this)
        .append('circle')
        .attr('r', d.size)
        .attr('cx', d.distance)
        .attr('cy', 0)
        .attr('class', 'satellite');
    });

  animateFrames = function() {
    var delta = Date.now() - timeZero;

    svg.selectAll('.satellite')
      .attr('transform', function(d) {
        return 'rotate(' + d.angle + delta * (d.speed / 10000) + ')';
    });
  };

  d3.timer(animateFrames);
};

(function() {
  render(satellites, source);
})();

我正在尝试整理一个简单的基于d3的动画,它代表某种静态中心体和围绕它的一组卫星。

我发现了一个很好的例子:http://bl.ocks.org/djvanderlaan/4953593,并尝试根据我的需要进行调整。不幸的是,这种奇怪的眨眼正在破坏正常工作的动画,我不知道如何调试它。

此外,经过较长一段时间后,动画变得越来越不流畅。

你能建议一个更好的方法或指出卫星闪烁的原因吗?

提前致谢

1 个答案:

答案 0 :(得分:1)

问题似乎是通过将计时系统从计算现在和程序开始之间的差值切换到现在和最后一帧来解决的:

container.selectAll('g.satellite')
    .data(satellites)
    .enter()
    .append('g')
    .attr('class', 'satellite')
    .each(function(d, i) {
        d3.select(this)
            .append('circle')
            .attr('r', d.size)
            .attr('cx', d.distance)
            .attr('cy', 0)
            .attr('class', 'satellite')
            .attr('transform', 'rotate(' + d.angle + ')');
    });

animateFrames = function() {
    var delta = Date.now() - timeZero;
    timeZero += delta;

    svg.selectAll('.satellite')
        .each(function (d) {
            var satellite = d3.select(this);
            var t = d3.transform(satellite.attr("transform"));
            t.rotate += delta * d.speed / 10000;
            satellite.attr("transform", "rotate(" + t.rotate + ")");
        });
};