Firefox svg渲染:如何获得真正的g位置?

时间:2021-12-14 17:04:53

I have a page with a svg loaded via object.

我有一个页面,通过对象加载了一个svg。

Then, I call a function that loads a div, using width, height, left and top of an internal g element

然后,我调用一个函数来加载div,使用内部g元素的宽度,高度,左边和顶部

var cartina = document.getElementById(whatMap);
        var cartinaContext;         
        cartina.addEventListener("load",function(){
        cartinaContext = cartina.contentDocument;
        var el   = $("#mappaBase", cartinaContext)[0]; 
        var rect = el.getBoundingClientRect(); 
        var whatContainer = "#containerIcone"+whatMap;
        $(whatContainer).css("position", "absolute");
        $(whatContainer).width(rect.width);
        $(whatContainer).height(rect.height);
        $(whatContainer).css("left", rect.left);
        $(whatContainer).css("top", rect.top);
}

I'm using getBoundingClientRect(). I'm applying the div #containerIcone over the svg. In Chrome it works smoothly well. The problem is in Firefox: when I load the page, width and height are properly loaded but left and top are not. If I inspect the svg with Firefox, it appears that the g element is placed in a fixed position, while the rendered g element has another one (responsive to window dimensions and other elements position). Still, the g fixed element reacts well to window various sizes. The div is placed over the g element fixed inspect-position.

我正在使用getBoundingClientRect()。我在svg上应用div #containerIcone。在Chrome中它运行顺利。问题出在Firefox中:当我加载页面时,宽度和高度已正确加载但左侧和顶部不正确。如果我用Firefox检查svg,看起来g元素被放置在固定位置,而渲染的g元素有另一个元素(响应窗口尺寸和其他元素位置)。仍然,g固定元件对各种尺寸的窗口反应良好。 div被放置在g元素固定的检查位置上。

Inspecting the same element with Chrome reveals that the g element inspect box is drawed everytime where the g rendered element is.

使用Chrome检查相同的元素会发现每次g渲染元素都会绘制g元素检查框。

How can I make this work in Firefox?

如何在Firefox中完成这项工作?

1 个解决方案

#1


I found a solution, it's working cross-browser. Instead of positioning with .top and .left of the nested g element, I get width and height of nested element

我找到了一个解决方案,它正在跨浏览器工作。我没有使用嵌套g元素的.top和.left定位,而是获得嵌套元素的宽度和高度

var el   = $(nestedElement); 
var rect = el.getBoundingClientRect(); 

Then I get width and height of the parent svg element

然后我得到父svg元素的宽度和高度

var rectSvg = mysvg.getBoundingClientRect();

Then I subtract the el width and height from the svg ones, and divide results by 2. The final result is the white space the svg has inside it, top and left, used to center the rendered element el inside the svg element (used by browser to mantain aspect ratio). Then I apply those results as css top and left of my div containing icons - it will be positioned exactly over the g el element.

然后我从svg中减去el宽度和高度,并将结果除以2.最终结果是svg在其中的顶部和左侧的空白区域,用于将渲染元素el置于svg元素内(由浏览器以保持宽高比)。然后我将这些结果应用为包含图标的div的顶部和左侧的css - 它将精确定位在g el元素上。

var leftSpace = (rectSvg.width - rect.width)/2;
var topSpace = (rectSvg.height - rect.height)/2;
$(myPositionedDiv).css("left", leftSpace);
$(myPositionedDiv).css("top", topSpace);

This manner, however Firefox positions the element despite of rendering, left and top are correctly calculated.

这种方式,但Firefox定位元素尽管渲染,左和顶部正确计算。

#1


I found a solution, it's working cross-browser. Instead of positioning with .top and .left of the nested g element, I get width and height of nested element

我找到了一个解决方案,它正在跨浏览器工作。我没有使用嵌套g元素的.top和.left定位,而是获得嵌套元素的宽度和高度

var el   = $(nestedElement); 
var rect = el.getBoundingClientRect(); 

Then I get width and height of the parent svg element

然后我得到父svg元素的宽度和高度

var rectSvg = mysvg.getBoundingClientRect();

Then I subtract the el width and height from the svg ones, and divide results by 2. The final result is the white space the svg has inside it, top and left, used to center the rendered element el inside the svg element (used by browser to mantain aspect ratio). Then I apply those results as css top and left of my div containing icons - it will be positioned exactly over the g el element.

然后我从svg中减去el宽度和高度,并将结果除以2.最终结果是svg在其中的顶部和左侧的空白区域,用于将渲染元素el置于svg元素内(由浏览器以保持宽高比)。然后我将这些结果应用为包含图标的div的顶部和左侧的css - 它将精确定位在g el元素上。

var leftSpace = (rectSvg.width - rect.width)/2;
var topSpace = (rectSvg.height - rect.height)/2;
$(myPositionedDiv).css("left", leftSpace);
$(myPositionedDiv).css("top", topSpace);

This manner, however Firefox positions the element despite of rendering, left and top are correctly calculated.

这种方式,但Firefox定位元素尽管渲染,左和顶部正确计算。