Javascript D3 V4-画布转换:D3.4计时器持续时间
我遵循了关于画布元素的转换。 因为我使用的是d3版本4.2.2,所以我尝试移植这个示例,但没有成功。 问题在于(取决于Javascript D3 V4-画布转换:D3.4计时器持续时间,javascript,animation,html5-canvas,d3.js,Javascript,Animation,Html5 Canvas,D3.js,我遵循了关于画布元素的转换。 因为我使用的是d3版本4.2.2,所以我尝试移植这个示例,但没有成功。 问题在于(取决于d3.timer持续时间),动画会在点不在其正确位置的点停止。它可以与D3V3配合使用。以下是代码的一部分: var duration = 1000; var delay = function(d) { return d.i; } var maxDelay = 0; var timeScale = d3.scaleLinear() .domain([0, duration
d3.timer
持续时间),动画会在点不在其正确位置的点停止。它可以与D3V3配合使用。以下是代码的一部分:
var duration = 1000;
var delay = function(d) {
return d.i;
}
var maxDelay = 0;
var timeScale = d3.scaleLinear()
.domain([0, duration])
.range([0, 1]);
data.forEach(function(d) {
d.trans = {
i: d3.interpolateNumber(height, d.y),
delay: delay(d)
};
if (d.trans.delay > maxDelay) {
maxDelay = d.trans.delay;
}
});
var renderTime = 0;
var timer = d3.timer(moveCircles);
function moveCircles(t) {
data.forEach(function(d) {
var time = timeScale(t - d.trans.delay);
d.y = d.trans.i(time);
});
var start = new Date();
drawCircles('black');
var end = new Date();
renderTime += (end - start);
if (t >= duration + maxDelay) {
console.log('Render time:', renderTime);
timer.stop();
return true;
}
}
举个完整的例子。红点表示数据的正确位置(x/y)。因此,每个黑点都应该与一个红点重叠。点的y值越高,到其正确位置的距离就越大。这导致我假设y值的插值存在错误
是否有办法设置持续时间(如1000)并设置点s.t.的动画。在指定的持续时间后,每个点都位于其正确的位置
EDIT:结果表明,使用与所提供示例相同的easeCubicInOut
效果很好。我不知道为什么会这样
var ease = d3.easeCubicInOut;
...
function moveCircles(t) {
data.forEach(function(d) {
//var time = timeScale(t - d.trans.delay); // without the ease it won't work
var time = ease(timeScale(t - d.trans.delay));
d.y = d.trans.i(time);
});
...
我怎么能跳过这个问题呢?这不是一个直接的答案,因为我没有完成所有的计算,但这里的数学有点问题:
var time = timeScale(t - d.trans.delay);
d.y = d.trans.i(time);
t-d.trans.delay
需要生成一个介于0和1000之间的值,以便它在0到1之间进行缩放。显然,您正在输入大于1的插值
函数值。我相信:
if (t >= duration + maxDelay) {
是罪魁祸首,因为您将在1000毫秒后运行动画
一种幼稚的做法是将其封顶:
var time = timeScale(t - d.trans.delay);
if (time > 1) time = 1;
d.y = d.trans.i(time);
也就是说,我不确定这段代码是否需要如此复杂。一个基本的学生应该能够做你想要做的事情:
d3.select({})
.transition()
.duration(duration)
.tween("animate.circles", function() {
return function(t) {
data.forEach(function(d,i){
d.y = d.trans.i(t);
});
drawCircles('black');
};
});
更新。非常感谢您的努力。我真的很讨厌你,你的小玩意儿太棒了!问题在于,afaik转换在数据点的数量上是不可伸缩的(或者有解决方法吗?),这基本上是我使用画布而不是svg的意图之一。例如,如果更改
size=10000
,则过渡不再平滑。