zok
zok

Reputation: 7892

How to use multiple SVG elements

I'm loading a bunch of SVG elements and randomically positioning them on the screen. For each time the app is loaded the user gets a different composition, and some elements might repeat, while some might not even show.

Initially I had a list of SVG files, each one with an element. But there seems to be two problems with this approach:

  1. Too many http requests;

  2. These elements contain ids with definitions of styling and gradients (not classes - styles already set to inline when exporting from Illustrator), and some of them end up affecting other elements. A solution to both problems would be to have all elements in only one SVG file, so Adobe Illustrator will assign different ids to each element and the styles won't clash.

My idea then is to load a big SVG file with all these elements, extract them with select() and append them to DOM elements.

Does all that sound reasonable?

Can I use JavaScript to load a single SVG, manage elements contained into that and add them to the DOM at will, or is it a terrible idea?

I've been trying but it's been very painful. For instance, I had to use SnapSVG to be able to find these inner elements inside my SVG, but I cannot append them to the DOM. Probably SnapSVG is not the right tool for that. I've seen other SVG tools but they seem to be rather for creating SVG shapes with JavaScript which is not my case, I just want to extract elements and use them (append to other elements, position, access paths within them and change color, translate, etc).

Upvotes: 2

Views: 3155

Answers (1)

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324630

Following up from my answer on your other question, here's how you can grab elements from one SVG to <use/> them in another.

function grabSVGElement(selector) {
    var svg = document.createElementNS('http://www.w3.org/2000/svg','svg');
    var use = document.createElementNS('http://www.w3.org/2000/svg','use');
    use.setAttributeNS('http://www.w3.org/1999/xlink','href',selector);
    svg.appendChild(use);

    document.body.appendChild(svg);
    var bbox = use.getBBox();
    svg.setAttribute("viewBox",[bbox.x,bbox.y,bbox.width,bbox.height].join(" "));
    document.body.removeChild(svg);
    return svg;
}

This should create the SVG you need, and size it appropriately using its bounding box, before returning it. (It is added to the body temporarily in order to calculate the BBox)

You can then appendChild it to whatever your real container is, and give it X,Y coordinates as desired.

Upvotes: 2

Related Questions