2

In Adobe Animate CC HTML5 Canvas (createJS), I'm trying to do something very simple, to trigger an animated rollover when the entire stage of an ad is moused over, and to trigger an animated rollout when the mouse leaves the stage. It should be very simple, but it's not. Using mouseenter and mouseleave on the stage is laggy and only works intermittently. It's the same with mouseover and mouseout.

Here's the code that's laggy and intermittent:

stage.addEventListener("mouseenter", fl_MouseOverHandler.bind(this));
stage.addEventListener("mouseleave", fl_MouseOutHandler.bind(this));

function fl_MouseOverHandler(){
    this.btnOverAnim.gotoAndPlay("on");
}

function fl_MouseOutHandler(){
    this.btnOverAnim.gotoAndPlay("off");
}

I also tried mouseover and mouseout on a button the entire size of the stage and I got the same issue. (Also doing it this way doesn't work at all from inside a frame, and the ad is served inside a frame). I put the var frequency way up to 90 to see if that would help with the lagging, it didn't.

This was the simple mouseover / mouseout code I tried:

var frequency = 90;
stage.enableMouseOver(frequency);

this.bgCta.addEventListener("mouseover", fl_MouseOverHandler.bind(this));
this.bgCta.addEventListener("mouseout", fl_MouseOutHandler.bind(this));

On the createJS website it says "You can monitor whether the pointer is over the canvas by using stage.mouseInBounds AND the mouseleave / mouseenter events." So I'm wondering if using stage.mouseInBounds will help (but I can't find an example anywhere of how to use it). But I actually don't think it'll help because I think this whole problem is about createJS not reading where the mouse is fast enough.

Does anyone know how to fix this lagginess and intermittent firing? A work around? Why does createJS not just monitor the mouse events constantly like pure js?

Also mouseenter and mouseleave on the stage in createJS do not work on tablets or mobile and that's a problem, so it would be better to do this with mouseover and mouseout on a button the entire size of the stage. I did try using mouseover and mouseout and having 3 pixels space around the button between the edge of the button and the edge of the ad banner, this helped, but it was still firing intermittently.

Your thoughts and ideas please.

Agent Zebra
  • 4,410
  • 6
  • 33
  • 66

2 Answers2

3

Mouseover checks are expensive. A canvas is essentially just a bitmap, so EaselJS can't use mouse events from the browser (you just get one for the entire canvas). Instead, mouseover in EaselJS requires every element to be drawn to a 1x1 pixel canvas, and then checked for fill. This gives pixel-perfect detection, but is costly if you are either checking a lot of content, or checking too often.

Reduce your frequency: It looks like you have set the frequency to 90. This is really high (11 ms between checks, which is basically trying to achieve 90 fps). The default is 10, which is slower than a good framerate, but fast enough to feel responsive. You can probably bring it down to 20 or so to give you a peppy check without it being unnecessarily high.

Modify interactivity: Another thing you can do is filter out exactly what gets checked. By default, all display objects get checked -- but you can reduce this by turning off mouseEnabled on anything you don't care about (omitting them from the check), and turning off mouseChildren on containers that you want to treat as a single object (so something like a complex button is drawn once, instead of all its contents being drawn individually).

// Example
myBackground.mouseEnabled = false;
myButton.mouseChildren = false;

Hope that helps!

Lanny
  • 11,244
  • 1
  • 22
  • 30
  • This is nice in theory, but in practice it does not work. I tried your suggestions. The issue is with **mouseenter**, **mouseleave**, **mouseover** and **mouseout** being excessively taxing on the canvas. When money was on the line, the only thing that alleviated the performance degradation was **stage.mouseInBounds**. I'm pretty sure this issue is not just with Adobe Animate or createJS, but with the html5 Canvas. None-the-less, the issue in this instance is happening and is alleviated in Adobe Animate. – charlesclements Oct 17 '21 at 02:48
0

Friends, I know this was asked 4 years ago, but the lagginess in Adobe Animate CC V.21 is no different (horrible) regarding mouseenter, mouseleave, mouseover and mouseout. After 10 times of rolling over/out the page becomes unresponsive. I was able to alleviate this using stage.mouseInBounds on a setInterval. The original poster could not find an example, so here is what I did:

// Place this in a keyframe on the timeline where the named cta exists.

setInterval(function(scope){ 
    if(stage.mouseInBounds){
        createjs.Tween.get(scope.cta).to({scaleX:1.1, scaleY:1.1}, 150);
    }
    else{
        createjs.Tween.get(scope.cta).to({scaleX:1, scaleY:1}, 150);
    }

}, 150, this );

Make sure to pass this into the end of the setInterval function as an argument for the callback function as to not lose scope. I am guessing this can be reworked to use gotoAndPlay() on the timeline, in this instance the built-in tweener for CreateJS sufficed for what I needed.

Dharman
  • 30,962
  • 25
  • 85
  • 135
  • Running a tween every 150ms is not a good approach, and in this example, as long as the mouse in bounds, 6 new tweens are created per-second that basically do nothing. You could easily leverage the native mouse events on the canvas element directly (mouseover, mouseout), which would be more efficient. – Lanny Oct 02 '21 at 16:55
  • @Lanny, (mouseover, mouseout) are even more expensive than checking stage.mouseInBounds with a few tweens that may do nothing. The whole reason to jump thru these burning hoops with **stage.mouseInBounds** is because after 10 mouseovers, the experience is completely unresponsive. Perhaps my example can be optimized to fire a tween once per.. Your comment "You could easily leverage the native mouse events on the canvas element directly (mouseover, mouseout), which would be more efficient." leads me to believe you didn't read the original poster issue and/or have not tried this in Adobe Animate. – charlesclements Oct 17 '21 at 02:33