如何在没有 viewbox 属性的情况下制作 SVG 比例?

Posted

技术标签:

【中文标题】如何在没有 viewbox 属性的情况下制作 SVG 比例?【英文标题】:How to make an SVG scale without viewbox attribute? 【发布时间】:2018-09-05 04:14:19 【问题描述】:

我正在尝试扩展 ReactJS 组件,使其扩展以适应其父 div 容器。组件返回一个

<svg/>

元素有几个孩子。 react 组件的 API 只允许我设置 svg 元素的 CSS 样式。我没有办法给 svg 元素一个 viewbox 属性。

我有没有办法让 SVG 缩放以仅通过 CSS 填充其父容器?

react 组件供参考:link

【问题讨论】:

不容易,这就是 viewBox 属性存在的原因。 someSelector svg display:block; width: 100% 不工作吗? 不,它会扩展 svg 以填充整个区域,但不会缩放 svg 的子项。意思是,绘制的项目停留在它们所在的位置并且不会缩放 如果 SVG 设置了 width 和 height 属性,那么据我所知你不走运。 好吧,你可以通过在 SVG 安装后遍历 DOM 并通过 vanilla javascript 设置 viewBox 属性来破解它,但这可能不是一个很好的解决方案从长远来看。 【参考方案1】:

嗯,很简单。您需要做的就是结合ResizeObserver 和transform: scale()。该解决方案用于将 svg 世界地图拉伸到我工作的公司的应用程序产品版本中的仪表板小部件区域。

有一个 gist 发布了一个指向 JSFiddle 演示的链接。

(function() 

  const parent = document.querySelector('.parent');
  const item = document.querySelector('.item');
  let scaleAdjust = 1.0;
    
  const process = (container, ref) => 
    const 
      height: originHeight,
      width: originWidth
      = ref.getBoundingClientRect();
    const 
      height: containerHeight,
      width: containerWidth,
     = container.getBoundingClientRect();
    const [height, width] = [originHeight * scaleAdjust, originWidth * scaleAdjust];
    const [from, to] = height > width ? [width, containerWidth] : [height, containerHeight];
    const scale = to / from;
    ref.style.transform = `scale($scale)`;
    scaleAdjust = 1 / scale;
  ;

  new ResizeObserver(() => process(parent, item)).observe(document.body);
    
)();

【讨论】:

以上是关于如何在没有 viewbox 属性的情况下制作 SVG 比例?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有新请求的情况下修改 ajax src 属性?

使用 CSS 更改 SVG Viewbox 大小

没有 id 的 SVG 外部引用

SVG(可缩放矢量图形)视区盒属性viewbox与preserveAspectRatio

带有 viewBox 和宽度的 SVG 在 IE 中无法正确缩放高度

C#里winform最大化时,如何使里面的控件按比例变化