将动态SVG数据设置为背景图像?

9

最初我有一些内联svg,它的功能是我想要的。

<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <pattern id="smallGrid" width="10" height="10" patternUnits="userSpaceOnUse">
      <path d="M 10 0 L 0 0 0 10" fill="none" stroke="gray" stroke-width="0.5"/>
    </pattern>
    <pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse">
      <rect width="100" height="100" fill="url(#smallGrid)"/>
      <path d="M 100 0 L 0 0 0 100" fill="none" stroke="gray" stroke-width="1"/>
    </pattern>
  </defs>
  <rect width="100%" height="100%" fill="url(#grid)" />
</svg>

这段代码之所以不错,是因为它是内联的,我可以通过jQuery选择器对其进行操作,更新宽高和路径的d属性。

但以这种方式,它只是一个覆盖层div,无法实现我的目标。

接下来,我考虑将其保存为svg文件,然后进行引用:

<div style="background-image:url('images/grid.svg');"></div>

这对我来说非常完美,因为我使用了已经存在的元素,并给它添加了背景,而不是创建一个全新的带有数据的div。

然而,使用背景图片的问题在于我无法动态调整高度/宽度/path.d属性。

是否有一种方法可以兼顾两者之间的优点呢?

background-image + being able to query and update the attributes?

这里是我最初为inline set_gridSize函数编写的代码:

Form.set_gridSize = function (num) {
    num = Number(num);
    Form.gridSize = num;

    var defs = $("div.grid-for-gridlock > svg > defs");
    defs.children("#smallGrid").attr({ Height: num, Width: num });
    var path = defs.children("#smallGrid").children().attr("d");
    var arr = path.split(" ");
    arr[1] = num;
    arr[arr.length - 1] = num;
    path = arr.join(" ");
    defs.children("#smallGrid").children("path").attr("d", path)
    defs.children("#grid").attr({ Height: num * 10, Width: num * 10 });
    defs.children("#grid").children("rect").attr({ eight: num * 10, Width: num * 10 });
    var path = defs.children("#grid").children("path").attr("d");
    var arr = path.split(" ");
    arr[1] = num*10;
    arr[arr.length - 1] = num*10;
    path = arr.join(" ");
    defs.children("#grid").children("path").attr("d",path);
}

谢谢! :)

编辑:我使用如何使用html5和(canvas或svg)绘制网格作为学习SVG和html5绘制网格的参考。


这可能会引起您的兴趣:http://blog.cloudfour.com/media-queries-in-svg-images/。但是,您会发现支持SVG作为背景图像的媒体查询有时会出现问题。 - cimmanon
4个回答

8
一种更简单的方法:
var green = '3CB54A';
var red = 'ED1F24';
var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"  width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#'+green+'" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/><circle class="mycircle" fill="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>';      
var encoded = window.btoa(svg);
document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")";

Fiddle Here


1
"url(data:image/svg+xml;utf8," +encodeURI(svg) + ")" 可译为: - Maxmaxmaximus

4

我不明白为什么你不能将这个内联SVG放在绝对定位的DIV中,如下所示。它可以作为背景,并通过jQuery / Javacript访问。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body style='overflow:hidden'>
<div id="svgDiv" style='position:absolute;top:0px;left:0px;width:100%;height:100%'>
<svg id="mySVG" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <pattern id="smallGrid" width="10" height="10" patternUnits="userSpaceOnUse">
      <path d="M 10 0 L 0 0 0 10" fill="none" stroke="gray" stroke-width="0.5"/>
    </pattern>
    <pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse">
      <rect width="100" height="100" fill="url(#smallGrid)"/>
      <path d="M 100 0 L 0 0 0 100" fill="none" stroke="gray" stroke-width="1"/>
    </pattern>
  </defs>
  <rect width="100%" height="100%" fill="url(#grid)" />
</svg>
</div>
</body>
</html>

那几乎就是我最终实际所做的。 - Fallenreaper

4
var svg = document.querySelector('#svg');
var svgCode = encodeURI(svg.outerHTML);

element.style.backgroundImage = "url(data:image/svg+xml;utf8," + svgCode + ")";

0

我首先查看了要求和所需内容。这可能不像其他选项那样高效,但仍然是可行的解决方案。

我的基本svg对象在xml变量中。从那里开始,我会根据需要进行操作与 "num",然后将其编码。这将返回url(data:..),因此我只需将其设置为任何我想要的背景图像的background-image。

鉴于这是静态的,您可以通过根据需要附加字符串来改进它。我只是希望它足够通用,以便我可以随时使用所需的SVG数据替换XML。

function set_gridSize (num) {
    num = Number(num);

    var xml = '<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="smallGrid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="gray" stroke-width="0.5"/> </pattern><pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse"><rect width="100" height="100" fill="url(#smallGrid)"/><path d="M 100 0 L 0 0 0 100" fill="none" stroke="gray" stroke-width="1"/></pattern></defs><rect width="100%" height="100%" fill="url(#grid)" /></svg>';
    var data = $($.parseXML(xml));

    var defs = data.children("svg").children("defs");
    defs.children("#smallGrid").attr({ height: num, width: num });
    var path = defs.children("#smallGrid").children().attr("d");
    var arr = path.split(" ");
    arr[1] = num;
    arr[arr.length - 1] = num;
    path = arr.join(" ");
    defs.children("#smallGrid").children("path").attr("d", path)
    defs.children("#grid").attr({ height: num * 10, width: num * 10 });
    defs.children("#grid").children("rect").attr({ height: num * 10, width: num * 10 });
    var path = defs.children("#grid").children("path").attr("d");
    var arr = path.split(" ");
    arr[1] = num*10;
    arr[arr.length - 1] = num*10;
    path = arr.join(" ");
    defs.children("#grid").children("path").attr("d", path);

    return "url(data:image/svg+xml;base64," + Base64.encode(new XMLSerializer().serializeToString(defs.parent()[0]))+")";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接