tags:

views:

172

answers:

1

I'm unfamiliar with the SVG spec, so I was wondering if there was an easy way to build a border of a certain width around a fixed-width, rectangular SVG simply by manipulating the DOM. This seems like it should be feasible, but I don't know where to prod to begin.

Help?

+1  A: 

Yes you can. Let's say you want to have a 4 user unit black rectangular border, and that you know that your SVG has viewBox="0 0 400 300". You can do this, from script:

var r = document.createElementNS("http://www.w3.org/2000/svg");
r.setAttribute("width", "400");
r.setAttribute("height", "400");
r.setAttribute("fill", "none");
r.setAttribute("stroke", "black");
r.setAttribute("stroke-width", "8");
document.documentElement.appendChild(r);

The reason you use 8 for the stroke width is that strokes are drawn centered on the geometry. Thus, half of the rectangle's stroke (i.e., 4 user units) will lie within the viewBox and half outside and thus not rendered. Alternatively you could do:

var r = document.createElementNS("http://www.w3.org/2000/svg");
r.setAttribute("x", "2");
r.setAttribute("y", "2");
r.setAttribute("width", "398");
r.setAttribute("height", "398");
r.setAttribute("fill", "none");
r.setAttribute("stroke", "black");
r.setAttribute("stroke-width", "4");
document.documentElement.appendChild(r);

to achieve the same effect.

Note though that if your document has content within the 4 unit region where the border is painted, say <circle cx="10" cy="10" r="10"/>, then the border will obscure it. This is unlike CSS box borders, which are drawn outside of the contents of the box. If you want to draw the border on the outside, then you'll need to place the rectangle so that it paints just around the original (0, 0, 400, 300) area and adjust the viewBox="" so that it includes the border. For example:

var r = document.createElementNS("http://www.w3.org/2000/svg");
r.setAttribute("x", "-2");
r.setAttribute("y", "-2");
r.setAttribute("width", "404");
r.setAttribute("height", "404");
r.setAttribute("fill", "none");
r.setAttribute("stroke", "black");
r.setAttribute("stroke-width", "4");
document.documentElement.appendChild(r);

document.documentElement.setAttribute("viewBox", "-4 -4 408 408");

Now, I just remembered from your other question that you're using Batik and manipulating documents from Java, but the above should work if you translate it into Java DOM calls (e.g. .getDocumentElement() instead of .documentElement).

(All of the above is untested, but the approach should be sound.)

heycam
What do you do if you don't have a viewbox, and widths and heights are specified in units (cm, for example).
Stefan Kendall