How can I find the translated co-ordinates of an SVG element?

时间:2018-01-23 19:35:15

标签: javascript d3.js svg

I have a SVG element with x and y set, but I'm also translating it by a certain vector using transform="translate(a, b)", which changes the co-ordinates it's rendered to but obviously doesn't update its x and y attributes. Is there a way to get the actual co-ordinates, which in this case would be x + a and y + b, without having to directly parse the values out of the transform attribute?

Not that this is a D3-specific question, but my code looks like this:

svg.selectAll(selector)
    .attr("x", x)
    .attr("y", y)
    .attr("width", width)
    .attr("height", height)
    .attr("transform", `translate(${a}, ${b})`);

2 个答案:

答案 0 :(得分:2)

好吧,这不是真正的D3相关,而是纯粹的SVG / javascript:

我在这里使用这个函数,我称之为" flatten",基本上你想将矩阵重置为非变换的矩阵(矩阵(1 0 0 1 0 0))并更新路径点扁平化值:

flattenShape(item, matrix) {
    let points = item.pathPoints;
    let l = points.length;
    for (let i = 0; i<l; i++) {
        let cache = this.mainSVG.createSVGPoint();
        cache.x = points[i].x;
        cache.y = points[i].y;
        cache = cache.matrixTransform(matrix);
        points[i].x = cache.x;
        points[i].y = cache.y;
    }
    item.d = this.constructPath(points);
    item.transform = "matrix(1 0 0 1 0 0)";
};

item - 您的SVG元素matrix - 您需要获取相关元素的实际SVGMatrix。我明白了:

let matrix = YOUR_SVG_ELEMENT.transform.baseVal.consolidate().matrix;

所以我的方法可能过于具体,但一般而言:

  • 合并您正在转换的SVG元素的矩阵。
  • 使用SVGPoint为每个相关坐标执行:matrixTransform(矩阵)。
  • 将变换属性重置为初始状态,例如matrixTransform(矩阵)

答案 1 :(得分:1)

您可以使用getBoundingClientRect()方法获取节点的位置

这是一个显示两个rect的代码段,其中一个 已翻译

var svgXY = d3.select('svg').node().getBoundingClientRect();

var rect1 = d3.select('rect#test1').node().getBoundingClientRect();
console.log('Rect 1: { top: ' + (rect1.top-svgXY.top) + ', left: ' + (rect1.left-svgXY.left) + '}');

var rect2 = d3.select('rect#test2').node().getBoundingClientRect();
console.log('Rect 2: { top: ' + (rect2.top-svgXY.top) + ', left: ' + (rect2.left-svgXY.left) + '}');
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<script src="https://code.jquery.com/jquery-3.2.1.js"></script>


<svg width="300" height="200">

  <rect x="20" y="40" fill="red" width="100" height="40" id="test1"></rect>
  <rect x="20" y="40" fill="green" width="100" height="40" transform="translate(40, 30)" id="test2"></rect>
</svg>

或者,如果您使用的是 jQuery ,则可以使用$('rect#test1').position()获取该位置。

希望这有帮助。

修改 body默认情况下保证金为8px,因此x等于28。我已经添加了CSS并立即查看了该片段。