A common performance trick in EaselJS is to layer multiple Stages, and only update content on the Stage instance that changes. For example, a background might contain an complex scene with interactive elements or UI, and an overlapping foreground scene that has animated sprites that is updated frequently. Layering stages can you minimize how often the complex content is rendered.
An issue arises if both stages (or even just the background) have interactivity. HTML DOM elements block mouse interaction with elements that are below their bounding rectangles. The CSS pointer-events API addresses this for individual elements (and its fairly well-supported now!). But when working with EaselJS, which draws content to a single square element, the need arises to let mouse events conditionally pass-through canvases higher in the DOM order.
The nextStage property
Good News! There is a nextStage
property on the Stage, built specifically to address this need. Initially added in EaselJS 0.7, and super-charged in 0.8, the nextStage property (link to docs) properly throttles all mouse events not handled on the current stage to the “next” stage.
The nextStage is super simple to apply, and you can layer stages to your heart’s content.
var stage1 = new createjs.Stage(“topCanvas”); var stage2 = new createjs.Stage(“bottomCanvas”); stage1.nextStage = stage2;
The “top” canvas should be higher in the DOM order, since it needs to intercept DOM events, and pass them to the next canvas if necessary. EaselJS will relay all DisplayObject mouse events, and even makes sure lower stage events, such as “mouseenter” and “mouseleave” are triggered properly.
Demos and Examples
For a full demo, check out the “TwoStages” example in the EaselJS GitHub, or the live example on CodePen. A StageGL demo is available as well, showing interaction between 2D Stage instances, and WebGL-accelerated StageGL instances. Pair this technique with other performance-improving techniques, such as liberal use of “mouseChildren” and “mouseEnabled” to optimize your HTML5 apps and websites!
Like this article? We are planning to release more mini-articles, including more performance tips and exposés on obscure or advanced features. Let us know in the comments!
Super cool! Will Adobe Animate utilize these features?
Out of the box, Animate just has the one Stage, so there is no real way for them to support this behaviour without some IDE changes. Its more a manual operation thing, and you could definitely throw two container clips on your Animate stage (instead of one), and then manually instantiate them on different Stages, instead of just using the generated
exportRoot”.
Cheers!
Dear Lanny,
(a) re: “…and then manually instantiate them on different Stages.~
(b) It sems to contradict your stating that “Animate just has the one Stage”
This begginner asks >>> Could you elaborate on (a) above? Would it involve editing HTML generated by Animate?
Also, please supply a site address where I can learn what exportRoot is about and its purpose.
Specifically, in Animate, is there any other workaround for maintaining (1) a static background and (2) an animation on forefront. I guess using two containers would not prevent createjs from refreshing everything onscreen.
Thanks for earlier reply on stackoverflow (so far not fully understood)
otherelse
PS – Found this on YT but could follow the visual “explanation”.
https://www.youtube.com/watch?v=KjOMRpLm01c
Adobe Animate has a single stage that you work with (the `root` if you came from the flash world). When your document is exported, a root-level movieclip is created that represents that stage, which we called “exportRoot”.
You can check out this getting started guide: http://blog.gskinner.com/archives/2015/04/introduction-to-the-flash-cc-html5-canvas-document.html