这可能是一个常见问题解答,所以请随时向我指出另一个答案。该主题很难搜索。
如果我想使用 d3.js 获取在 SVG 对象中显式声明的属性,或者我使用 D3 显式放置的属性,我可以使用 d3.select
轻松获取属性的值.例如,打印 300:
...
<circle id="mycircle" r="10" cx="100" cy="200">
...
d3.select("#mycircle").attr("cx", 300);
console.log(d3.select("#mycircle").attr("cx"));
如果我没有显式设置属性的值,但它是从
<g>
中隐式“设置”的怎么办?团体?或者:如何使用代码找出 <g>
的位置组居中?我想要一些方法来确定 <svg>
的绝对坐标系中的位置反对<g>
里面的东西是。如果我知道<g>
在哪里是,它在空间中的方向等等,我可以弄清楚它里面的点在哪里。我怎样才能做到这一点?BigBadaboom 在对 this question 答案的评论中发表评论继承的不是一对坐标,而是一个
transform
属性。所以我可以选择 <g>
并获取变换属性的值:console.log(d3.select("#mygroup").attr("transform"));
打印,例如:
“旋转(-125.93)翻译(0,-25)”
我是否必须解析它才能找出
<g>
的位置?是否位于绝对坐标系中?
最佳答案
这里的其他人已经提到了SVGLocatable.getBBox()
这对于根据元素自身的局部坐标系抓取元素的边界框很有用。不幸的是,正如您所注意到的,这没有考虑对元素或其父元素进行的任何转换。
在处理这些转换时,还有一些其他功能可以帮助您解决问题。SVGLocatable.getScreenCTM()
给你一个SVGMatrix
表示从视口(viewport)坐标转换为元素的本地坐标所需的转换。这很棒,因为它将考虑应用于调用它的元素的变换,以及应用于父元素的任何变换。不幸的是,它还考虑了元素在屏幕上的确切位置,这意味着如果您在 svg 文档之前有内容,或者甚至只是围绕它的一些边距,则返回的矩阵将包含该空间作为翻译。Element.getBoundingClientRect()
将允许您考虑该空间。如果您在 SVG 文档本身上调用此函数,您可以找出 SVG 在屏幕上的偏移量。
然后,当您想在坐标系之间转换时,您所要做的就是将两者结合起来。 HERE是一些关于如何使用 SVGMatrix
的好信息作品。现在要知道的重要一点是 SVGMatrix
是一个有六个属性的对象 a
, b
, c
, d
, e
, 和 f
它表示如下变换:
假设您有一个变量 svgDoc
这是对 svg 文档的引用(不是 d3 选择,而是元素本身)。然后您可以创建一个函数,将其转换为 svg 元素的坐标系 elem
如下。
function convertCoords(x,y) {
var offset = svgDoc.getBoundingClientRect();
var matrix = elem.getScreenCTM();
return {
x: (matrix.a * x) + (matrix.c * y) + matrix.e - offset.left,
y: (matrix.b * x) + (matrix.d * y) + matrix.f - offset.top
};
}
然后,假设您想在
elem
的中间添加一个点。 ,你可以这样做:var bbox = elem.getBBox(),
middleX = bbox.x + (bbox.width / 2),
middleY = bbox.y + (bbox.height / 2);
var absoluteCoords = convertCoords(middleX, middleY);
var dot = svg.append('circle')
.attr('cx', absoluteCoords.x)
.attr('cy', absoluteCoords.y)
.attr('r', 5);
当然,您可能想要概括
convertCoords
函数,因此您可以传入目标元素,但希望这会让您朝着正确的方向前进。祝你好运!更好的实现是为任何给定元素和 svg 文档上下文生成转换函数的工厂:
function makeAbsoluteContext(element, svgDocument) {
return function(x,y) {
var offset = svgDocument.getBoundingClientRect();
var matrix = element.getScreenCTM();
return {
x: (matrix.a * x) + (matrix.c * y) + matrix.e - offset.left,
y: (matrix.b * x) + (matrix.d * y) + matrix.f - offset.top
};
};
}
给定相同的
elem
,这可以按如下方式使用和 svgDoc
作为一个天真的例子:var bbox = elem.getBBox(),
middleX = bbox.x + (bbox.width / 2),
middleY = bbox.y + (bbox.height / 2);
// generate a conversion function
var convert = makeAbsoluteContext(elem, svgDoc);
// use it to calculate the absolute center of the element
var absoluteCenter = convert(middleX, middleY);
var dot = svg.append('circle')
.attr('cx', absoluteCenter.x)
.attr('cy', absoluteCenter.y)
.attr('r', 5);
关于svg - 如何获取 <g> 组内对象的绝对坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26049488/