8

I get an XML or JSON with paths only, and I need to recreate the SVG image.

I create an empty

<svg xmlns='http://www.w3.org/2000/svg' version='1.1'></svg>,

I add a <g transform="scale(1 -1)" fill='#aaa' stroke='black' stroke-width='5' ></g> in it, and then in this element I add all of the paths in it (e.g. <path d= ... />).

In the end I get a SVG image, but because I haven't set the viewBox attribute in the SVG element the image isn't properly displayed - when I open it in browser, a part of it is displayed full size.

Can the viewBox be calculated from the values from the paths?

Thank you!

Martin Spa
  • 1,494
  • 1
  • 24
  • 44

2 Answers2

18

Similar to Martin Spa's answer, but a better way to do get the max viewport area is using the getBBox function:

var clientrect = path.getBBox();
var viewBox = clientrect.x+' '+clientrect.y+' '+clientrect.width+' '+clientrect.height;

You can then set the viewbox to these co-ordinates.

n.b. i think you can change the viewbox of an svg after it's rendered so you may have to re-render the svg.

alzclarke
  • 1,725
  • 2
  • 17
  • 20
3

OK so I solved it the following way:

  1. removed all letters from the paths string and made an array out of it with

    var values = pathValue.split('L').join(' ').split('M').join(' ').split('z').join('').split(' ');

  2. found max and min from those values:

    var max = Math.max.apply( Math, values );

    var min = Math.min.apply( Math, values );

  3. set the viewBox:

    viewBox = max min max max

This worked in my case excellent. Hope that it will be helpful to someone else too.

Martin Spa
  • 1,494
  • 1
  • 24
  • 44
  • That sounds good. I understand the problem now. Initially I thought you could just set the viewBox to a fixed value, but I guess that wouldn't work because if the image is too big, part of if won't get displayed. – mihai Apr 06 '12 at 13:47
  • 2
    nice : > btw an easier way to do the values bit: path.match(/(\-?\d+(\.\d+)?)/gi). this also works with other characters like q and t which can be in paths – alzclarke Apr 21 '12 at 13:12
  • 1
    note that splitting a path this way to find the extent works ONLY if the path are polygonals; any circular arc or cubic/quadratic spline, or positioned text elements within the SVG may extend outside the bbox computed this way. There's a solution for arcs and splines, but it requires converting them to polygonal lines up to some level of precision where you are sure it will not escape the bounding box; for text it is more complex as it requires computing font styles, and extracting glyphs. Additionally strokes have a width, and you need to take into account the miter/circle/butt joining types. – verdy_p Oct 08 '18 at 23:49
  • Finally, animation in SVG may move elements outside their initial position. It is always a good solution to include in the SVG some dummy rectangle (unfilled and without stroke borders) that define the intended area where the rest will be drawn. – verdy_p Oct 08 '18 at 23:52
  • How will it works for arcs and bezier that has outer curves (concave)? – Mark Vital Oct 10 '18 at 12:25