setting background image to dynamic svg data?

css, javascript, jquery, svg

Solution

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]))+")";
}

Problem

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.

Original source

Related problems