0

I'm trying to write a quick blurb of javascript to animate layers from the SVG files generated by Inkscape. Inkscape is nice enough to set the inkscape:groupmode attribute to "layer" for layer groups:

<g
   transform="translate(-12.681101,-9.7947913)"
   id="g2179"
   inkscape:groupmode="layer"
   inkscape:label="Frame 2"
   style="display:inline"
>

So I wrote a little script to find all those nodes, hide them, and then show them one by one in a loop with a delay:

<script type="text/javascript">
    <![CDATA[
        var layers;
        var current = 0;

        // show one at a time
        function animate() {
            if (layers.length > 0) {
                layers[current].style.display = "none";
                current = (current+1) % layers.length;
                layers[current].style.display = "inline";
            }
        }

        // on load, get layers and hide them
        function init() {
            layers = document.querySelectorAll("g[inkscape\\:groupmode='layer']");
            alert(layers.length);

            // hide all layers
            for (var ii=0; ii < layers.length; ii++) {
                layers[ii].style.display = "none";
            }

            setInterval(animate, 500);
        }
    ]]>
  </script>

Where init() is called by onload on the svg element:

<svg onload="init()">

Unfortunately, the querySelectorAll call returns a layers array that's empty (alert shows '0'). I can query all the group elements by removing the attribute identifier, but that's not what I want.

How do I select just the elements that are layers?

Edit: Full example, this pops up "0" in Firefox 71.0, and Chrome 79.0.3945.79 on Linux:

<svg
   onload="init()"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="79.63958mm"
   height="79.63958mm"
   viewBox="0 0 79.63958 79.63958">

  <script type="text/javascript">
    <![CDATA[
        var layers;
        var current = 0;

        // show one at a time
        function animate() {
            if (layers.length > 0) {
                layers[current].style.display = "none";
                current = (current+1) % layers.length;
                layers[current].style.display = "inline";
            }
        }

        // on load, get layers and hide them
        function init() {
            layers = document.querySelectorAll("g[inkscape\\:groupmode='layer']");
            alert(layers.length);

            // hide all layers
            for (var ii=0; ii < layers.length; ii++) {
                layers[ii].style.display = "none";
            }

            setInterval(animate, 500);
        }
    ]]>
  </script>

  <g
     inkscape:label="Frame 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(-12.681101,-9.7947913)"
     style="display:inline">
  </g>
</svg>
gct
  • 14,100
  • 15
  • 68
  • 107
  • 1
    You are looking for a `g` element not for a `.g` class. Change to `"g[inkscape\\:groupmode='layer']"`, or just remove `.g`. – Ori Drori Dec 17 '19 at 19:39
  • 1
    Good catch, will edit to fix. Unfortunately still not getting elements – gct Dec 17 '19 at 19:41
  • 1
    Without the class dot it works - https://jsfiddle.net/d1kh20np/ – Ori Drori Dec 17 '19 at 19:44
  • Still doesn't work for me in Chrome or Firefox, I updated the question with a full code that's not working. – gct Dec 17 '19 at 19:54
  • Again, I copied everything, pasted it in a new document ([this one](https://pastebin.com/raw/E2Lq6XNR)) and it alerts `1` in Chrome. Does this at least work for you, if you create a new HTML document and just paste [this](https://pastebin.com/raw/E2Lq6XNR) in it? – blex Dec 17 '19 at 20:06
  • You're pasting it as HTML, it's an SVG doc – gct Dec 17 '19 at 20:25

1 Answers1

3

You can't select get element by that type of querySelector, but you can try filtering, the G elements that you need

const g = document.querySelectorAll('g')
const layers = Array.from(g)
    .filter(g => g.getAttribute('inkscape:groupmode') === 'layer')