寻找SVG元素的偏移位置

Tol*_*oli 23 d3.js

我用D3遇到了很多这个问题.很多时候我喜欢在我的SVG上叠加HTML对象.

我目前的策略是在名为.html-overlay的SVG元素旁边创建一个空DIV.我根据我在主图形的SVG中设置的内部填充来定位它(例如:20px).然后我使用以下函数(使用jQuery)来确定HTML元素应该去的位置:

//element is the object returned by D3 .append()
var getOffset: function(element) {
        var $element = $(element[0][0]);
        return {
            left: $element.offset().left - $('.html-overlay').offset().left,
            top: $element.offset().top - $('.html-overlay').offset().top
        };
    }
Run Code Online (Sandbox Code Playgroud)

我想知道,必须有一些内部(非jQuery依赖)方式来快速获得元素的偏移量.它非常有用(特别是在元素经过多次翻译,旋转,缩放等之后)

具有用于计算元素的"中心"的偏移,元素的最高点,最底部,最左边,最右边等的函数也是很好的.

注意:

由于某些原因,getBoundingClientRect()没有给出正确的数字:

var $element = $(element[0][0]);

            console.log($element.offset(), element[0][0].getBoundingClientRect())
Object
left: 328
top: 248.8333282470703
__proto__: Object

ClientRect
bottom: 376.83331298828125
height: 139.99998474121094
left: 328
right: 478
top: 236.8333282470703
width: 150
Run Code Online (Sandbox Code Playgroud)

Asa*_*vic 16

你试过了吗

var xywh =element[0][0].getBoundingClientRect();
Run Code Online (Sandbox Code Playgroud)

似乎拥有一切吗?(原帖在这篇文章中)

  • 只是在这里添加一个注释,而不是使用[0] [0],你可以改为使用d3的`node`方法:`element.node().getBoundingClientRect()` (5认同)
  • 添加scrollFirefoxOffset = document.documentElement.scrollTop; 和scrollOffsetChrome = document.body.scrollTop; 到getBoundingClientRect().top用于滚动偏移量.Chrome和Firefox似乎需要不同的功能. (2认同)

Jam*_*Lai 11

问题在于getBoundingClientRect,它没有考虑滚动位置或元素相对于文档的容器位置.它只会报告项目相对于文档顶部和左侧坐标的确切位置.

我已经创建了一个d3方法,它将报告元素的位置.它通过循环遍历父元素直到找到容器SVG,然后在计算中考虑该项的位置.它会返回您通常会收到的内容getBoundingClientRect.

这是方法:

d3.selection.prototype.position = function() {

    var el = this.node();
    var elPos = el.getBoundingClientRect();
    var vpPos = getVpPos(el);

    function getVpPos(el) {
        if(el.parentElement.tagName === 'svg') {
            return el.parentElement.getBoundingClientRect();
        }
        return getVpPos(el.parentElement);
    }

    return {
        top: elPos.top - vpPos.top,
        left: elPos.left - vpPos.left,
        width: elPos.width,
        bottom: elPos.bottom - vpPos.top,
        height: elPos.height,
        right: elPos.right - vpPos.left
    };

};
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

d3.select(element).position()

请注意,我实际上并未在此处添加代码来考虑滚动位置.