自动调整 SVG 大小?

Posted

技术标签:

【中文标题】自动调整 SVG 大小?【英文标题】:Autosize an SVG? 【发布时间】:2013-01-16 16:06:28 【问题描述】:

这是code demo

我有一个高度未知的 SVG。我可以在我加载 json 并使用 javascript+math 之后弄清楚它,但是我可以使用任何 css 来动态调整它的大小吗?

css:

svg 
  width: 500px;
  height: 9000px;

.tabme 
  border:3px solid red;
  height: 200px;
   overflow:scroll;

html:

<div class="tabme">
  <div id="Chart">
    <div class="chartbody" />
    <svg>
      <rect  y="0"  x="175" />
      <rect  y="20"  x="175" />
      <rect  y="40"  x="175" />
      <rect  y="60"  x="175" />
      <rect  y="80"  x="175" />
      <rect  y="100"  x="175" />
      <rect  y="120"  x="175" />
      <rect  y="140"  x="175" />
      <rect  y="160"  x="175" />
      <rect  y="180"  x="175" />
      <rect  y="200"  x="175" />
      <rect  y="220"  x="175" />
      <rect  y="240"  x="175" />
      <rect  y="260"  x="175" />
      <rect  y="280"  x="175" />
      <rect  y="300"  x="175" />
    </svg>
  </div>
</div>

【问题讨论】:

svg 高度:100%;宽度:自动 可能是?它会像图像一样工作,高度为 200px,并保存比例.. @Flops:自动不起作用。我也想要身高 【参考方案1】:

如果 SVG 元素没有任何宽度和高度属性,那么宽度/高度应为 calculated according to the CSS specs,正如 Robert Longson 所指出的那样。但是,这些值不会反映 SVG 内容的正确尺寸。您可以使用getBBox() 找出正确的尺寸和位置:

// Javascript to run after document load
var svg = document.getElementsByTagName("svg")[0];
var bbox = svg.getBBox();
svg.setAttribute("width", bbox.width + "px");
svg.setAttribute("height", bbox.height + "px");
svg.setAttribute("viewBox", `$bbox.x $bbox.y $bbox.width $bbox.height`);
<svg xmlns="http://www.w3.org/2000/svg" style="background-color: red">
  <rect x="30" y="40"  />
</svg>

【讨论】:

有一些规则定义了在w3.org/TR/CSS21/visudet.html#inline-replaced-width 中使用的宽度/高度,如果没有更好的,你最终会得到 300px x 150px。 @RobertLongson:很有趣,感谢您提供的信息!我的印象是结果不一致,但也许我的记忆根本不准确。我将更改答案以包含该信息。 结果不一致,因为并非所有 UA 都正确实施了规则。【参考方案2】:

另一种方法是与上述 JS 类似,但设置 viewBox(注意,不是 viewbox!)而不是来自 JS 的 widthheight,其值来自 getBBox() 调用。然后使用preserveAspectRatio="xMidYMid meet" 或类似的。

var svg = document.getElementById("x1");
svg.setAttribute("viewBox", "0 0 32 18.4");

https://jsfiddle.net/t88pLgbb/4/

【讨论】:

【参考方案3】:

受 Thomas 回答的启发,我是这样做的:

if (true) 
  let svg = document.getElementById("bleh");
  let bb = svg.getBBox();
  svg.setAttribute("width", bb.width);
  svg.setAttribute("height", bb.height);
  svg.setAttribute("transform",
    "translate(-" + bb.width / 2 + ",-" + bb.height / 2 + ") \
    scale(" + 600 / bb.width + "," + 250 / bb.height + ") \
    translate(" + bb.width / 2 + "," + bb.height / 2 + ")");
<!DOCTYPE html>
<html>
<head>
</head>
<body>

<div style="width: 600px; height: 250px; border: 1px solid blue;">
  <svg id="bleh">
    <path d="M0 0 T100 400 T500 500 T800 200 T0 0" fill="purple" opacity="0.8" />
    <path d="M0 0 L100 400 L500 500 L800 200 L0 0" fill="none" stroke="black" stroke- />
  </svg>
</div>

</body>
</html>

目标:尝试将整个 SVG 图自动适应大小为 600*250 的 div。

基本上我做的是得到SVG形成后的宽度和高度,向左和向上平移50%,根据600*250 div和SVG图形之间的宽度和高度差的比例进行缩放尺寸,然后将其向右和向下平移 50%。这样,当我缩放它时它保持居中。 (它似乎不喜欢这种方式的实际百分比......)

【讨论】:

我认为最好使用viewBox 属性(如@GufNZ 所建议)而不是转换。我更新了我的答案以包含它。

以上是关于自动调整 SVG 大小?的主要内容,如果未能解决你的问题,请参考以下文章

d3.js Map (<svg>) 自动适应父容器并随窗口调整大小

反应中的 SVG 大小

D3 svg 组件不可调整大小

如何调整 SVG 剪辑路径的大小?

调整浏览器大小时,SVG 顶部有空白区域

在移动设备上调整 SVG 大小