gpt4 book ai didi

javascript - 如何链接 d3 转换?

转载 作者:行者123 更新时间:2023-12-01 13:11:47 29 4
gpt4 key购买 nike

我有一组动画,当用户移动 slider 时会发生这些动画。 slider 的每个增量都会创建一个过渡。但是,只要用户非常快速地移动 slider (即他们增加 slider 的速度快于过渡可以完成的速度),过渡就会出现竞争条件,旧的会被打断,动画的“流动”很奇怪。我想要一个转换序列,并让它们始终按照它们被调用的顺序发生。 IE。直到最后一个完成,下一个才开始。 jsfiddle (按住“a”键 vs 慢慢按几次看区别)

var svg = d3.select("svg"),
margin = {top: 40, right: 40, bottom: 40, left: 40},
width = svg.attr("width") - margin.left - margin.right,
height = svg.attr("height") - margin.top - margin.bottom,

g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var y = d3.scalePoint()
.domain(d3.range(50))
.range([0, height]);

g.selectAll("circle")
.data(y.domain())
.enter().append("circle")
.attr("r", 25)
.attr("cx", 50)
.attr("cy", y);

var radius = 25;
function animate() {
radius = (radius+5)%50;
g.selectAll("circle")
.transition()
.duration(500)
.attr("r", radius);
}
document.addEventListener('keydown', e => e.code === "KeyA" ? animate() : 0);

最佳答案

您可以使用 .on("end", callback) 来监听动画的结束。由于您有 50 个动画对象,并且将为每个对象获取该事件,因此您需要一个计数器来了解最后一个对象何时完成。

要确保所有按键都产生动画,但只有在前一个按键完成后,您不能只对按键事件调用 animate()。而是跟踪必须执行多少次调用,并在触发关键事件时增加调用次数。仅在该计数器为零时调用 animate()

请注意,这种 animate() 调用的排队也可能会产生不自然的行为:动画可能会一直持续到最后一个关键事件之后很长时间。为了改善用户体验,您可以降低持续时间参数,以便在仍有大量关键事件需要相应调用 animate() 处理时加快动画速度。

以下是如何调整您的代码来完成所有这些工作:

var svg = d3.select("svg"),
margin = {top: 40, right: 40, bottom: 40, left: 40},
width = svg.attr("width") - margin.left - margin.right,
height = svg.attr("height") - margin.top - margin.bottom,

g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Use a variable for the number of items:
var size = 50;
var y = d3.scalePoint()
.domain(d3.range(size)) // <--- use that variable
.range([0, height]);

g.selectAll("circle")
.data(y.domain())
.enter().append("circle")
.attr("r", 25)
.attr("cx", 50)
.attr("cy", y);

var radius = 25;
var count = 0; // <--- the number of queued calls of animate
function animate() {
let i = size; // <-- the number of items that will be animating
console.log("anim");
radius = (radius+5)%50;
g.selectAll("circle")
.transition()
.duration(500 / count) // <--- reduce the duration when count is high
.attr("r", radius)
.on("end", () => {
i--;
// when all objects stopped animating and more animate() calls needed:
if (i === 0 && --count > 0) animate(); // on to the next...
});
}
document.addEventListener('keydown', e =>
// only call animate when no animation is currently ongoing, else increment
e.code === "KeyA" ? count++ || animate() : 0
);

关于javascript - 如何链接 d3 转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59513673/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com