d3 путь рисуется дважды при попытке анимации пути - PullRequest
0 голосов
/ 14 декабря 2018

Я использую эту технику для анимации пути в d3: https://bl.ocks.org/mbostock/5649592

Я анимирую дуги между узлами.Мои данные выглядят так:

this.transfers = [[1, 480, 0, 5], [2, 0, 480, 20], [3, 0, 720, 5], [3, 240, 720, 5], [3, 480, 720, 5], [5, 480, 0, 5]];

Цель кода - визуализация игрового процесса.Первый элемент каждого внутреннего массива выше - это раунд игры, следующие два - это координаты x узлов, которые перевели некоторые точки - первый узел изгибается на второй - и четвертый - это количество переданных точек.,Я пытаюсь запрограммировать дугу для анимации между узлами, которые принимали участие в переносе, причем дуга перемещается от одного узла к другому.Это код для анимированной дуги:

this.linkAnimation = this.svg.append('g')
  .selectAll('path')
  .data (self.transfers)
  .enter()
  .append('path')
  .attr('fill', 'none');

this.timedAnimation();

timedAnimation( ) {
  for (let j = 0; j < this.rounds+1; j++ ) {

    this.linkAnimation = this.linkAnimation
      .transition()              // transition for delay between rounds
      .delay(2000)
      .attr('d', (t, i) => {
        if (j == t[0]) {
          let denominator = (t[1] < t[2])? 1.75 : 2; // to keep forward and reverse arcs from tracing the same path
          return ['M', t[1], self.height, 'A',
            (t[1] - t[2])/2, ',',
            (t[1] - t[2])/denominator, 0, 0, ',',
            t[1] < t[2] ? 1 : 0, t[2], ',', self.height]
            .join(' ');
        }
      })
    .attr('stroke-width', d => this.linkWidth(d[3]))
    .call(this.transition);
  }
}

transition(path) {
  path.transition()
    .duration(2000)
    .attrTween("stroke-dasharray", self.tweenDash);
}

tweenDash(path) {
  let l = this.getTotalLength(),
    i = d3.interpolateString("0," + l, l + "," + l);
  if (l == 0) { return; } else {
    return function(t) { return i(t); };
}

Проблема в том, что каждая дуга рисуется дважды подряд.Он полностью прорисовывается (не анимация движения) один раз, прямо перед появлением анимации движения.

1 Ответ

0 голосов
/ 15 декабря 2018

В начале анимации вы должны инициализировать stroke-dasharray.

. Выберите действительно большой размер для начальной черты, больше любой длины пути, которую вы собираетесь нарисовать.

.attr('stroke-width', d => this.linkWidth(d[3]))
.attr('stroke-dasharray', "0,1000000")
.call(this.transition);
...