我构建了这个形状(我称之为管道),它是由两个圆圈和一条路径构建的:http://jsfiddle.net/gluz/4udR2/3/embedded/result/ 代码:
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 800);
var circle1 = svg.append("circle").attr("cx", 320).attr("cy", 171).attr("r", 37).style("fill", "#CDDE3A");
var shapeCoordinates = [{"x":254,"y":370},{"x":352,"y":189},{"x":284,"y":162},{"x":235,"y":363}];
var coordinatesFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear-closed");
var lineGraph = svg.append("path")
.attr("d", coordinatesFunction(shapeCoordinates))
.attr("stroke", "blue")
.attr("stroke-width", 0)
.attr("fill", "#CDDE3A")
.style("opacity","0.2");
var circle2 = svg.append("circle").attr("cx", 245).attr("cy", 365).attr("r", 10).style("fill", "#CDDE3A").style("opacity", 0.2);
我想让它互动。 对于初学者我希望它看起来它会像一个小圆圈一样构建,如下面的方式,但在第一个例子中有阴影:http://jsfiddle.net/gluz/jeRgz/embedded/result/ 代码:
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 800);
var circle1 = svg.append("circle").attr("cx", 245).attr("cy", 365).attr("r", 10).style("fill", "#CDDE3A");
var circle2 = svg.append("circle").attr("cx", 245).attr("cy", 365).attr("r", 10).style("fill", "#CDDE3A").style("opacity", 0.2);
circle1.transition().duration(3000)
.attr("cx", 320)
.attr("cy", 171)
.attr("r", 37)
.style("opacity", 1.0);
我的问题是: 1.如何将路径对象的圆转换到一起? 2.有没有办法把它建成一个形状? 3.如何让小圆圈不显示它下面的东西,所以它看起来不像是拼接成两个,就像在第一个例子中一样?
谢谢!
答案 0 :(得分:3)
下面是使用单个path
刺痛绘制形状的函数。 Here's a fiddle和here a simpler版本。这里是关于数学的some info,可以使用一些精简。 pt1
和pt2
指定小圆圈和大圆圈的中心,预计是2元素数组, [x,y] 。 r1
和r2
控制每个圆圈的半径。
您可以使用transition()
为路径设置动画,但它并不完美,因为弧线参数是线性插值的。更准确的替代方法是通过调用pipePath()
来确定如何在每个动画帧重建路径。
function pipePath(pt1, r1, pt2, r2) {
angle = Math.atan2(
pt2[0] - pt1[0],
pt2[1] - pt1[1]
)
distance = Math.sqrt(
Math.pow(pt2[0] - pt1[0], 2) +
Math.pow(pt2[1] - pt1[1], 2)
)
rDiff = r1 - r2
if(distance+5 <= r2) { return "M0,0";}
theta = Math.asin(rDiff/distance)
l11 = [
pt1[0] + r1 * Math.cos(theta-angle),
pt1[1] + r1 * Math.sin(theta-angle)
]
l12 = [
pt2[0] + r2 * Math.cos(theta-angle),
pt2[1] + r2 * Math.sin(theta-angle)
]
l21 = [
pt1[0] + r1 * Math.cos(-theta-angle+Math.PI),
pt1[1] + r1 * Math.sin(-theta-angle+Math.PI)
]
l22 = [
pt2[0] + r2 * Math.cos(-theta-angle+Math.PI),
pt2[1] + r2 * Math.sin(-theta-angle+Math.PI)
]
return "M" + l12 +
"A" + [r2,r2] + " 0,0,0 " + l22 + // swap 0,0,0 with 0,1,1 for full shape
"L" + l21 +
"A" + [r1,r1] + " 0,0,1 " + l11 + "z"
}