Scaling and Stretching with the ScaleBitmap Class

We are always looking for ways to optimize, simplify, or create better workflows in CreateJS, and the ScaleBitmap is a great example of this. Using an old Flash approach, the ScaleBitmap class, shipped in the “extras” folder in EaselJS, uses a simple grid approach to create elements that scale and stretch, providing some flexibility to a raster design.

We know, we know… ScaleBitmap (aka Scale9 or 9-slice), was a UI pattern long before Flash, but it was certainly popularized by Adobe when it was included as a built-in behaviour in Flash and ActionScript 2. We were huge fans, and even provided a Bitmap workaround, as Flash’s implementation was limited to vector content.

How it works

Scale9 splits rectangular content into a 3×3 grid.

Unscaled ScaleBitmap Grid

The 3×3 grid used by ScaleBitmap

  • The four corners (1,3,7, and 9) are drawn at normal size on the outside corners of the scaled sprite
  • The top and bottom borders (2 and 8) are scaled horizontally ↔️
  • The left and right borders (4 and 6) are scaled vertically ↕️
  • And the center (5) is scaled both horizontally and vertically ↔️ + ↕️
Stretched Scale9 Grid

The grid, stretched vertically and horizontally.

This lets you create sprites that can be scaled to any size, while distorting parts of the content in a predictable way. In the sample shipped with EaselJS, a simple speech bubble image has been provided, which scales to random sizes when clicked.

sample image with a grid overlay

ScaleBitmap Sample Image

See the Pen ScaleBitmap by CreateJS (@createjs) on CodePen.31824

Here is a quick codepen fork of the previous demo, where the image can be swapped out to see better how the content scales (apologies to Grant for using his likeness).

Usage and Examples

To use the ScaleBitmap class, download and include it in your project (EaselJS does not include it as part of the minified or combined libraries). You don’t have to ensure your images are loaded before creating instances, but they will not render until the images are ready.

The grid is specified using a CreateJS Rectangle that defines the center square (x, y, width, and height).

var sb = new createjs.ScaleBitmap(“path/to/image.png”, 
    new createjs.Rectangle(12, 12, 5, 10));
sb.setDrawSize(200, 100); // Set an initial draw size.
stage.addChild(sb); // Add to stage

This exact idea was used in this anniversary codepen, allowing the text in the bubble to change, and the bubble to scale to fit the contents without distorting the graphics.

See the Pen Happy 2 years, Chris by CreateJS (@createjs) on CodePen.31824

Note that the ScaleBitmap EaselJS class is intended for image-based content. It is also possible to cache dynamic content, and apply ScaleBitmap afterwards. Here is an example. Other approaches might make more sense for assets drawn with vector Graphics (such as changing properties using Commands).

ScaleBitmap is not currently supported by StageGL.

Part of a Larger Solution

Creating high fidelity experiences now often comes with the cost of creating assets for a bunch of different resolutions, perspectives, and even performance profiles. It means content must be authored at retina (and higher) resolutions to work on any device, and potentially sends a ton of content over the network, or requires complex loading schemas to choose the right asset to download and display.

With initiatives like Google’s AMP Project for a faster web browsing experience, tools like Webpack to compile and split up assets, new protocols like HTTP/2 to speed up browsing in general, and even industry best-practices like using ImageOptim for super-compressing PNGs, it’s clear there is still a need for optimized content. We like to think that utilities like the ScaleBitmap can help chip away at this challenge.

2 thoughts on Scaling and Stretching with the ScaleBitmap Class

Comments are closed.

© Copyright 2024