D3.js中的中断滚动过渡

时间:2019-04-09 19:50:15

标签: d3.js scroll

我正在使用scrollama javascript库编写一篇“草稿”文章,其中涉及在用户滚动时将D3图形从视图中移入和移出。它通常可以正常工作,但是如果我滚动得太快,则图形会相互叠放。

Here is a jsfiddle基于此example by the scrollama author。在我的示例中,彩色圆点应该一次消失一次。如果要快速滚动到末尾,则不应出现间歇点。以下代码片段显示了我如何设置转换:

我定义了一些创建“图形”的函数,然后调用它们。

var makeCircle0 = function(){

  g.append("circle")
    .attr("cx", 50)
    .attr("cy", 100)
    .attr("r", 20)
    .attr("fill", "red")
    .attr("class", "redcircle")

  g.selectAll(".redcircle")
    .attr("opacity", 0)
}

makeCircle0();

// Do this for makeCircle1, 2, and 3, also. 

然后,我制作一些函数来处理过渡。这个说要使红色圆圈淡入,并将其他圆圈设为0不透明。我对所有圈子/阶段都这样做。

var showCircle0 = function(){

  g.selectAll(".redcircle")
  .transition()
  .duration(1000)
  .attr("opacity", 1)

  g.selectAll(".yellowcircle").attr("opacity", 0)
  g.selectAll(".greencircle").attr("opacity", 0)
  g.selectAll(".bluecircle").attr("opacity", 0)

}

本节创建了一系列转换函数,以便在滚动时可以在页面的特定步骤调用它们。这类似于Jim Vallandingham handled his scroller

var activateFunctions = [];
activateFunctions[0] = showCircle0;
activateFunctions[1] = showCircle1;
activateFunctions[2] = showCircle2;
activateFunctions[3] = showCircle3;

最后,这将在页面的正确步骤调用所需的功能。它的作用是……但并非没有停止在上一步中触发的其他转换,导致在各个阶段出现多个点。

function handleStepEnter(response) {
  step.classed('is-active', function (d, i) {
    return i === response.index;
  })

  figure.call(activateFunctions[response.index])
}

如何防止这种情况?

1 个答案:

答案 0 :(得分:4)

如果您需要中断转换,则d3-transition有一个用于此的方法:

selection.interrupt();

这将取消所选内容的过渡。 如果使用命名转换,则可以通过提供带有一个参数的中断来指定名称,该参数指示要取消的转换的名称。


如果这是函数的通用版本以显示元素:

function show() {
  selectionToHide.attr("opacity",0);

  selectionToShow.transition()
     .attr("opacity",1);
}

在不使用selection.interrupt的情况下,将不透明度设置为零,然后任何进行中的过渡的下一个刻度将继续更新不透明度并完成过渡。通过添加中断,我们避免了这种情况。这是更新后的fiddle

但是,还有另一种解决方案-我们可以对不想显示的元素应用另一个过渡。为此,我们只需用新的过渡替换过渡即可:

function show() {
  selectionToHide.transition()
     .attr("opacity",0);

  selectionToShow.transition()
     .attr("opacity",1);
}

这将替换现有的未命名过渡(因为您的未命名过渡)并淡出元素,而不是一次全部隐藏它们。这是其中的fiddle当然,如果您有很多元素,可以将其优化为仅对任何正在过渡的元素(而不是已隐藏的元素)应用过渡,以减少活动过渡的数量。

我没有碰过滚动,显示的圆圈的索引应该与显示的数字匹配,但是似乎数字并不总是与滚动位置匹配,但这是一个单独的问题