Reputation: 477
I am using SVG.js library to manipulate one existing SVG file. I have created this image with Inkscape: http://svgur.com/i/100.svg
What I'm trying to do is accessing the internal pink rectangle and animate it but I don't even know how to select that specific element.
I have a simple 'test.html' with: <div id="drawing"></div>
And then I can successfully load the image with the following lines:
var draw = SVG('drawing').size(500, 500);
var use = draw.use('svg8', BASE_URL + '/app/test/test.svg');
use.move(0, 0);
How can I access now the internal element <rect id="rect4928"></rect>
of the SVG file?
Thank you very much.
Upvotes: 1
Views: 4129
Reputation: 2828
If you're just going with vanilla JS you could do something like this. You don't have to create unique ids.
Embed your svgs with object tags
<object id="svg1" data="100.svg" type="image/svg+xml"></object>
<object id="svg2" data="100.svg" type="image/svg+xml"></object>
Then use this javascript.
window.onload = function (){
var c = document.getElementById("svg1").contentDocument;
var rect = c.getElementById("rect4928");
rect.setAttribute("style", "fill: green;");
var c2 = document.getElementById("svg2").contentDocument;
var rect = c2.getElementById("rect4928");
rect.setAttribute("style", "fill: green;");
}
Upvotes: 4
Reputation: 477
After studying these last few days, I have realised it's not possible to do what I was trying. When you import one particular SVG image via <use>
attribute, this image is imported as one single element, all the internal elements go to the shadow DOM and they're not accessible anymore. You can read a very good explanation and possible workarounds by CSS in this article: https://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/
In my case, even if the <use>
element had put all the internal elements in the regular DOM, it wouldn't have been enough. I need the exact same image to appear 8 times in the same HTML and I also need to modify individually all the internal elements of each SVG image (the example above was only a simplified version, in the real scenario I have an image with around 15 internal elements that I have to transform: change color, spin...). For that reason I have to assign a unique ID to each of the internal elements, so for example if I have an SVG with 15 internal elements that is repeated 8 times, in the end I need 125 unique IDs.
What I finally did was creating one of these 8 images in Inkscape. After that I built a simple Java program to make 8 copies of the original file and also give unique IDs to all the elements that will co-exist in the final HTML. Once I have 8 copies of the same SVG with unique IDs, I just embeded directly each of them in the HTML and now I can easily access everything with vanilla JS (I don't really need SVG.js anymore)
You can see next the final result of what I was trying to do: https://jsfiddle.net/6shzx7Lk/
In the final picture I have 8 blue SVG files, 8 yellow and 2 grey blocks. For example you can see each of the blue images have 10 green points inside and if you inspect the source code you can see each of these points have a unique ID. This way I will be able to easily modify each of the green points in all the 8 blue images (and the same with the rest of elements inside). I can also resize the final image with Bootstrap by arranging the different elements according to the user screen size.
I don't know if there's a better way to achieve this but after playing around with SVG last days this is the solution I found for my particular problem.
Thank you very much for your help.
Upvotes: 2
Reputation: 133
You could add id to that element and go with:
var element = SVG.get('purple_rect');
element.move(30,30);
This is from the docs, you can easily manipulate elements. Here is codepen example http://codepen.io/anon/pen/peKzYM#anon-login
Upvotes: 0