Collision/overlap detection of circles in a d3 transition
collision-detection, d3.js, javascript, svg, transition
Solution
You can detect collision in your tween function. Define a `collide` function to be called from inside the tween function as follows:
function collide(node){
var trans = d3.transform(d3.select(node).attr("transform")).translate,
x1 = trans[0],
x2 = trans[0] + (+d3.select(node).attr("r")),
y1 = trans[1],
y2 = trans[1] + (+d3.select(node).attr("r"));
var colliding = false;
points.each(function(d,i){
var ntrans = d3.transform(d3.select(this).attr("transform")).translate,
nx1 = ntrans[0],
nx2 = ntrans[0] + (+d3.select(this).attr("r")),
ny1 = ntrans[1],
ny2 = ntrans[1] + (+d3.select(this).attr("r"));
if(!(x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1))
colliding=true;
})
return colliding;
}
Where `points` are the stationary points, and `node` is the transitioning element. What `collide` does is check whether `node` overlaps with any of the points (as shown in collision detection example here).
Because we need the `node` to be passed to the tween function, we replace `attrTween` used in Mike's example, with `tween`:
circle.transition()
.duration(10000)
.tween("attr", translateAlong(path.node()))
.each("end", transition);
Finally, the tween function calling our `collide`:
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
d3.select(this).attr("transform","translate(" + p.x + "," + p.y + ")");
if(collide(this))
d3.select(this).style("fill", "red")
else
d3.select(this).style("fill", "steelblue")
};
};
}
See the full demo here
Problem
I'm using d3 to animate a route (path) on a map. When the route reaches a point along the route I'd like to popup some information. Most of my code is based on the following example. http://bl.ocks.org/mbostock/1705868. I'm really just trying to determine if there is a way to detect when the transitioning circle collides or overlaps any of the stationary circles in this example.