В d3 возможно ли динамически изменить, где начинается позиция пути для анимации?

к: уточнить. Представьте себе круг. Мы начинаем рисовать окружность с определенной координаты. Теперь давайте нарисуем круг, начиная с другой координаты.

Я играю с данными пути, полученными из глифов SVG, а затем использую d3js tween для анимации изменения между путями.

Для этого примера, считая от 1 -> 9,0, а затем повторяя.

http://jsfiddle.net/chrisloughnane/HL2ET/

Как видите, некоторые переходы не так хороши, как другие. Они рисуют линию, закрывающую путь для следующего пути. (Я предполагаю, что) это происходит, когда начало и конец пути очень далеко друг от друга, когда выполняется расчет для новой формы. Когда работает очень приятно.

Может ли кто-нибудь предложить возможное решение уродливых линий?

CODE без данных пути

svg.append("path")
    .attr("transform", "translate(150,300)scale(.2,-.2)")
  .style("stroke", "red")
  .style("fill", "gray")
  .style("stroke-width", "9")
    .attr("d", d0)
    .call(transition, digits[0], digits[position]);

function transition(path, d0, d1) {
  position++;
  if(position==10)
  {
    position=0;
  }
  path.transition()
      .duration(2000)
      .attrTween("d", pathTween(d1, 4))
      .each("end", function() { d3.select(this).call(transition, d1, digits[position]); });
}

function pathTween(d1, precision) {
  return function() {
    var path0 = this,
        path1 = path0.cloneNode(),
        n0 = path0.getTotalLength(),
        n1 = (path1.setAttribute("d", d1), path1).getTotalLength();

    // Uniform sampling of distance based on specified precision.
    var distances = [0], i = 0, dt = precision / Math.max(n0, n1);
    while ((i += dt) < 1) distances.push(i);
    distances.push(1);

    // Compute point-interpolators at each distance.
    var points = distances.map(function(t) {
      var p0 = path0.getPointAtLength(t * n0),
          p1 = path1.getPointAtLength(t * n1);
      return d3.interpolate([p0.x, p0.y], [p1.x, p1.y]);
    });

    return function(t) {
      return t < 1 ? "M" + points.map(function(p) { return p(t); }).join("L") : d1;
    };
  };
}

К сожалению, он также не работает на мобильных устройствах Chrome, где http://bl.ocks.org/mbostock/3081153 работает нормально.

Следующий шаг — применить этот эффект к предложениям.


person chris loughnane    schedule 09.05.2013    source источник
comment
Хм интересная задачка. Похоже, нужен лучший алгоритм для сопоставления точек p0 и p1 при интерполяции. Возможно, вы захотите попробовать Гейла-Шепли, чтобы сопоставить точки на основе евклидова расстояния. Я думаю, что лучшим алгоритмом будет тот, который отдает приоритет интерполяции между двумя точками, которая не вызывает никаких пересечений. Хотя не уверен, как это сделать.   -  person Ben Rudolph    schedule 09.02.2014


Ответы (1)


Разница между вашим примером и примером Бостока заключается в том, что в его примере есть один непрерывный путь, который он превращает в другой одиночный непрерывный путь.

Принимая во внимание, что в вашем примере такие цифры, как 1, 2, 3, 5, 6, 7, можно рисовать с использованием одного непрерывного пути. Но чтобы нарисовать такие цифры, как 4, 6, 9 и 0, вам нужно 2 пути - один поверх другого. И для цифры 8 вам нужно иметь 2 пути поверх внешнего пути.

Итак, я предлагаю всегда держать 2 пути поверх внешнего пути, который вы используете в настоящее время, и придавать им соответствующие размеры всякий раз, когда должна отображаться какая-либо особенная цифра.

Обратитесь к изображению для получения более подробной информации: введите описание изображения здесь

person Vikram Deshmukh    schedule 25.03.2014