最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - setting background image to dynamic svg data? - Stack Overflow

programmeradmin3浏览0评论

Originally i had some inline svg which works as i wanted.

<svg width="100%" height="100%" xmlns="">
  <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>

and was nice because it was inline, i could do jQuery selectors on it to undate: Width/Height and the path.d attributes.

in that way, it was an overlaid div, which didnt do what i wanted.

Next step i was thinking to save it as an svg file, and then reference it:

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

which was PERFECT for me, because i took something already existing and gave it a background instead of having an entire new div with data.

The issue though with the background image route, is that i cant dynamically adjust the Height/Width/ path.d attributes

Is there a way such that i can get the best of both worlds?

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

Here is code i had originally for the inline set_gridSize function:

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);
}

Thanks! :)

edit: I used how to draw grid using html5 and (canvas or svg) as my source for figuring out SVG and html5 for grids.

Originally i had some inline svg which works as i wanted.

<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>

and was nice because it was inline, i could do jQuery selectors on it to undate: Width/Height and the path.d attributes.

in that way, it was an overlaid div, which didnt do what i wanted.

Next step i was thinking to save it as an svg file, and then reference it:

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

which was PERFECT for me, because i took something already existing and gave it a background instead of having an entire new div with data.

The issue though with the background image route, is that i cant dynamically adjust the Height/Width/ path.d attributes

Is there a way such that i can get the best of both worlds?

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

Here is code i had originally for the inline set_gridSize function:

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);
}

Thanks! :)

edit: I used how to draw grid using html5 and (canvas or svg) as my source for figuring out SVG and html5 for grids.

Share Improve this question edited May 23, 2017 at 12:00 CommunityBot 11 silver badge asked Feb 20, 2014 at 17:20 FallenreaperFallenreaper 10.7k15 gold badges75 silver badges138 bronze badges 1
  • This may be of interest: blog.cloudfour.com/media-queries-in-svg-images. However, you'll find that support for media queries on SVGs as background images to be spotty. – cimmanon Commented Feb 20, 2014 at 17:42
Add a comment  | 

4 Answers 4

Reset to default 8

A simpler method:

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

I can't see why you couldn't place ths inline svg in absolute positioned DIV as follows. It would function as a background and accessible via 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>
var svg = document.querySelector('#svg');
var svgCode = encodeURI(svg.outerHTML);

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

I first looked at the requirements, and what was needed. This might be not as efficient as other options. Nevertheless, still a viable solution.

My base svg object is in the xml variable. From there, i will maniuplate it as needed with "num" and then encode it. This returns url(data:..) so i just set it to the background-image of whatever i would like.

Given that this is static, you can improve upon this by just appending to the string as needed. I just wanted it to be generic enough such that i can just replace xml as needed with whatever svg data i needed.

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]))+")";
}
发布评论

评论列表(0)

  1. 暂无评论