链接D3.js过渡的区别

时间:2019-11-28 18:16:12

标签: javascript d3.js svg transition

绿色圆圈的第二个过渡行为类似于蓝色圆圈的第二个过渡需要做什么?

我希望两个圆的过渡行为相同。但是,似乎可以应用绿色圆圈的第一个过渡代替第二个过渡。

const svg = d3.select("svg");

const blueCircle = svg.append("circle")
  .attr("cx", 10)
  .attr("cy", 10)
  .attr("r", 5)
  .style("fill", "blue");

const greenCircle = svg.append("circle")
  .attr("cx", 10)
  .attr("cy", 30)
  .attr("r", 5)
  .style("fill", "green");

blueCircle
  .transition()
    .duration(4000)
    .ease(d3.easeLinear)
    .attr("cx", 100)
  .transition()
    .duration(2000)
    .ease(d3.easeElastic)
    .attr("cx", 200);

const firstTransition = d3.transition()
  .duration(4000)
  .ease(d3.easeLinear);

const secondTransition = d3.transition()
  .duration(2000)
  .ease(d3.easeElastic);

greenCircle
  .transition(firstTransition)
    .attr("cx", 100)
  .transition(secondTransition)
    .attr("cx", 200);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.14.2/d3.min.js"></script>
<svg width="250" height="50"></svg>

更新

由于Coola's answerthis question,我发现可以使绿色圆圈的第二个过渡按预期工作:

const greenCircle = svg.append("circle")
  .attr("class", "green")
  .attr("cx", 10)
  .attr("cy", 30)
  .attr("r", 5)
  .style("fill", "green");

const firstTransition = d3.transition()
  .duration(4000)
  .ease(d3.easeLinear);

const secondTransition = firstTransition.transition()
  .duration(2000)
  .ease(d3.easeElastic);

firstTransition
  .select("circle.green")
  .attr("cx", 100);

secondTransition
  .select("circle.green")
  .attr("cx", 200); 

但是,此代码仍然存在以下缺陷:

  • 转换不是独立的,因此不能以不同的顺序重用。
  • 您不能将已选择的元素(即greenCircle)插入转换的select方法中(这会导致“无法对'Element'执行'querySelector':'[object Object]'不是有效的选择器”。 “例外)。
  • 未使用D3.js的典型方法链接概念。

有人知道没有这些问题的解决方案吗,尤其是对于第一点?

1 个答案:

答案 0 :(得分:1)

要链接转换,您必须使用on("end", function(){<do something>})

您可以在documentation中了解有关高级控制流的更多信息。

greenCircle
  .transition(firstTransition)
    .attr("cx", 100)
    .on("end", () => {
      greenCircle.transition(secondTransition)
      .attr("cx", 200);
    });

完整摘要:

const svg = d3.select("svg");

const blueCircle = svg.append("circle")
  .attr("cx", 10)
  .attr("cy", 10)
  .attr("r", 5)
  .style("fill", "blue");

const greenCircle = svg.append("circle")
  .attr("cx", 10)
  .attr("cy", 30)
  .attr("r", 5)
  .style("fill", "green");

blueCircle
  .transition()
    .duration(4000)
    .ease(d3.easeLinear)
    .attr("cx", 100)
  .transition()
    .duration(2000)
    .ease(d3.easeElastic)
    .attr("cx", 200);

const firstTransition = d3.transition()
  .duration(4000)
  .ease(d3.easeLinear);

const secondTransition = d3.transition()
  .duration(2000)
  .ease(d3.easeElastic);

greenCircle
  .transition(firstTransition)
    .attr("cx", 100)
    .on("end", () => {
      greenCircle.transition(secondTransition)
      .attr("cx", 200);
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.14.2/d3.min.js"></script>
<svg width="250" height="50"></svg>

更新:

以上代码仅解决了部分问题。您会注意到蓝色和绿色圆圈之间的动画并不完全相同。

您还需要将firstTransition链接到secondTransition const中。喜欢:

const secondTransition = firstTransition.transition()
  .duration(2000)
  .ease(d3.easeElastic);

完整摘要:

const svg = d3.select("svg");

const blueCircle = svg.append("circle")
  .attr("cx", 10)
  .attr("cy", 10)
  .attr("r", 5)
  .style("fill", "blue");

const greenCircle = svg.append("circle")
  .attr("cx", 10)
  .attr("cy", 30)
  .attr("r", 5)
  .style("fill", "green");

blueCircle
  .transition()
    .duration(4000)
    .ease(d3.easeLinear)
    .attr("cx", 100)
  .transition()
    .duration(2000)
    .ease(d3.easeElastic)
    .attr("cx", 200);

const firstTransition = d3.transition()
  .duration(4000)
  .ease(d3.easeLinear);

const secondTransition = firstTransition.transition()
  .duration(2000)
  .ease(d3.easeElastic);

greenCircle
  .transition(firstTransition)
    .attr("cx", 100)
    .on("end", function () {
      greenCircle.transition(secondTransition)
      .attr("cx", 200);
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.14.2/d3.min.js"></script>
<svg width="250" height="50"></svg>