使用 D3 (v5) 应用多个转换

Applying multiple transitions using D3 (v5)

我正在尝试创建一个动画,它会淡出列表中的文本,然后在您单击标题时折叠列表。在 fiddle 我有 here,有几个问题。

d3.select('.panel-heading')
  .on('click',()=>{
    let p = d3.select('.panel-collapse');
    p.transition()
      .duration(300)
      .style('opacity', '0');
    p.transition()
      .delay(300)
      .duration(300)
      .ease(d3.easeLinear)
      .style('height','0px');
    p.transition()
      .delay(600)      
      .duration(300)
      .style('display','none');

    p.transition()
      .delay(3000)
      .duration(10)
      .style('display','block');
    p.transition()
      .delay(3010)
      .duration(600)
      .ease(d3.easeLinear)
      //.style('display','block')
      .style('height','auto');
    p.transition()
      .delay(3610)
      .duration(3000)
      .style('opacity','1');
  });
  1. 第一次单击标题时,列表淡出并且列表高度降低,如我所料。但是,随后的点击列表高度并没有慢慢缩小。它只是弹出到 0。
  2. 当列表再次展开时,它会弹出到全高(无论点击次数如何)在整个过渡期间不会展开。

如何让列表一致地扩展和收缩?

您首先必须在折叠面板之前捕获面板的高度,以便在恢复中使用它。

链接动画而不使用预先计算的延迟。

d3.select('.panel-heading')
  .on('click',()=>{
    let p = d3.select('.panel-collapse');
    let height = p.node().clientHeight;
    p.transition()
      .duration(300)
      .style('opacity', '0')
      .transition()
      .duration(300)
      .ease(d3.easeLinear)
      .style('height','0px')
      .transition()
      .duration(10)
      .style('display','none')
      .transition()
      .delay(3000)
      .duration(10)
      .style('display','block')
      .transition()
      .duration(600)
      .ease(d3.easeLinear)
      //.style('display','block')
      .style('height', ''+height+'px')
      .transition()
      .duration(3000)
      .style('opacity','1');
  });
  
<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />

<div class="panel panel-default">
  <div class="panel-heading" role="button">
    Hello World
  </div>
  <div class="panel-collapse">
    <div> item1 </div>
    <div> item1 </div>
    <div> item1 </div>
    <div> item1 </div>
    <div> item1 </div>
  </div>
</div>