使用 D3 我想检测我的动画线何时改变方向(或到达一个点),并在恰好时间点附加一个圆圈。因此,一个圆圈将一次附加,而不是所有圆圈,这就是当前正在发生的事情。
var points = [
[480, 200],
[580, 400],
[680, 100],
[780, 300],
[180, 300],
[280, 100],
[380, 400]
];
var path = svg.append("path")
.data([points])
.attr("d", d3.svg.line()
.tension(0) ); //); // Catmull–Rom
//.interpolate("cardinal-closed"));
var totalLength = path.node().getTotalLength();
path
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(10000)
.ease("linear")
.attr("stroke-dashoffset", 0);
svg.selectAll(".point", function(d,i){
console.log(d,i)
})
.data(points)
.enter().append("circle")
.transition()
.duration(2000)
.ease("linear")
.style("fill", "url(#image)")
.attr("r", 20)
.attr("transform", function(d) { return "translate(" + d + ")"; })
我尝试测量最后一个 x 和 y 与之前的 x 和 y 的对比,但如果它们都继续沿正方向或负方向移动,则不容易发现差异。我还需要测量斜率变化。我希望有更聪明的方法?
我尝试测量以查看 newX 和 oldX 之间的差异是否保持不变,但它不起作用 :( https://jsfiddle.net/hs5a9z5a/3/
最佳答案
要知道线条何时改变方向(即击中数据点),您需要控制 stroke-dashoffset
上的转换功能。这就是我的做法(我试着很好地评论它,如果您有任何问题,请告诉我):
path
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(10000)
.ease("linear")
.tween("myTween", function() {
var i = d3.interpolate(totalLength, 0);
var self = d3.select(this);
return function(t) {
// current position of stroke-dashoffset
var len = i(t),
// current position with respect to line length of stroke-dashoffset
per = (1 - len / totalLength) * totalLength,
// pixel position of stroke-dashoffset
p = self.node().getPointAtLength(per);
// loop our points and look for hit detection
points.forEach(function(d) {
// are we one a point?
if (Math.abs(p.x - d[0]) < 1 && Math.abs(p.y - d[1]) < 1) {
console.log("point hit");
}
});
// apply stroke-dashoffset
self.attr("stroke-dashoffset", len);
};
});
运行示例:
var points = [
[480, 200],
[580, 400],
[680, 100],
[780, 300],
[180, 300],
[280, 100],
[380, 400]
];
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500);
var path = svg.append("path")
.data([points])
.attr("d", d3.svg.line()
.tension(0)); //); // Catmull–Rom
//.interpolate("cardinal-closed"));
var totalLength = path.node().getTotalLength();
path
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(10000)
.ease("linear")
.tween("myTween", function() {
var i = d3.interpolate(totalLength, 0);
var self = d3.select(this);
return function(t) {
var len = i(t),
per = (1 - len / totalLength) * totalLength,
p = self.node().getPointAtLength(per);
points.forEach(function(d) {
if (Math.abs(p.x - d[0]) < 1 && Math.abs(p.y - d[1]) < 1) {
console.log("point hit");
}
});
self.attr("stroke-dashoffset", i(t));
};
});
/*
svg.selectAll(".point", function(d,i){
//console.log(d,i)
})
.data(points)
.enter().append("circle")
.transition()
.duration(2000)
.ease("linear")
.style("fill", "url(#image)")
.attr("r", 20)
.attr("transform", function(d) { return "translate(" + d + ")"; })
var circle = svg.append("circle")
.attr("r", 13)
.attr("transform", "translate(" + points[0] + ")");
transition();
function transition() {
circle.transition()
.duration(10000)
.attrTween("transform", translateAlong(path.node()))
//.each("end", transition);
.each("end");
}
// Returns an attrTween for translating along the specified path element.
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
*/
path {
fill: none;
stroke: #000;
stroke-width: 3px;
}
circle {
fill: url('http://www.e-pint.com/epint.jpg');
fill: steelblue;
/stroke: #fff;
//stroke-width: 3px;
}
<script src="http://d3js.org/d3.v3.js"></script>
<svg id="mySvg" width="80" height="80">
<defs id="mdef">
<pattern id="image" x="0" y="0" height="40" width="40">
<image x="0" y="0" width="40" height="40" xlink:href="http://www.e-pint.com/epint.jpg"></image>
</pattern>
</defs>
</svg>
<div id="line"></div>
关于javascript - 使用 D3.js,如何检测何时到达动画线上的点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40937535/