svgdotjs / svg.js

The lightweight library for manipulating and animating SVG
https://svgjs.dev
Other
11.01k stars 1.07k forks source link

position(), prev(), etc. returning incorrect values #1193

Closed samhocevar closed 11 months ago

samhocevar commented 3 years ago

Bug report

Fiddle

https://jsfiddle.net/azqoxptd/

data = `<svg id="doc">
  <path id="a" fill="#DA251d" d="M-20,-15"/>
  <path id="b" fill="#FF0" d="M0,-6"/>
  <path id="c" fill="#FF0" d="M0,-6"/>
  <path id="d" fill="#FF0" d="M5.7063,-1.8541"/>
</svg>`
var canvas = SVG().addTo('#canvas').size('100%', '100%')
canvas.svg(data);

let do_something = function(e) {
    for (let child of e.children())
        do_something(child);
    if (e.position() > 0)
        console.info(`${e.position()}: ${e.id()} (after ${e.prev().id()})`);
}
do_something(canvas);

Explanation

I expect to see the following output:

1: b (after a)
2: c (after b)
3: d (after c)

Instead I see the following:

1: a (after a)
3: b (after c)
Uncaught TypeError: Cannot read property 'id' of undefined

Everything is wrong with these lines:

Maybe this happens because the calls to prev() are inside an enumeration of the parent’s children? Anyway, if there are limitations and shortcomings with the use of these function, I could not find them in the documentation.

samhocevar commented 3 years ago

I realise that everything works properly if the SVG is built like this:

var canvas = SVG().addTo('#canvas').size('100%', '100%')
canvas.id('doc');
canvas.path('M0,0').id('a');
canvas.path('M0,0').id('b');
canvas.path('M0,0').id('c');
canvas.path('M0,0').id('d');

So maybe the problem lies within SVG.svg().

Fuzzyma commented 3 years ago

It's because of whitespaces

Fuzzyma commented 11 months ago

Changing this would be a major breaking change and therefore this is a wontfix until we decide to develop a v4