0

I am using Two.JS to render shapes to the stage which have been interpreted from an SVG using the Two.js interpret method.

These have an lifespan property added, and in Two's render loop I check for the illustration and remove it if the time is up.

This is working most of the time (>99%), but occasionally the shape gets stuck and I get this error:

Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

showIllustration: (which) =>
    alreadyIllustration = false
    for shape, i in @_shapes
        if shape.isIllustration is true
            alreadyIllustration = true

    if alreadyIllustration is false
        switch which
            when 'food'
                if Math.random() > 0.49
                    id = 'currywurst'
                else
                    id = 'pretzel'
            when 'mascot'
                if Math.random() > 0.49
                    id = 'ample'
                else
                    id = 'bear'
            when 'landmark'
                if Math.random() > 0.49
                    id = 'tower'
                else
                    id = 'tor'

        illustration = @_two.interpret document.getElementById id
        illustration.center().translation.set @_two.width / 2, @_two.height / 2
        @_foreGround.add illustration
        illustration.lifeSpan = 100
        illustration.creationTime = new Date().getTime()
        illustration.isIllustration = true
        @_shapes.push illustration

and here is my loop to remove the illustrations:

removeShapes: () =>
    time = new Date().getTime()
    for shape, i in @_shapes by -1
        if shape.lifeSpan
            if time - shape.creationTime >= shape.lifeSpan
                shape.remove()
                @_shapes.splice i, 1

here is the relevant code from two.js where the error is occurring.

removeChild: function(id) {
        var elem = this.domElement.querySelector('#' + id);
        if (elem) {
          this.elem.removeChild(elem);
        }
      },

this only happens on interpreted svg's, not with shapes. both shapes and interpreted shapes return two.polygon objects so this seems odd.

One thing I can think of is that two.js uses the id of the element it interprets as the id of the polygon made, and if there are two elements with the same id then this causes an error when trying to remove. But the alreadyIllustration check seems to work correctly every time to stop adding illustrations if there are any existing.

I also tried setting the id to the time it was created instead of the id of the element so it was unique every time, but this causes other problems and errors.

Many thanks.

Jack Wild
  • 2,072
  • 6
  • 27
  • 39
  • It looks like you have a similar issue as a previous post http://stackoverflow.com/questions/24155757/some-shapes-not-being-removed-in-two-js-when-looping-through-array-of-all-shapes with iterating through an array that's being modified. At any rate, I think this might be an error in Two.js, because it looks like the element to be removed is not a child of the group. I'll fix this right now. – jonobr1 Jun 17 '14 at 17:15
  • The latest build of two.js on the master branch should have a fix for this: https://raw.githubusercontent.com/jonobr1/two.js/master/build/two.js Give that a try — it shouldn't error anymore. – jonobr1 Jun 17 '14 at 17:18
  • Awesome... how's that for customer service. I'll give it a go this eve and let you know if it's fixed it. – Jack Wild Jun 18 '14 at 11:23
  • It was actually my question from that one before... they were similar but different issues. ;) – Jack Wild Jun 18 '14 at 11:24
  • @jonobr1 i have updated to the latest v of Two now, will let you know if I see the error again. – Jack Wild Jun 20 '14 at 09:50

1 Answers1

0

This isn't a full fix exactly, but I discovered that the problem is something to do with the blur / fade events on the window, and the way in which Chrome handles this. The error seemed to happen when the window was not in focus, and the same illustration that was currently displayed was triggered.

The illustration was removed from the array but not removed from the DOM until the window was back in focus, and this meant that the check would pass and multiple instances of the same illustration with the same ID were displayed.

In order to stop the problem from happening, I disabled the events when the window is not in focus so no new illustrations can be shown until the window is back in focus.

Jack Wild
  • 2,072
  • 6
  • 27
  • 39