CreateJS New Driver's Guide
Categories: Study

Photographed at Sabah Mangrove Fireflies
TL;DR
Recently, I have been learning and exploring some front-end interactive game technologies. It happened that a small game used CreateJS technology. I take this article as a memo for its use, and also let students who want to use CreateJS to write small games get started quickly.
Notes are based on the latest version 1.0. There are many inconsistencies with old tutorials on the Internet. It is also recommended to use the latest version. The main contents are as follows:

Overview
Introduction
CreateJS is a suite of modular libraries and tools based on HTML5. Based on these libraries, games, animations and interactive applications based on HTML5 can be developed very quickly.
History can be traced back to 7 years ago when flash use slowly decreased. gskinner developed it as a “next generation” rich interactive tool library. A project officially funded by Adobe, Microsoft, and Firefox. The API is very similar to Flash in many places, and can be directly exported to Canvas for use in Web via Adobe Animate CC (replacing Flash).
Version 1.0 was finally released in 2018, and version 2.0 is officially under development. I believe there will be a more modern Createjs presented to developers soon.
Module Composition
The 4 modules provided by CreateJS can help handle common operations in game development:
- EaselJS: Used for drawing bitmaps, graphics, Sprites, text, and also includes Ticker timer
- TweenJS: Used to create tween animation effects
- PreloadJS: Preloading and management of game resources, including images, audio, json and other resources
- SoundJS: Play and process audio
Better Usage
Currently, the official version of createjs does not support usage via npm, which causes the need to manually introduce a <script> tag in html in ES6 development, which is inconvenient for modular development.
createjs-npm adds a layer of glue to the official library through imports-loader and exports-loader, allowing everyone to use it like using npm packages. Specifically:
// After installation, usage is consistent with official createjs 1.0
npm install createjs-npm -S
// Import all modules
import createjs from 'createjs-npm';
// Only import a single module (xx can be easel, preload, tween, sound)
import createjs from 'createjs-npm/lib/xx';
Usage of EaselJS
EaselJS assumes the drawing ability in Createjs. For example, if you want to draw pictures, graphics, frame animations, text, you can use its API to implement.
Steps
For example, if you need to draw a red circle, the required steps are Create Stage -> Create Object -> Set Object Properties -> Add Object to Stage -> Update Stage to Render Next Frame:
//Create a stage, get a reference canvas
const stage = new createjs.Stage("myCanvas");
//Create a shape display object
const circle = new createjs.Shape();
circle.graphics.beginFill("red").drawCircle(0, 0, 40);
//Set position of shape instance
circle.x = circle.y = 50;
//Add shape instance to stage display list
stage.addChild(circle);
//Update stage will render next frame
stage.update();
The effect of the above code is:
See the Pen Demo by Tw93 (@tw93) on CodePen.
Graphics Class
In the above Demo, we created a Shape. Actually, a canvas is created here. If you need to draw things on the canvas, you need to use the Graphics class.
Many styles can be set on Graphics, or call drawing methods to draw other graphics. At the same time, all drawing methods in the Graphics class will return a graphics instance. Using chaining operations here will be very convenient. See 【EaselJS API】 for specific usage.
EaselJS Elements
As mentioned above, EaselJS can be used to draw images, graphics, animation frames, text. Correspondingly, they are Bitmap, Shape, Sprite, Text. Specific usage is:
// Use Bitmap to represent image
const bitmap = new createjs.Bitmap("imagePath.jpg");
// Use Shape combined with Graphics to represent graphics
const shape = new createjs.Shape();
shape.graphics.beginFill("#ff0000").drawRect(0, 0, 100, 100);
// Use Sprite to represent sprite animation (introduced in detail later)
const instance = new createjs.Sprite(spriteSheet);
instance.gotoAndStop("frameName");
// Use Text to represent text
const text = new createjs.Text("How are you", "20px Arial", "#000000");
Sprite Animation
This feature will make students who come into contact for the first time happy. It is very convenient to use, and the implementation effect is great. For example, if you need to implement a gentleman walking:
See the Pen Sprite by Tw93 (@tw93) on CodePen.
【Tip】The generation of sprite sheet here can use TexturePacker. There is an option to export as EaselJS. Just replace the value with SpriteSheet directly.
The above code should express the meaning well. You can try setting a few more actions in animations to make it more interesting. For more detailed usage, please refer to SpriteSheet Class
Ticker Refresh
Main Function
The movement of the characters mentioned above relies on Ticker to refresh the stage in real time. At the same time, addEventListener can be used to listen to the refresh of tick and “do something” inside.
createjs.Ticker.framerate = 60;
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;
sprite.addEventListener("tick", ()=>{console.log("doing something"});
Focus Points
createjs.Ticker.framerate indicates Ticker frame rate. Ideally it is 60FPS. Here it can be set to 60 during game experience optimization.
createjs.Ticker.timingMode indicates Ticker’s rendering mode (setTimeout, requestAnimationFrame). Can choose like this:
- TIMEOUT: Default mode. This mode updates the next time through setTimeout. Although it provides a predictable and flexible frame rate, it is much worse than requestAnimationFrame in performance experience. Not recommended.
- RAF: Simply use RAF. Will ignore frame rate equivalent values set by framerate. Frequency depends on the running environment and browser performance at that time.
- RAF_SYNCHED: It will try to coordinate RAF and the set framerate frequency. Equivalent to combining the advantages of setTimeout and RAF. That is, here you can set framerate=60, optimize to let CreateJS help handle. Recommend using this mode.
Optimization Points
At the same time, it can be combined with Ticker.paused for performance optimization. For example, when we pause the game, we can prevent constant refreshing like this:
createjs.Ticker.addEventListener('tick', (e) => {
!e.paused && stage.update();
});
createjs.Ticker.paused = true; //Calling this anywhere will pause processing inside tick
createjs.Ticker.paused = false; //Calling this anywhere will resume processing inside tick
In the process of performance tuning, createjs.Ticker.getMeasuredFPS() can be used to output the real-time frame rate to the screen. When this value is very close to the set framerate, it indicates good performance.
Usage of TweenJS
From the above, we can see that EaselJS can actually handle many things in CreateJS development. The other three items can be used as auxiliary tools to make development more convenient.
TweenJS acts as the ability of “movement” here. At the same time, it can also be used independently. It supports numeric object properties and CSS style properties. It is a very powerful tween animation function library.
Case
For example, the following classic animation example:
See the Pen TweenJS by Tw93 (@tw93) on CodePen.
Usage
It can be seen that chain processing makes many operations very simple to use. That is, you can get the target element, set wait time, execute next animation, animation end event;
In general scenarios, the above is completely enough. There are also the following advanced features, which can be queried through 【Document】:
- createjs.Ease: Set animation easing effect, including numerous animation Ease effects available, such as linear/bounceIn/circInOut/getBackIn/quadInOut
- ColorPlugin: Color value processing plugin, can handle any color supported by CSS
- CSSPlugin: Need
createjs.CSSPlugin.install();registration before use, can handle styles in most CSS - RotationPlugin: Through
RotationPlugin.install(props);, used to handle angle problems - MotionGuidePlugin: Guide animation effect, need
createjs.MotionGuidePlugin.install(createjs.Tween);before use, implement path animation effect by setting a series of paths - Timeline: Used to process multiple groups of animation effects, allowing them to be controlled group by group
Usage of PreloadJS
PreloadJS is a class library used to manage and coordinate related resource loading. It can conveniently help you preload related resources.
It mainly uses the LoadQueue class to manage loaded content. A common scenario in games is preloading image resources and game music.
Case
In the screen, you can see the processed image loaded, and background music is playing at the same time:
See the Pen PreloadJS by Tw93 (@tw93) on CodePen.
Usage
Loading Method
const queue = new createjs.LoadQueue(false);
Pass in a boolean value to indicate whether to use XHR or HTML tags to load. Default is true, which is to use XHR to load. However, XHR loading cdn often reports some errors, so it is recommended to use false type, load through tags.
Resource Loading and Usage
Through loadManifest class, you can load a group of all resources used in the game, including images, audio, json, svg and other files. id is used as identifier after loading, accessed through queue.getResult(id).
During resource loading, there are complete, error, progress, fileload for subscription. Only after completion can resources be used. progress and complete combine to display progress bar. fileload indicates a single file is loaded.
Loading Music
When loading music, need to register Sound plugin, i.e., queue.installPlugin(createjs.Sound);, meanwhile specify music file format, e.g., createjs.Sound.alternateExtensions = ["mp3"];
There is a small pit here. For lower version browsers, music may not play. Can introduce HTMLAudioPlugin to solve: createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin])
For music playback, use createjs.Sound.play(id);. Detailed usage introduced in SoundJS later.
Usage of SoundJS
If a small game wants to have good interactivity, background music is indispensable. Can choose some relaxed and lively ones. Need to use SoundJS to “play music”, and have perfect compatibility processing.
Sound Class
Audio management mainly uses Sound class, with following functions:
- Sound.registerSound: Register audio to be played. registerSounds supports multiple audios. Need to register in advance before audio playback (loading here can actually also use preload),
- Sound.registerPlugins: Register audio playback plugins. Generally used for incompatible low browser scenarios. Can register to be compatible with WebAudioPlugin or HTMLAudioPlugin
- Sound.play: Play audio, generally
createjs.Sound.play(id)
AbstractSoundInstance Playback Instance Class
When we call Sound.play API, we actually create an AbstractSoundInstance class. After creation, we can use it to directly control audio playback or other operations, and listen to its playback status:
const myInstance = createjs.Sound.play("myAssetPath/mySrcFile.mp3");
// Property control, select needed properties to set in practice
// Properties can also be added to play second parameter as object
myInstance.volume = 0.5;
myInstance.paused = false; // Control music pause or not
myInstance.loop = true; // Loop playback
myInstance.duration = 30; // Playback duration
// Listen to status, commonly used for error, re-play
myInstance.on("complete", handleComplete);
myInstance.on("loop", handleLoop);
myInstance.on("failed", handleFailed);
Performance Experience Optimization
Image Optimization
- Image size affects performance more than normal H5. Try to use appropriate size and images compressed by tinypng
- For sprite sheets or many small image scenarios, use TexturePacker tool to synthesize them into one sprite sheet
- For frame animation scenarios, use gka tool to compress images and directly generate animation files
Make Good Use of Recycling Mechanism
- Destroy timely for those outside the screen or not in the stage
- Use cache for complex objects to increase performance. Try not to use for simple ones, will have counter effect
- SpriteSheetBuilder way can replace cache, and effect is better
Use More Bitmaps Less Vectors
- Vector operations in CreateJS affect performance relatively. Strangely Text shape are counted as vectors. Suggest directly converting text and vector images to bitmaps through tools here
- If some projects must use vectors, filters, overlay modes, or contain very many sub-components, can optimize by using SpriteSheetBuilder for bitmap rendering
- Mask in animateCC is equivalent to framing the whole animation sequence, vectorizing, so try to use less. If really have to use, operation method is same as handling vectors above
Filter and Animation Scene Optimization
- Do not use filter effects such as (shadow filter and glow filter) to do animation, because this will consume performance very much, performance uncontrollable on mobile end
- Can use frame-by-frame images to replace related filter effects to achieve animation effects
Reduce Nesting and Overlapping
- When doing animation or other scenarios, try not to have too much container nesting, try to flatten the hierarchy (a bit like writing Weex, paying attention to flat and thin)
- Some overlapping scenarios can be replaced directly with images
Frame Rate Optimization
- Cancel frame rate listening timely if not used, such as tick
- Use
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED - Set
createjs.Ticker.framerateslightly higher than expected - Through
createjs.Ticker.getMeasuredFPS()output real-time FPS to screen, perform optimization
Try StageGL Artifact
- StageGL is not introduced in current compressed version, need to introduce additionally
- Usage is similar to Stage, equivalent to changing original Stage to StageGL, but equivalent to using WebGl capability, performance will be much better than original, see GETTING STARTED WITH STAGEGL for more details
// Conventional 2D scene
const stage = new createjs.Stage("canvasId");
// Use WebGl
const stage = new createjs.StageGL("canvasId");
Mobile End Click Event Optimization
When initializing our game, generally need to bind click events for it, but for mobile end adding this sentence will have much better effect
var stage = new createjs.Stage("canvasId");
createjs.Touch.enable(stage);
End
CreateJS features should be more than these. More need to be used in actual projects. Many interesting usages can be discovered through various game scenarios. If you also have insights on H5 interactive mini game development, welcome to communicate together.