Skip to main content
jpgmx84
Participating Frequently
March 7, 2017
Answered

gotoAndStop() and event listeners issue on HTML5 Canvas project

  • March 7, 2017
  • 1 reply
  • 2849 views

Here's the project for you to download: buttons.fla - Google Drive​.

I'm using Animate CC 2015.2.0.66. Probable issue happens on code line 50 in the main actions layer.

The project

I have some movieclips with a very simple animation inside. I've added event listeners to them, to control mouseover, mouseout and click events. On click, a popup window appears with some info. I remove the event listeners, so users won't be able to interact with the buttons while the window is above them. An "x" button in the corner closes the window. I put the event listeners back so you can click on another button. Pretty basic.

The issue

The problem happens when I use gotoAndStop() to "reset" the clicked button's state. Frame number 10 is where the over animation starts inside the movieclip. Since "frame numbers in EaselJS start at 0 instead of 1", I've used  button.gotoAndStop(9), but that will cause all buttons to stop working. That means no over, out or click states. If I use instead button.gotoAndStop(10), the buttons work just fine, but then they¡re one frame ahead in their animation.

Any idea why this happens? Thanks.

    This topic has been closed for replies.
    Correct answer ClayUUID

    Somehow your code seems to be leaning hard against some severe edge case behaviors of CreateJS. I managed to get it to break/work just by inserting some console.log() statements.

    So of all things, the fading of the content clip to 0 is what's breaking it. Also, there's a pretty bad issue of over state thrashing when you roll over the faces from the bottom. And the mouse cursor was still changing to a hand when mousing over the faces behind the content clip. And if you move the cursor over a face while the content clip is still fading out it doesn't react until you move away from it then move back.

    Well, here's the fixed code:

    stage.enableMouseOver();

    //VARIABLES

    var root = this;

    var lastClicked = 0;

    //FUNCTIONS

    function init() {

        var btn;

        for (var i = 1; i <= 5; i++) {

            btn = root["button" + i];

            btn.number = i;

            btn.mouseChildren = false;

            btn.addEventListener("mouseover", buttonOver);

            btn.addEventListener("mouseout", buttonOut);

        }

        root.content.scaleX = root.content.scaleY = 0.5;

        root.content.alpha = 0.01;

        activateButtons();

    }

    function activateButtons() {

        var btn;

        for (var i = 1; i <= 5; i++) {

            btn = root["button" + i];

            btn.cursor = "pointer";

            btn.addEventListener("click", buttonClick);

        }

    }

    function deactivateButtons() {

        var btn;

        for (var i = 1; i <= 5; i++) {

            btn = root["button" + i];

            btn.cursor = "auto";

            btn.removeEventListener("click", buttonClick);

        }

    }

    function showContent(n) {

        lastClicked = n;

        root.content.gotoAndStop(n - 1);

        root.content.close.cursor = "pointer";

        root.content.close.addEventListener("click", hideContent);

        createjs.Tween.get(root.content, {override:true}).to({scaleX:1, scaleY:1, alpha:1}, 500, createjs.Ease.quartOut);

        deactivateButtons();

    }

    function hideContent() {

        //Change value to 9 and buttons will stop working. Change it to 10 and they'll work.

        //gotoAndPlay will also make the buttons stop working. Why??

        root["button" + lastClicked].gotoAndStop(1);

        root.content.close.cursor = "auto";

        root.content.close.removeEventListener("click", hideContent);

        activateButtons();

        createjs.Tween.get(root.content, {override:true}).to({scaleX:0.5, scaleY:0.5, alpha:0.01}, 500, createjs.Ease.quartOut);

    }

    //EVENTS

    function buttonOver(e) {

        e.currentTarget.gotoAndPlay("over");

    }

    function buttonOut(e) {

        e.currentTarget.gotoAndPlay("out");

    }

    function buttonClick(e) {

        showContent(e.currentTarget.number);

    }

    //EXECS

    init();

    1 reply

    kglad
    Community Expert
    Community Expert
    March 7, 2017

    with html5/canvas you must explicitly reference the parent:

    this.button.gotoAndStop(etc)

    jpgmx84
    jpgmx84Author
    Participating Frequently
    March 7, 2017

    Yeah, I actually have a global variable called root, so I can access the objects on the stage. If it makes it easier, here's the main code. There are five buttons on stage, as well as a movieclip called "content":

    stage.enableMouseOver();

    //VARIABLES

    var root = this;

    var number = 1;

    //FUNCTIONS

    function init (){

      for (var i = 1; i <= 5; i++){

      root["button"+i].number = i;

      root["button"+i].cursor = "pointer";

      }

      root.content.close.cursor = "pointer";

      root.content.scaleX = root.content.scaleY = root.content.alpha = 0;

      activateButtons();

    }

    function activateButtons (){

      for (var i = 1; i <= 5; i++){

      root["button"+i].addEventListener("mouseover", buttonOver);

      root["button"+i].addEventListener("mouseout", buttonOut);

      root["button"+i].addEventListener("click", buttonClick);

      }

    }

    function deactivateButtons (){

      for (var i = 1; i <= 5; i++){

      root["button"+i].removeEventListener("mouseover", buttonOver);

      root["button"+i].removeEventListener("mouseout", buttonOut);

      root["button"+i].removeEventListener("click", buttonClick);

      }

    }

    function showContent (n){

      number = n;

      root.content.gotoAndStop(number-1);

      root.content.close.addEventListener("click", hideContent);

      createjs.Tween.get(root.content).to({scaleX:1, scaleY:1, alpha:1}, 500, createjs.Ease.quartOut);

      deactivateButtons();

    }

    function hideContent (){

      //Change value to 9 and buttons will stop working. Change it to 10 and they'll work.

      //gotoAndPlay will also make the buttons stop working. Why??

      root["button"+number].gotoAndStop(9);

      //

      root.content.close.removeEventListener("click", hideContent);

      createjs.Tween.get(root.content).to({scaleX:0, scaleY:0, alpha:0}, 500, createjs.Ease.quartOut).call(activateButtons);

    }

    //EVENTS

    function buttonOver (e){

      e.currentTarget.gotoAndPlay("over");

    }

    function buttonOut (e){

      e.currentTarget.gotoAndPlay("out");

    }

    function buttonClick (e){

      showContent(e.currentTarget.number);

    }

    //EXECS

    init();

    ClayUUIDCorrect answer
    Legend
    March 8, 2017

    Somehow your code seems to be leaning hard against some severe edge case behaviors of CreateJS. I managed to get it to break/work just by inserting some console.log() statements.

    So of all things, the fading of the content clip to 0 is what's breaking it. Also, there's a pretty bad issue of over state thrashing when you roll over the faces from the bottom. And the mouse cursor was still changing to a hand when mousing over the faces behind the content clip. And if you move the cursor over a face while the content clip is still fading out it doesn't react until you move away from it then move back.

    Well, here's the fixed code:

    stage.enableMouseOver();

    //VARIABLES

    var root = this;

    var lastClicked = 0;

    //FUNCTIONS

    function init() {

        var btn;

        for (var i = 1; i <= 5; i++) {

            btn = root["button" + i];

            btn.number = i;

            btn.mouseChildren = false;

            btn.addEventListener("mouseover", buttonOver);

            btn.addEventListener("mouseout", buttonOut);

        }

        root.content.scaleX = root.content.scaleY = 0.5;

        root.content.alpha = 0.01;

        activateButtons();

    }

    function activateButtons() {

        var btn;

        for (var i = 1; i <= 5; i++) {

            btn = root["button" + i];

            btn.cursor = "pointer";

            btn.addEventListener("click", buttonClick);

        }

    }

    function deactivateButtons() {

        var btn;

        for (var i = 1; i <= 5; i++) {

            btn = root["button" + i];

            btn.cursor = "auto";

            btn.removeEventListener("click", buttonClick);

        }

    }

    function showContent(n) {

        lastClicked = n;

        root.content.gotoAndStop(n - 1);

        root.content.close.cursor = "pointer";

        root.content.close.addEventListener("click", hideContent);

        createjs.Tween.get(root.content, {override:true}).to({scaleX:1, scaleY:1, alpha:1}, 500, createjs.Ease.quartOut);

        deactivateButtons();

    }

    function hideContent() {

        //Change value to 9 and buttons will stop working. Change it to 10 and they'll work.

        //gotoAndPlay will also make the buttons stop working. Why??

        root["button" + lastClicked].gotoAndStop(1);

        root.content.close.cursor = "auto";

        root.content.close.removeEventListener("click", hideContent);

        activateButtons();

        createjs.Tween.get(root.content, {override:true}).to({scaleX:0.5, scaleY:0.5, alpha:0.01}, 500, createjs.Ease.quartOut);

    }

    //EVENTS

    function buttonOver(e) {

        e.currentTarget.gotoAndPlay("over");

    }

    function buttonOut(e) {

        e.currentTarget.gotoAndPlay("out");

    }

    function buttonClick(e) {

        showContent(e.currentTarget.number);

    }

    //EXECS

    init();