Вопрос:

Путь к клипу для анимированной линии и круга в d3 js

animation d3.js line geometry clip-path

818 просмотра

1 ответ

43 Репутация автора

Как обрезать анимированную линию и окружность вместе с путем?

В этом примере я также попытался обрезать круг и точки.

Я добавил следующий код:

svg.append("defs")
            .append("clipPath")
            .attr("id", "clip")
            .append("rect")
            .attr("width", 960/2)
            .attr("height", 500/2);

И добавил следующую часть, где определены круг и путь

.attr('clip-path', 'url(#clip)')

Отсечение работает нормально для пути, но оно работает по-разному для круга и линии.

Demo1 и Demo2 здесь.

Как я могу добавить путь клипа, чтобы он показывал круг и линию только в видимой / обрезанной части пути?

NB Необходимо применить отсечение для нескольких кругов и линий, движущихся по нескольким путям.

Автор: Shaila Zaman Источник Размещён: 08.11.2017 10:32

Ответы (1)


3 плюса

21875 Репутация автора

Решение

Это потому, что вы используете преобразование на круге: путь клипа круга также трансформируется, что означает, что он относительно круга. По мере движения круга путь клипа меняется. И поскольку круг центрируется в 0,0 относительно его преобразования (преобразование изменяется при перемещении круга, а не атрибутов центрирования), путь обрезки разрезает его на четверть круга (так как он также проходит через 0,0).

Одним из решений является использование атрибутов cx и cy для позиционирования окружностей. Более быстрый вариант - добавить путь, линию, окружность и точки к a gи обрезать g, обрезая все дочерние элементы в процессе:

var g = svg.append("g")
  .attr("clip-path", "url(#clip)")

var path = g.append("path")
    .data([points])
    .attr("d", d3.svg.line()
    .tension(0) // Catmull–Rom
    .interpolate("cardinal-closed"));

 g.selectAll(".point")
    .data(points)
  .enter()
    .append("circle")
    .attr("r", 4)
    .attr("transform", function(d) { return "translate(" + d + ")"; });

circle = g.append("circle")
    .attr("r", 13)
    .attr("transform", "translate(" + points[0] + ")");

line = g.append("line")
    .attr("y1", -50)
    .attr("y2", 50)
    .attr("class", "x-hover-line hover-line")
    .attr("transform", "translate(" + points[0] + ")");

Обновленный код:

var points = [
  [480, 200],
  [580, 400],
  [680, 100],
  [780, 300],
  [180, 300],
  [280, 100],
  [380, 400]
];

var svg = d3.select("body").append("svg")
    .attr("width", 960)
    .attr("height", 500);



svg.append("defs")
            .append("clipPath")
            .attr("id", "clip")
            .append("rect")
            .attr("width", 960/2)
            .attr("height", 500/2);
            
   

var g = svg.append("g")
  .attr("clip-path", "url(#clip)")
  
  
var path = g.append("path")
    .data([points])
    .attr("d", d3.svg.line()
    .tension(0) // Catmull–Rom
    .interpolate("cardinal-closed"));
  

g.selectAll(".point")
    .data(points)
  .enter()
    .append("circle")
    .attr("r", 4)
    .attr("transform", function(d) { return "translate(" + d + ")"; });

circle = g.append("circle")
    .attr("r", 13)
   
    .attr("transform", "translate(" + points[0] + ")");

line = g.append("line")
    .attr("y1", -50)
    .attr("y2", 50)
    .attr("class", "x-hover-line hover-line")
    .attr("transform", "translate(" + points[0] + ")");



transition();

function transition() {
  circle.transition()
      .duration(10000)
      .attrTween("transform", translateAlong(path.node()))
      .each("end", transition);

  line.transition()
      .duration(10000)
      .attrTween("transform", translateAlong(path.node()))
      .each("end", transition);
}

// Returns an attrTween for translating along the specified path element.
function translateAlong(path) {
  var l = path.getTotalLength();
  return function(d, i, a) {
    return function(t) {
      var p = path.getPointAtLength(t * l);
      return "translate(" + p.x + "," + p.y + ")";
    };
  };
}
path {
  fill: none;
  stroke: #000;
  stroke-width: 3px;
}

circle {
  fill: steelblue;
  stroke: #fff;
  stroke-width: 3px;
}

.hover-line {
    /*stroke: #6F257F;*/
    stroke: #140917;
    stroke-width: 2.5px;
    /*stroke-dasharray: 3,3;*/
}

.hover-text {
    font-size: 22px;
    font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"></script>

Или посмотрите обновленную скрипку .

Если вы не хотите обрезать один из них, вы можете добавить их как есть (или использовать другого родителя g). Посмотри на эту скрипку , линия будет видна везде.

Автор: Andrew Reid Размещён: 08.11.2017 11:21
Вопросы из категории :
32x32