我正在尝试创建一个动画,其中圆圈在多个路径上进行动画处理。
我能够为其中一条路径获取我想要的动画,但我不确定为什么圆圈只是在该特定路径上制作动画,而不是根据它们所属的路径进行分配。
完整的代码可以在我的bl.ocks页面找到:https://bl.ocks.org/JulienAssouline/4a11b54fc68c3255a85b31f34e171649
这是它的主要部分
var path = svg.selectAll("path")
.data(data.filter(function(d){
return d.From > 2010
}))
.enter()
.append("path")
.style("stroke", "#832129")
.attr("class", "arc")
.attr("d", function(d){
var To_scale = xScale(d.experience),
From_scale = xScale(0),
y = yScale(0),
dx = To_scale - From_scale,
dy = y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + From_scale + " " + y + " A 43 50 0 0 1 " + To_scale + " " + y;
})
.style("fill", "none")
.style("opacity", 0)
.call(transition)
.on("mouseover", function(d){
var thisClass = d3.select(this).attr("class")
d3.selectAll(".path").style("opacity", 0.1)
d3.select(this).style("stroke", "white").style("opacity", 1).style("stroke-width", 2)
})
.on("mouseout", function(d){
d3.select(this).style("stroke", "#832129").style("opacity", 1)
})
function transition(path){
path.each(function(PathItem, index){
d3.select(this).transition()
// .delay(index + 200)
.duration(index * 5 + 1000)
.on("start", function(){
d3.select(this).style("opacity", 1)
})
.attrTween("stroke-dasharray", tweenDash)
})
}
function tweenDash(){
var l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l)
return function(t){ return i(t); };
}
console.log(data[0])
var circle = svg.selectAll("circle")
.data(data.filter(function(d){
return d.From > 2010
}))
.enter()
.append("circle")
.attr("r", 5)
.attr("cx", function(d){
return xScale(d.experience)
})
.style("fill", "red")
.attr("transform", "translate(" + 0 + ")")
.style("opacity", 0)
transition_circles();
function transition_circles(){
circle.each(function(pathItem, index){
d3.select(this)
.transition()
.delay(index * 200)
.duration(index * 10 + 1000)
.on("start", function(){
d3.select(this).style("opacity", 1)
})
.on("end",function(){
d3.select(this).style("opacity", 0)
})
.attrTween("transform", translateAlong(path.node(), index))
})
}
function translateAlong(path, index){
var l = path.getTotalLength();
return function(d, i , a){
return function(t){
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
}
}
}
基本上,我遵循这个https://bl.ocks.org/mbostock/1705868示例来获得逐点插值,但是我很难适应它以在多行上获得相同的效果。
我也尝试将.attr("cx", function(d){ return d.experience}
添加到圈子中,但这不起作用。
答案 0 :(得分:1)
您始终将相同的路径(第一个路径)传递给translateAlong
功能:
.attrTween("transform", translateAlong(path.node(), index))
//this is always the first path ---------^
您必须将不同的路径传递给translateAlong
函数。有不同的方法(我不知道你想要哪一个),其中一个是:
.attrTween("transform", translateAlong(path.nodes()[index], index))
在这种方法中,圆的索引从0到数据数组长度减去1.因此,由于path.nodes()
是一个元素数组,所以它们通过它们的索引选择不同的元素。 / p>
以下是更新的bl.ocks:https://bl.ocks.org/anonymous/f54345ed04e1a66b7cff3ebeef271428/76fc9fbaeed5dfa867fdd57b24c6451346852568
PS:关于优化,您不需要在同一位置绘制多条路径!现在你有几十条完全相同的路径。只绘制不同的路径(在您的情况下,只有3个)。