【问题标题】:How to correctly access the transform of an SVG element during d3.transition [duplicate]如何在 d3.transition 期间正确访问 SVG 元素的转换 [重复]
【发布时间】:2020-07-06 21:08:57
【问题描述】:

我正在使用 d3.transitions 处理 d3 动画,例如圆圈。

假设有以下圆形动画(d3.transition()):

animationTime = 500;
svg = d3.select('#svg');                      // Select the SVG by its id previously added to the DOM
circle = d3.select('#circleid')               // Select a circle by its id from the SVG
           .transform('translate(0,0)');      // Set position of that circle to origin

circle.transition().duration(animationTime)   // Start an animation with transition time of 0.5 sec
      .transform('translate(500,500)');       // Animate position of circle to new position (500, 500)

console.log(circle.attr('transform'));    // --> Output: 'translate(50,50)'
setTimeout(() => { 
   console.log(circle.attr('transform')); // --> Output: 'translate(500,500)'
}, animationTime + 50);                   // without +50 the animation is not completely finished, yet

我目前的解决方案是引入地图或元素属性来保存最终位置并访问该SVGElement属性而不是transform,这使得这种定位方式的管理更加复杂。见这里:

animationTime = 500;
svg = d3.select('#svg');                      
circle = d3.select('#circleid')               
           .transform('translate(0,0)');      

circle.attr('final-x', 500).attr('final-y', 500)   // Save final position as separate attribute
      .transition().duration(animationTime)   
      .transform('translate(500,500)');       

console.log(circle.attr('final-x'), circle.attr('final-y'));  // Output --> 500 500

这里的值是正确的,但需要附加属性ON EACH ELEMENT

因此,我认为这不是一个合适的解决方案...

解决此问题的标准 d3 方法是什么? 有没有办法在不需要额外的属性/数据结构的情况下访问元素的最终转换状态?我不想不必要地用垃圾填充 DOM。

关于如何以一种好的方式做到这一点的任何想法?

编辑:我不能使用转换的 .end() 函数,因为我已经需要访问转换,并且已经转换完成之前。 p>

【问题讨论】:

  • this 回答你的问题了吗?
  • 请展示如何在代码示例中管理多个元素。
  • @Kaiido 这正是我想要的!谢谢你。没有必要有多个元素,因为问题已经存在于一个圆圈中。我认为没有必要在这里解释我需要这个的原因吗?我猜会很冗长。

标签: javascript animation d3.js transition


【解决方案1】:

可以将transition.end event listener 添加到代码中,并提供转换结束时的值。

在下面的 sn-p 中演示。

animationTime = 500;
circle = d3.select('#circleid')               // Select a circle by its id from the SVG
           .attr('transform', 'translate(0,0)');      // Set position of that circle to origin

let t = circle.transition().duration(animationTime)   // Start an animation with transition time of 0.5 sec
      .attr('transform', 'translate(500,500)')       // Animate position of circle to new position (500, 500)

t.on('end', function() {
    console.log(circle.attr('transform'))
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="800" height="600" viewbox = "0 0 1000 1000">
  <circle id ="circleid" cx ="20" cy="20" r="15" fill="blue"></circle>
</svg>

【讨论】:

  • 感谢提示,问题是,我需要在转换完成之前访问该位置,否则,结束函数就足够了,这是真的。我忘了在问题中提到这一点
  • 好的,那么请更新问题以包含minimal, reproducible example。否则我们将提出的解决方案可能与您的情况不匹配。
猜你喜欢
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-25
  • 2012-08-08
  • 2019-07-07
相关资源
最近更新 更多