SVG元素内部实际可见的内容取决于其宽高比,viewBox值和preserveAspectRatio值.
例如,具有相同viewBox值(下面的红色虚线)的相同SVG元素大小可以具有不同的视口(在下面显示为蓝色),具体取决于preserveAspectRatio:

Chrome有一个viewport属性,但在我的使用中它始终是一个空的(所有0值)SVGRect.Firefox没有实现此属性.
该svg.getBBox()方法返回的值,而viewBox不是实际的可见视口内容.
给定对SVG元素的引用,我如何最容易地确定可见内容(视口),用SVG根部的用户坐标表示(与坐标相同viewBox)?
这是适用于 Chrome、Safari 和 Firefox 的函数。请参阅此处的测试页面:
// Given an <svg> element, returns an object with the visible bounds
// expressed in local viewBox units, e.g.
// { x:-50, y:-50, width:100, height:100 }
function calculateViewport(svg){ // http://phrogz.net/JS/_ReuseLicense.txt
var style = getComputedStyle(svg),
owidth = parseInt(style.width,10),
oheight = parseInt(style.height,10),
aspect = svg.preserveAspectRatio.baseVal,
viewBox = svg.viewBox.baseVal,
width = viewBox && viewBox.width || owidth,
height = viewBox && viewBox.height || oheight,
x = viewBox ? viewBox.x : 0,
y = viewBox ? viewBox.y : 0;
if (!width || !height || !owidth || !oheight) return;
if (aspect.align==aspect.SVG_PRESERVEASPECTRATIO_NONE || !viewBox || !viewBox.height){
return {x:x,y:y,width:width,height:height};
}else{
var inRatio = viewBox.width / viewBox.height,
outRatio = owidth / oheight;
var meetFlag = aspect.meetOrSlice != aspect.SVG_MEETORSLICE_SLICE;
var fillAxis = outRatio>inRatio ? (meetFlag?'y':'x') : (meetFlag?'x':'y');
if (fillAxis=='x'){
height = width/outRatio;
var diff = viewBox.height - height;
switch (aspect.align){
case aspect.SVG_PRESERVEASPECTRATIO_UNKNOWN:
case aspect.SVG_PRESERVEASPECTRATIO_XMINYMID:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMID:
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMID:
y += diff/2;
break;
case aspect.SVG_PRESERVEASPECTRATIO_XMINYMAX:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMAX:
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMAX:
y += diff;
break;
}
}
else{
width = height*outRatio;
var diff = viewBox.width - width;
switch (aspect.align){
case aspect.SVG_PRESERVEASPECTRATIO_UNKNOWN:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMIN:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMID:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMAX:
x += diff/2;
break;
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMID:
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMIN:
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMAX:
x += diff;
break;
}
}
return {x:x,y:y,width:width,height:height};
}
}
Run Code Online (Sandbox Code Playgroud)