【问题标题】:GetBBox of SVG when hidden隐藏时的 SVG 的 GetBBox
【发布时间】:2015-04-01 16:01:52
【问题描述】:

我已经尝试解决这个问题超过一天了,但我找不到答案。我的问题是我需要缩放 SVG 图像(响应式设计)。我需要在客户端操作 SVG 代码,因此不能通过 img 标签嵌入它。因此,我尝试改用内联图像。但是,要正确缩放它,我似乎需要设置 viewBox 属性。 SVG 文件是由一些无法自行设置边界框的软件生成的,所以我的想法是为此使用 JavaScript。

问题是我的软件使用了我无法修改的库中的各种选项卡控件。我不能只获取边界框,因为它最初没有呈现,因此我只会返回零(在 Chrome 中)或错误消息(在 Firefox 中)。

我需要的是一种无需实际渲染对象即可获得边界框大小的方法。无法操纵库用于显示和隐藏选项卡的显示参数。

有什么想法吗?

一个想法是将 SVG 复制到另一个可见的 div 中,但我不知道这是否能解决问题。而且我不知道该怎么做。

最好的问候

【问题讨论】:

  • 为什么不能等到选项卡控件呈现后再调整 viewBox 的大小?
  • 因为 SVG 似乎没有视图状态更改事件,而且我的选项卡库的可能性非常有限。
  • 我通过使用 JQuery 的 id 搜索正确的 svg 图像解决了我的问题。
  • 你能澄清你的解决方案吗,我不明白。我也有类似的问题。
  • 好吧,我为每个内联 svg 添加了一个 ID 标签,并通过 jQuery 选择了这个 ID。但我不记得细节了。

标签: javascript jquery svg inline


【解决方案1】:

您可以将其克隆为可见的 svg,然后 getBBox。

添加到你的html中:

<div style="position:absolute;left:-9999cm;top:-9999cm;visibility:hidden;">
  <svg id="svg1" xmlns="http://www.w3.org/2000/svg"></svg>
</div>

添加到您的 javascript:

function getBBox(elem){
    var svg1 = document.getElementById('svg1'), e = elem.cloneNode(true);
    e.style.display = "inline";
    svg1.appendChild(e);
    var b = e.getBBox();
    svg1.removeChild(e);
    return b;
}

【讨论】:

    【解决方案2】:

    根据之前的答案,我在我的应用程序初始化时对 getBBox 进行了猴子补丁,因此它将透明地应用黑客攻击。

    现在我可以直接在任何元素上调用getBBox,无论它是否附加。

    _getBBox = SVGGraphicsElement.prototype.getBBox;   
    SVGGraphicsElement.prototype.getBBox = function() {
      var bbox, tempDiv, tempSvg;
      if (document.contains(this)) {
        return _getBBox.apply(this);
      } else {
        tempDiv = document.createElement("div");
        tempDiv.setAttribute("style", "position:absolute; visibility:hidden; width:0; height:0");
        if (this.tagName === "svg") {
          tempSvg = this.cloneNode(true);
         } else {
          tempSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
          tempSvg.appendChild(this.cloneNode(true));
        }
        tempDiv.appendChild(tempSvg);
        document.body.appendChild(tempDiv);
        bbox = _getBBox.apply(tempSvg);
        document.body.removeChild(tempDiv);
        return bbox;
      }
    };
    

    【讨论】:

    • 这不起作用。当我在 svg 元素上调用 getBBox() 时,不会调用此方法
    • @EugeneMala 它已经为我们工作了几年?‍♂️
    • 它不适用于动态创建的 svg 元素:element = document.createElementNS("http://www.w3.org/2000/svg", 'path');element.getBBox() // does not work
    • @EugeneMala 对我来说很好用。请参阅jsfiddle.net/diegose/aodstg9b/6(当然,path 需要包含一些内容)
    • @EugeneMala 抱歉,这是正确的版本:jsfiddle.net/diegose/aodstg9b/7。查看右侧的控制台。 JSON.stringify 似乎忽略了所有字段。
    【解决方案3】:

    崔西平作为函数的回答:

    function svgBBox (svgEl) {
      let tempDiv = document.createElement('div')
      tempDiv.setAttribute('style', "position:absolute; visibility:hidden; width:0; height:0")
      document.body.appendChild(tempDiv)
      let tempSvg = document.createElementNS("http://www.w3.org/2000/svg", 'svg')
      tempDiv.appendChild(tempSvg)
      let tempEl = svgEl.cloneNode(true)
      tempSvg.appendChild(tempEl)
      let bb = tempEl.getBBox()
      document.body.removeChild(tempDiv)
      return bb
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-11
      • 2021-12-16
      • 2017-07-22
      • 1970-01-01
      • 2011-09-25
      相关资源
      最近更新 更多