SVG and javascript#2 - jackdarker/TwineTest GitHub Wiki
My plan was to dynamical load vector-graphics and combine them to an image just like you can stack multiple images in css-background.
With the svg-<use> command it should be possible to combine the separatly loaded svg into one scene.
But I run into several problems here:
- svg can be loaded via
<img>but then you cannot access each component of svg for re-styling - you can either inline-embed an SVG in html or use
<object>to load dynamical from a path - first one is ugly to edit (copy paste from svg-file)
- I CANNOT access contentDocument (opposed to the many examples out there) from the loaded svg inside
<object>because of cross-origin-blocking for local files ! - both are creating a visible image; but I just want to get the svg loaded to be able to
<use>them
So my current workaround is like this:
- I use SVG.js to modify SVG-DOM on the fly
- create a js-function that builds a svg-html-string for a picture (copy paste svg-code from svg-file into function; remove all line breaks)
- those functions are called in the passage-script to add the svg-html to the
<symbols>-container of the scene-svg - the scene can now
<use>those svg-html because it exists in the html-document
Example:
//sample svg-html-generator
window.gm.images.wolf2 = function() {
return('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="wolf2">.....</svg>');
//notice that id="wolf2" is already set in the string
};
window.gm.printSceneGraphic=function() {
var width=600,height=300;
var draw = SVG().addTo('#canvas').size(width, height); //initilize SVG, pointing to scene-canvas (just a <div>)
var background = draw.rect(width, height).attr({ fill: '#f06'}); //draw a simple colored background rect
var image = draw.symbols().image('assets/battlers/slug1.svg'); //this will load the svg as image that cannot be styled!
image.node.id='slug1'; //need to add a id for <use>
var node = SVG(window.gm.images.wolf2()); //convert the SVG-string into a node
if(node) node.addTo(draw.symbols()); // and add it to symbols
draw.use('wolf2').move(-20, 20); //now we can use them refering to their id
draw.use('slug1').move(20, 20);
draw.use('wolf2').move(100, 20);
};
If you change the style of a symbol (or a use-reference), this will affect all instances of the symbol (other then the move-operation ?!).
If you just want to restyle a single node, you can add the node directly to draw and change its style:
var node2 = SVG(window.gm.images.wolf2());//node2 is a SVG-document that contains SVG-elements
if(node2) node2.addTo(draw);//added to scene - not symbols !
node2.node.getElementById('wolfbody').style.fill= '#f03';//wolfbody is the id of the svg-element, f.e. a path
If you dont have the node anymore, you can find it:
node3.node.id='wolf3a'; //make sure to give the node a unique id
... later...
SVG.find('#wolf3a #wolfbody')[0].node.style.fill= '#f03';//this will find the subelement of id wolfbody inside node of id wolf3a
Todo: how to load a svg-file from disk and append its content to <devs>-container of scene-svg? This is not possible because of cross-origin-blocking?