如何添加条件转换?

问题描述 投票:1回答:1

此问题与d3.js的转换有关,例如矩形的x1属性的更改。

如果您希望立即进行更改,则可以将delay = duration = 0设置为

svg.selectAll("rect")
   .transition()
   .delay(delay)
   .duration(duration)
   .attr("x1", 0)

但是这可能太昂贵了(假设转换比立即更改要消耗更多的CPU资源)。因此,我该如何有条件地添加过渡,例如

if (delay == 0 && duration == 0) {
    svg.selectAll("rect")
        .attr("x1", 0)
} else {
    svg.selectAll("rect")
        .transition()
        .delay(delay)
        .duration(duration)
        .attr("x1", 0)
}

但是冗余度更低,结构更紧凑,有点像x = condition ? 0 : 1

javascript animation d3.js svg
1个回答
0
投票

这是一个非常奇怪的情况,我无法考虑这种情况会有用的情况。即使这样,这也是许多可能的解决方案之一:扩展D3选择原型。

在我的方法中,我们将扩展原型以在delayduration都为零的情况下返回完全相同的选择,或者如果不为[],则返回transition选择:

d3.selection.prototype.conditionalTransition =
  function(cond1, cond2) {
    return cond1 && cond2 ? this.transition().duration(duration).delay(delay) : this;
  };

然后,您只需继续attr()方法链。顺便说一下,<rect>没有x1属性,只有x

这里是第一个演示。所有的rects都在x = 10中。该选择变为转换选择:

d3.selection.prototype.conditionalTransition =
  function(cond1, cond2) {
    return cond1 && cond2 ? this.transition().duration(duration).delay(delay) : this;
  };

const rect = d3.selectAll("rect");

const delay = 100,
  duration = 1000;

rect.conditionalTransition(delay, duration)
  .attr("x", 200)

function transitioning(sel) {
  return sel.transition()
    .delay(delay)
    .duration(duration);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
 <rect x="10" y="10" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="40" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="70" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="100" width="50" height="20" fill="teal"></rect>
</svg>

这是相同的代码,delayduration都等于零。您可以看到矩形立即移动:

d3.selection.prototype.conditionalTransition =
  function(cond1, cond2) {
    return cond1 && cond2 ? this.transition().duration(duration).delay(delay) : this;
  };

const rect = d3.selectAll("rect");

const delay = 0,
  duration = 0;

rect.conditionalTransition(delay, duration)
  .attr("x", 200)

function transitioning(sel) {
  return sel.transition()
    .delay(delay)
    .duration(duration);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
 <rect x="10" y="10" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="40" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="70" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="100" width="50" height="20" fill="teal"></rect>
</svg>
© www.soinside.com 2019 - 2024. All rights reserved.