如果您查看这个 jsbin svg 图像,它具有宽度和高度属性以及 viewBox 属性集:
var width = width + margin.left + margin.right;
var height = height + margin.top + margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr('viewBox', '0 0 ' + width + ' ' + height)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
Run Code Online (Sandbox Code Playgroud)
那么 svg 根本无法缩放。
但是,如果我随后注释掉宽度和高度属性,那么它确实会像此 bin中那样缩放。
我对 viewBox 属性感到非常困惑,我在网上看到很多示例,其中宽度、高度和 viewBox 属性都已设置。当存在宽度和高度属性时,我看到 viewBox 属性被否定。
我还对 viewBox 的宽度和高度属性实际上对应于实际空间感到困惑。
文档说您正在指定自己的坐标系,但我不明白这意味着什么以及宽度和高度如何对应于文档的实际宽度和高度。
tl;dr: viewBox用于绘制 SVG 内部的内容,width并height告知以什么尺寸显示它。
viewBox 定义了您将 SVG 绘制到的画布和坐标系。如果它显示viewBox="10 50 100 100",并且您想绘制一个覆盖图像左上四分之一的正方形,您将编写:
<svg viewBox="10 50 100 100" xmlns="http://www.w3.org/2000/svg">\n <rect x="10" y="50" width="50" height="50" />\n</svg>\nRun Code Online (Sandbox Code Playgroud)\n\n然后,当您想要显示 SVG(例如嵌入到 html 页面中)时,宽度和高度会告诉显示它们的尺寸,就像图像标签一样:
\n\n<div>\n <svg width="250" height="250" viewBox="10 50 100 100"\n xmlns="http://www.w3.org/2000/svg">\n <rect x="10" y="50" width="50" height="50" />\n </svg>\n</div>\nRun Code Online (Sandbox Code Playgroud)\n\n如果您的 SVG 保存为外部文件drawing.svg,您可以表达相同的效果
<div>\n <img src="drawing.svg" width="250" height="250" />\n</div>\nRun Code Online (Sandbox Code Playgroud)\n\n在这两种情况下,您绘制的正方形都会覆盖图像的左上四分之一,但由于 SVG 的总体尺寸为 250px \xe2\x9c\x95 250px,因此正方形的边长为 125px \xe2\ x9c\x95 125 像素。
\n\n换句话说,如果 viewBox 中定义的宽度为a,元素上定义的宽度为b,则效果与以 因子缩放 SVG 内的所有内容(水平)相同b / a。
(这显然提出了一个问题,当 viewBox 高度为c,元素高度为d,并且比率d / c \xe2\x89\xa0 b / a不匹配时会发生什么?这就是preserveAspectRatio属性所描述的内容。)
形式上,width、height、viewBox和的每个组合都preserveAspectRatio可以等效地写为transform属性。此处描述了该算法。(请注意,对于<svg>示例中使用的元素,x和y属性必须始终为 0。)