Sim*_*lam 7 html javascript svg
我正在尝试使用一些html元素沿着SVG路径相互跟随.我希望他们在路径上保持相同的距离.我还希望SVG图像缩放到容纳它的容器.
我创建了一个codepen来演示我到目前为止所拥有的内容:http://codepen.io/mikes000/pen/GIJab
我遇到的问题是,当元素沿X轴移动时,它们似乎比它们在Y轴上的距离更远.
有没有办法让它们沿着线路行进时保持相同的距离?
谢谢!
更新**
经过一些进一步的摆弄后,我发现距离变化似乎是由于SVG视箱的纵横比增加了X大于Y.当沿X轴向下拉伸1px时,线可能变为3px屏幕.
红色正方形的位置是通过将它们前后移动黑盒宽度的一半来设定的.当沿着线行进时,如果视框宽高比被改变,则线上每个点之间的距离基于此增加或减少.
我尝试使用容器div大小的精确视图框创建一个类似的SVG,红点正好位于黑盒子的两端.这并没有解决问题,因为我希望SVG的线可以扩展到它放在里面的任何大小的容器.
我想如果有一种方法可以计算出黑盒子的大小相对于它覆盖的线下多少像素的多少像素,红点就会准确排列.
任何想法如何实现这个或任何想法更好的方法来解决这个问题?
var svg = d3.select("#line").append("svg:svg").attr("width", "100%").attr("height", "100%");
var data = d3.range(50).map(function(){return Math.random()*10})
var x = d3.scale.linear().domain([0, 10]).range([0, 700]);
var y = d3.scale.linear().domain([0, 10]).range([10, 290]);
var line = d3.svg.line()
.interpolate("cardinal")
.x(function(d,i) {return x(i);})
.y(function(d) {return y(d);})
var path = svg.append("svg:path").attr("d", line(data));
var circle =
svg.append("circle")
.attr("cx", 100)
.attr("cy", 350)
.attr("r", 3)
.attr("fill", "red");
var circleBehind =
svg.append("circle")
.attr("cx", 50)
.attr("cy", 300)
.attr("r", 3)
.attr("fill", "blue");
var circleAhead =
svg.append("circle")
.attr("cx", 125)
.attr("cy", 375)
.attr("r", 3)
.attr("fill", "green");
var pathEl = path.node();
var pathLength = pathEl.getTotalLength();
var BBox = pathEl.getBBox();
var scale = pathLength/BBox.width;
var offsetLeft = document.getElementById("line").offsetLeft;
var randomizeButton = d3.select("button");
svg.on("mousemove", function() {
var x = d3.event.pageX - offsetLeft;
var beginning = x, end = pathLength, target;
while (true) {
target = Math.floor((beginning + end) / 2);
pos = pathEl.getPointAtLength(target);
if ((target === end || target === beginning) && pos.x !== x) {
break;
}
if (pos.x > x) end = target;
else if (pos.x < x) beginning = target;
else break; //position found
}
circle
.attr("opacity", 1)
.attr("cx", x)
.attr("cy", pos.y);
posBehind = pathEl.getPointAtLength(target-10);
circleBehind
.attr("opacity", 1)
.attr("cx", posBehind.x)
.attr("cy", posBehind.y);
posAhead = pathEl.getPointAtLength(target+10);
circleAhead
.attr("opacity", 1)
.attr("cx", posAhead.x)
.attr("cy", posAhead.y);
});
randomizeButton.on("click", function(){
data = d3.range(50).map(function(){return Math.random()*10});
circle.attr("opacity", 0)
path
.transition()
.duration(300)
.attr("d", line(data));
});
Run Code Online (Sandbox Code Playgroud)
不要自己计算前后圆的位置,而是使用getPointAtLength相对于必须保持在中间的对象的中心的位置。
灵感来源: http: //bl.ocks.org/duopixel/3824661