SVG 2 DOM/JSON Constructors

From SVG
Jump to: navigation, search

It would be useful in some scenarios to be able to construct a DocumentFragment from JSON. However, it's difficult to find something that isn't hard to read and write. You might think you could do something clever like this (making the property name "@" special to distinguish attributes from child "elements"):

var json = { svg: { "@": { viewBox: "0 0 100 100", "pointer-events": "all" },
               g: { "@": { transform: "scale(2)" },
                 rect: { "@": { width: 10, height: 10 } },
                 circle: { "@": { cx: 10, cy: "50%", r: "10em", fill: "red" } },
               }
             }
           } );

var frag = element.createFragment(json);

However, since ECMAScript does not require object properties to be stored in any order, there is no guarantee that the 'rect' and 'circle' will end up in the intended document order. Try to use arrays to get around this problem, and things start to get messier and harder to write (in this case the property name "." is made special to distinguish child "elements" from attributes):

var json = [{ svg: { viewBox: "0 0 100 100", "pointer-events": "all", ".": [
              { g: { transform: "scale(2)" , ".": [
                { rect: { width: 10, height: 10 } },
                { circle: { cx: 10, cy: "50%", r: "10em", fill: "red" } }
              ] }}
           ] }}];

var frag = element.createFragment(json);

If you think that doesn't look too bad, try recreating a small DOM tree yourself and see if you can keep track of the curly and square brackets as you write it. It's pretty painful. Also, interacting with the JSON tree is pretty ugly, since the use of arrays means that child "elements" must be accessed by array indexes. For example, to access the 'circle' "element" would require:

json.svg['.'][0].g['.'][1].circle

For these reasons it seems like JSON is a very poor solution to the problem of creating, reading from or manipulating SVG content.