Skip to content
CatLabInteractivePublic

About

GUI engine combining easeljs and backbonejs. Developed to be used with flash cc html5 output, but can be used with any easeljs content.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

easelbone

A GUI engine combining EaselJS and Backbone.js. Originally developed for use with Flash CC HTML5 output, but can be used with any EaselJS content.

Features

  • Navigatable views with keyboard, mouse and touch support (single-touch is enabled on the stage; new easelbone.Views.Root({ ..., touch: false }) opts out)
  • UI controls: sliders, checkboxes, selectboxes, and buttons
  • Scrollable containers with list and float layouts, scrolled by wheel, scrollbar, keyboard focus or dragging the content (touch)
  • Text rendering with auto-sizing and emoji support
  • Alpha mask support
  • Asset loading and management
  • Built on top of AMD modules (RequireJS)
  • Opt-in dirty rendering (new easelbone.Views.Root({ ..., dirtyRendering: true })): the stage ticks every frame but is repainted only when the picture changed. After each tick the root view walks the display list as the painter would (hidden subtrees and the inside of cached objects are skipped) and compares a fingerprint of everything that decides the picture: transforms, alpha, child order, MovieClip and Sprite frames (nested at any depth, independent or synched), text, images, video time, masks, shadows, redrawn Graphics. No invalidate() calls are needed for changed display objects, also not for changes made outside a tick. See Dirty rendering below.

Documentation

Visit the documentation and examples page for a full overview of the library and live demos.

Installation

npm install easelbone

Or with Bower:

bower install easelbone

Examples

Live examples are hosted on GitHub Pages:

Pull request previews are automatically deployed to https://catlabinteractive.github.io/easelbone/pr/<PR_NUMBER>/examples/.

Development

# Install dependencies
npm install
npx bower install

# Build
npm run build

# Watch for changes
npx grunt watch

# Headless tests (need `npx playwright install chromium` once)
npx http-server dist -p 8080 --silent &   # serve the build first
npm run smoke                             # every example page renders cleanly
npm run test:baseline                     # BigText vertical centering (self-serving)
npm run test:touch                        # touch on the stage, drag scrolling (self-serving)
npm run test:dirty                        # dirty rendering, nested MovieClips (plain node, no browser)

Note: BigText fits and centers text on the measured glyph bounds (TextMetrics.actualBoundingBox*), so the drawn ink never leaves the available space and manual BigText.setFontOffset(...) calls are no longer needed in modern browsers — even for decorative fonts whose glyphs extend beyond their em box or advance widths. Registering an offset still works and takes precedence (restoring the fully legacy behavior for that font), as does the legacy heuristic on browsers without extended TextMetrics.

Dirty rendering

Off by default. With dirtyRendering: true the root view paints a frame when one of these is true:

  1. the display-list fingerprint differs from the previous frame, plus the two frames after that;
  2. a view's tick() returned true (Views.Base.tick() returns false when it is ticked by a dirty-rendering root view and true otherwise, so a view that does not override it leaves the decision to the fingerprint; a view that overrides it and returns true keeps painting every frame);
  3. rootView.invalidate() was called, the mouse was pressed or released over the stage, or the page became visible again (a mouse move does not paint: hover visuals are display properties, which the fingerprint sees);
  4. an image the walk has met finished loading (a sprite sheet that was still loading, a src swapped for a picture of the same size), or an easelbone object asked for it: an emoji image that arrived after its text was painted, a Fill that is laid out at draw time or whose image finished loading (it listens for the load itself, and nothing is painted for it while the image loads), a pinned object that moved;
  5. nothing was painted for rootView.heartbeatInterval ms (default 500): a change nothing noticed shows that late instead of not at all.

What the fingerprint cannot see, and needs rootView.invalidate(): pixels drawn into a canvas that a Bitmap shows, a display object with a custom draw() (also one that draws a hover state from the mouse position), a Graphics command whose fields are edited after it was appended. (A Graphics object that is cleared and redrawn, or appended to, is seen. A Text counts whether or not it was given a font.)

Other things to know:

  • A MovieClip or tween that changes nothing visible (under a hidden or cached ancestor) no longer causes paints. A cached container shows what is below it only after updateCache(), as always.
  • rootView.render() (and so setView() and resize()) ticks the stage before painting, as stage.update() does without the option, with no time passed (delta: 0: a clip with a framerate does not advance). It is one paint: the next frame is compared with what it painted. rootView.update() only paints.
  • rootView.paintCount counts stage paints in both modes; a host can show paints per second next to the ticker FPS.
  • easelbone.DirtyRendering exposes fingerprint(stage) and isActive(). Its presence also tells a host that this build decides on the display list. Up to 1.2.18 the option painted while any MovieClip advanced or any tween was active, visible or not, and missed changes made outside a tick.
  • Per root view: isActive() answers for the root view whose views are ticking, rootView.invalidate() paints that root view only. What easelbone objects raise is seen once by every dirty-rendering root view.
  • rootView.setDirtyRendering(false|true) switches the mode at run time; rootView.destroy() (also called by remove()) stops the tracker and removes the ticker, stage and page listeners.

Releasing

npm run bump        # or bump:minor — bumps package.json, commits, creates the vX.Y.Z tag
npm publish

npm publish wraps itself around that:

  • prepublishOnly runs bower install && npm run build, so a stale or missing dist/scripts/easelbone.js can never be published.
  • The published tarball is limited to the built bundle and its source map (see the files field) — the examples, sources and tooling stay in the repo.
  • postpublish pushes the branch and the new tag with git push --follow-tags, then creates the matching GitHub Release with auto-generated notes (gh release create ... --generate-notes --verify-tag). This needs the GitHub CLI to be installed and authenticated (gh auth login); --verify-tag makes it abort rather than invent a tag if you published without bumping first.

License

MIT

About

GUI engine combining easeljs and backbonejs. Developed to be used with flash cc html5 output, but can be used with any easeljs content.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages