我正在尝试沿着螺旋曲线创建一个简单的平面动画
但是,我在尝试使用d3的延迟功能延迟转换时遇到问题,动画似乎没有正确显示
所以我一直在考虑使用setTimeout来延迟触发转换函数,但似乎无法正确。有人可以给我一个建议吗?
Link to the fiddle。这包括没有setTimeout或任何.delay的原始转换; v15显示使用.delay的错误;和v16有我尝试过的setTimeout
这是我没有setTimeout进行转换的代码(没有.delay工作正常)
function transitionThis(d,i) {
d3.select(this).transition()
.duration(3000)
//.delay(3000) //causes error in the animation
.ease("exp")
.each("start", function() { d3.select(this).style("opacity", "1"); })
.attrTween("transform", translateAlong(path.node()))
.styleTween("opacity", function () {return d3.interpolate("1", "0");});}
plane.each(transitionThis);
// Returns an attrTween for translating along the specified path element.
function translateAlong(path) {
var l = path.getTotalLength();
var t0 = 0;
return function(i) {
return function(t) {
var p0 = path.getPointAtLength(t0 * l);//previous point
var p = path.getPointAtLength(t * l);////current point
var angle = Math.atan2(p.y - p0.y, p.x - p0.x) * 180 / Math.PI;//angle for tangent
t0 = t;
return "translate(" + p.x + "," + p.y + ")scale(" + (0.2+t*4) + ")rotate(" + angle +"15"+")";
};
};
}
这是我尝试添加setTimeout
function transitionThis(d,i) {
d3.select(this).transition()
.duration(3000)
//.delay(3000) //causes error in the animation
.ease("exp")
.each("start", function() { d3.select(this).style("opacity", "1"); })
.attrTween("transform", translateAlong(path.node()))
.styleTween("opacity", function () {return d3.interpolate("1", "0");});
}
function delayedFlight() {
var tOut = setTimeout(transitionThis(),3000);
}
plane.each(delayedFlight);
答案 0 :(得分:2)
以下是正在发生的事情:由于某种原因,将.delay()
添加到过渡使得每隔一段时间插值函数(返回变换值的函数)连续两次被调用t
的值相同。例如,这是我插入console.log(t)
时得到的输出的子集:
0.006692062648206693
0.006707542472169953
0.007238969233518517
0.007255714140926161
0.0077049430038543705
0.0077049430038543705 // <- same as previous
0.008568945153864268
0.008588766510821856
0.00899496468906235
0.00899496468906235 // <- same as previous
0.009529833123126597
0.00955187716946928
0.01107410052517391
0.011099716711945125
0.012516716837337842
我不是为什么会这样,但从技术上讲,这不是一个错误,只是一个怪癖。但是,它会导致插值函数出现一种错误:当t0
和t
相等时,p0
和p
也是如此,因此计算出{{1}对于那些间歇性的情况,这是0。当你看到飞机口吃时 - 只要它的旋转设置为0。
最简单的解决方法是使angle
和t0
永远不相等,这可以通过拦截该条件并稍微修改t
来实现。像这样:
t0
它不是那么漂亮,但可能仍然比进入setTimeouts更好....