1 Reply Latest reply: Apr 15, 2014 11:51 AM by sinious RSS

    HTML5 Canvas: removeChild() not working

    LordMysterious Community Member

      Hey Guys


      I'm working on a project within Flash CC using the HTML5 Canvas.


      I'm able to add library items to the canvas using this.addChild(name) and position it using setTransform.


      I'm also attempting to remove it from the canvas using removeChild(name), which I imagine to be the logical way of doing it. If I set up a click event listener and removeChild(name) on click, it removes without any problems. However, if I try to remove it as part of a function with no event listener (i.e. as part of a setTimeout) it doesn't remove it at all, I've tried adding an alert either side of the line of code to see when it is run, the second alert never gets triggered.


      What could be the problem here? Can removeChild() only be used as part of a mouse event?


      Thanks in advance

        • 1. Re: HTML5 Canvas: removeChild() not working
          sinious MVP

          Not an easy subject to grasp due to the differences between typical class based coding and prototype based coding. Much like back in AS2.0, scope is your issue.


          If you examine the output of the JavaScript from Flash you'll see that when you generate a new library object and add it to the stage, it occurs in several encapsulated scopes. You have the lib (or whatever you namespaced the library as), which has an AddRemove function inside a MovieClip immediate function which specifies the frame_0 scripts in another function, etc.. It's a lot of encapsulation.


          When you setTimeout(), you run from 'window' scope, not from the scope you think you're running from (inside that frame_0 function). Therefore your 'name' var no longer exists if you dynamically created it there.


          If you create yourself a way to manage references (so you don't pollute the global scope) you can get a reference to this object at any time. The reason it works on a mouse click is because that click operates at object scope. In other words when you click on the object on the canvas, "this" returns back to that objects scope. So saying stage.removeChild(this);, the "this" refers directly to what you clicked.


          Code seems to work better if you don't understand prototype scope so here's a quick and dirty example of me escaping the encapsulated scope issue by directly creating a new 'ball' object from my library at the top most level (global), which is 'window':


          New HTML5 Canvas document, object in library with linkage set to 'ball':


          // aquire new 'ball' from library linkage, assign to global (window)

          // variable 'myBall', as addChild returns the DisplayObject added

          window.myBall = stage.addChild(new lib.ball());

          // display on stage (stage is inherited from window)



          // set timeout in this context but function will run from

          // the window context, not this context (a function inside

          // the frame_0 function inside lib.AddRemove)



          function removeBall()


                    // I am running from window scope here, luckily I

                    // created myBall at this scope so I can access it




          Because I saved myBall to 'window', I have global access to it. While this works, this isn't a good idea, it just proves the scope issue.


          When you use CreateJS directly the scope you create objects from is created by you yourself so you know how to access items. I myself am a bit confused on the scope in which Flash wishes to operate.