Skip to content

dynamic SVG image

jackdarker edited this page Nov 14, 2021 · 6 revisions

In the previous page it was shown how to modify existing elements in a SVG.
Now I want to create an image dynamical:
Instanciate an object by using , assigning formatting classes and position it on the canvas.

Important: When using <use>, the position of the new object will be relative to the template object, not relativ to viewbox ! I place all template objects at the "zero"-position in my image. They are all added to a "template"-layer and this layer is hidden.

Important#2: Template objects should be unscaled or they will return wrong cx(),cy(),x(),y().
Also make sure that the layer-groups dont have an offset set and that viewbox dimension is the same as width/height of the SVG.

In the code below, 2 rooms are instantiated and connected with a polyline. Note that the lines points needs to be offset by the center-position of the template (see notes above). Also insertBefore is used, otherwise the line would be drawn on top of the rooms.
A text is added. Note that ax/ay is used instead move because this somehow messes up position. Text formatting is also placed in a class.
It should have set text-anchor:middle; text-align:center; There has to be a "layer1" in the source-svg that will hold the instanciated objects.

var width=400,height=200,step=32; //step defines the gridsize of the map
draw = SVG().addTo('#canvas').size(width, height);
draw.rect(width, height).attr({ fill: '#303030'}); //background
var node = SVG(window.gm.images['template2']()); //get the source-svg
var group=node.find('#layer1')[0]; //fetch a layergroup by id to add to
var tmpl = node.find('#tmplRoom')[0]; //the template to instanciate, just to get "zero"
var ox= tmpl.cx(),oy=tmpl.cy(); //offset in pixel
var A1 = group.use('tmplRoom').attr({id:"Tile_A1"}).move(0, 0).addClass('roomFound');
var B2 = group.use('tmplRoom').attr({id:"Tile_B2"}).move(0, 20).addClass('roomVisited');
group.text('E').addClass('textLabel').ax(B2.cx()+ox).ay(B2.cy()+oy);
var door = group.polyline([[A1.cx()+ox,A1.cy()+oy], [B2.cx()+ox,B2.cy()+oy]]).attr({id:"A1B2"}).insertBefore(A1).addClass('pathFound');
node.addTo(draw);

Clone this wiki locally