CreateJS is a JavaScript framework that makes use of the HTML5 Canvas, rather than the HTML DOM, to make graphic-based objects, such as shapes, buttons, and text. The integration of CreateJS with FlexJS lets CreateJS developers take advantage of coding in ActionScript (a cousin of JavaScript, with true classes and strong data typing). Further, CreateJS applications can use MXML for layout and definition.
Getting Started
The examples on this page require the installation of the Apache Flex SDK which can be found on the Getting Started With FlexJS page in order to run.
This section mimics the tutorial found on the Getting Started Guide on the CreateJS site. The example below uses a command line approach and can easily be adapted to a FlexJS-compatible IDE.
Using EaselJS
Create a new directory for your FlexJS project and in the directory make a sub-directory called src
. Change to the src
directory and create a file called, Demo.mxml
. Open the file and add the following Application
tag and content:
<cjs:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:js="library://ns.apache.org/flexjs/basic" xmlns:cjs="library://ns.apache.org/flexjs/createjs" > <js:valuesImpl> <js:SimpleCSSValuesImpl /> </js:valuesImpl> <js:initialView> <cjs:View> </cjs:View> </js:initialView> </cjs:Application>
Notice that the namespace for the Application
tag is cjs
and the cjs
namespace is defined to bring in all of the FlexJS CreateJS component framework. You will identify FlexJS CreateJS elements using the cjs
namespace. The FlexJS CreateJS Application
tag creates the HTML5 Canvas automatically.
Within the cjs:View
element, add the following MXML tags to create a CreateJS circle.
<cjs:Circle id="circle" x="100" y="100" radius="50"> <js:fill> <js:SolidColor color="#26C9FF" /> </js:fill> </cjs:Circle>
Save the file and compile it:
${FLEXJS_INSTALLDIR}/js/bin/mxmlc Demo.mxml
Once the compilation is complete, you will find a bin
directory parallel to the src directory. Open ../bin/js-debug/index.html
in a browser. You should see a blue circle.
Using TweenJS
Continue with the previous example where you already have a circle to work with. You will add some MXML declarations for the tweens and a bit of ActionScript code to trigger them. Copy the following MXML declarations and fx:Script
block into the Demo.mxml
file, above the js:initialView
definition:
<js:beads> <js:ApplicationDataBinding /> </js:beads> <fx:Declarations> <cjs:Sequence id="seq" target="circle" loop="true"> <cjs:Tween id="tween1" target="circle" xTo="400" duration="1000" easing="{Ease.getPowInOut(4)}" /> <cjs:Tween id="tween2" target="circle" alphaTo="0" yTo="175" duration="500" easing="{Ease.getPowInOut(2)}" /> <cjs:Tween id="tween3" target="circle" alphaTo="0" yTo="225" duration="100" /> <cjs:Tween id="tween4" target="circle" alphaTo="1" yTo="200" duration="500" easing="{Ease.getPowInOut(2)}" /> <cjs:Tween id="tween5" target="circle" xTo="100" duration="800" easing="{Ease.getPowInOut(2)}" /> </cjs:Sequence> </fx:Declarations> <fx:Script> <![CDATA[ // the import is required by the Ease functions in the data binding import org.apache.flex.createjs.tween.Ease; ]]> </fx:Script>
The fx:Declarations
tag in MXML is where you put non-visual items that are referenced in the app. Here, a set of Tween
s is declared for the circle and surrounded by the Sequence
tween which forces the individual Tweens to play in the order specified. Note that the easing function on some of the Tween
s is specified using binding to an expression.
In order for the Sequence
to happen however, the Sequence's play()
function, needs to be triggered by an event. Modify the cjs:Application
tag with an applicationComplete
event handler to call the play
() function:
applicationComplete="seq.play()">
Save the file and compile it:
${FLEXJS_INSTALLDIR}/js/bin/mxmlc Demo.mxml
Open the ../bin/js-debug/index.html
file in a browser. You will see the circle move and fade across the screen. The loop
option on the Sequence
will make it run continuously.
You can see the complete code below.
Comparison
This section examines the demonstration code (above) in more detail and compares it with the original CreateJS demo code. The example looks like this:
<html> <head> <script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script> <script> function init() { var stage = new createjs.Stage("demoCanvas"); var circle = new createjs.Shape(); circle.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, 50); circle.x = 100; circle.y = 100; stage.addChild(circle); stage.update(); } </script> </head> <body onload="init();"> <canvas id="demoCanvas" width="500" height="200"></canvas> </body> </html>
The original CreateJS example is an HTML page with a Canvas
in the body of the page. A JavaScript function is used to programmatically create the circle and insert it onto the Stage
(the CreateJS root of its own DOM structure or display list). The corresponding FlexJS MXML file looks like this:
<cjs:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:js="library://ns.apache.org/flexjs/basic" xmlns:cjs="library://ns.apache.org/flexjs/createjs" > <js:valuesImpl> <js:SimpleCSSValuesImpl /> </js:valuesImpl> <js:initialView> <cjs:View> <cjs:Circle id="circle" x="100" y="100" radius="50"> <js:fill> <js:SolidColor color="#26C9FF" /> </js:fill> </cjs:Circle> </cjs:View> </js:initialView> </cjs:Application>
Unlike the original HTML, the MXML elements (or tags) define the size, placement, and color of the circle without using any code.
Beneath the covers, the FlexJS application creates an HTML5 Canvas
and sets up the drawing Stage
; FlexJS has wrapper classes for the CreateJS and EaselJS constructs (note that today only a few exist but the pattern to add more has been established). Using either ActionScript or MXML, the CreateJS components can be added to the stage and displayed.
An advantage to using the FlexJS MXML approach is that the compiler (or an IDE if you use one) can catch errors before you need to run the code. For instance, in the original JavaScript you could accidentally write, circle.c = 100
and the page would load fine and even execute, except the circle would not be where you thought it would be. Using FlexJS, if you mistyped "c" for "x" in the cjs:Circle
tag, the compiler would immediately spot the problem. If you use an IDE with FlexJS, you have code-completion in addition to syntax checking which will also help avoid errors.
In addition to EaselJS, the FlexJS CreateJS framework also includes a bit of TweenJS, the animation package. There is a small TweenJS example on the CreateJS page which looks like this:
<html> <head> <script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script> <script> function init() { var stage = new createjs.Stage("demoCanvas"); var circle = new createjs.Shape(); circle.graphics.beginFill("Crimson").drawCircle(0, 0, 50); circle.x = 100; circle.y = 100; stage.addChild(circle); createjs.Tween.get(circle, {loop: true}) .to({x: 400}, 1000, createjs.Ease.getPowInOut(4)) .to({alpha: 0, y: 75}, 500, createjs.Ease.getPowInOut(2)) .to({alpha: 0, y: 125}, 100) .to({alpha: 1, y: 100}, 500, createjs.Ease.getPowInOut(2)) .to({x: 100}, 800, createjs.Ease.getPowInOut(2)); createjs.Ticker.setFPS(60); createjs.Ticker.addEventListener("tick", stage); } </script> </head> <body onload="init();"> <canvas id="demoCanvas" width="500" height="200"></canvas> </body> </html>
The corresponding FlexJS MXML file looks like this:
<cjs:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:local="*" xmlns:js="library://ns.apache.org/flexjs/basic" xmlns:cjs="library://ns.apache.org/flexjs/createjs" applicationComplete="seq.play()" > <js:valuesImpl> <js:SimpleCSSValuesImpl /> </js:valuesImpl> <js:beads> <js:ApplicationDataBinding /> </js:beads> <fx:Declarations> <cjs:Sequence id="seq" target="circle" loop="true"> <cjs:Tween id="tween1" target="circle" xTo="400" duration="1000" easing="{Ease.getPowInOut(4)}" /> <cjs:Tween id="tween2" target="circle" alphaTo="0" yTo="175" duration="500" easing="{Ease.getPowInOut(2)}" /> <cjs:Tween id="tween3" target="circle" alphaTo="0" yTo="225" duration="100" /> <cjs:Tween id="tween4" target="circle" alphaTo="1" yTo="200" duration="500" easing="{Ease.getPowInOut(2)}" /> <cjs:Tween id="tween5" target="circle" xTo="100" duration="800" easing="{Ease.getPowInOut(2)}" /> </cjs:Sequence> </fx:Declarations> <fx:Script> <![CDATA[ // the import is required by the Ease functions in the data binding import org.apache.flex.createjs.tween.Ease; ]]> </fx:Script> <js:initialView> <cjs:View> <cjs:Circle id="circle" x="100" y="100" radius="50"> <js:fill> <js:SolidColor color="#26C9FF" /> </js:fill> </cjs:Circle> </cjs:View> </js:initialView> </cjs:Application>
The Tweens are declared in an fx:Declarations
block and correspond to the CreateJS tween.to()
functions written in JavaScript. You specify exactly the same things: target, duration, x position, y position, alpha value, and even easing functions. Once again, you can quickly declare your Tween
s and given them parameters, any of which can be specified using data binding.
FlexJS is a "pay as you go" system. The use of binding for the easing functions on the Tween
s necessitates the including of the js:ApplicationDataBinding
bead. Without the bead the data binding will not happen and should only be included in applications that use data binding to reduce their final footprint and runtime overhead.
Extending FlexJS CreateJS
At this time the FlexJS CreateJS framework is far from complete. CreateJS has a lot to offer and this foray into it via FlexJS just touches upon it and lays the foundation to extend it.
Components from the FlexJS Basic framework cannot be used with components from the FlexJS CreateJS framework. This is due to the fact that CreateJS uses the HTML5 Canvas as its drawing space and maintains its own DOM; the FlexJS Basic framework uses the HTML DOM.
If you look at the flex-asjs repository, specifically the frameworks/projects/CreateJS directory, you'll see how the FlexJS wrapper classes are composed. There is an Application class which provides the injection of the necessary CreateJS JavaScript downloads as well as creating the Canvas and the CreateJS Stage object.
From there, components use org.apache.flex.createjs.core.CreateJSBase
as their foundation class. Other "higher level" components such as Circle, Rect, Label, and TextButton build from there. The key part is the createElement
function. You can see how the CheckBox, for example, is composed from several different EaselJS elements. You would add any new components following this pattern.
Since CreateJS is an JavaScript-only framework, you can see that many of the classes use the COMPILE::JS
compiler tag to identify the code that only belongs on the JavaScript side (code that gets cross-compiled to JavaScript and does not have any relevance to the SWF). Any additional CreateJS structures or code should be wrapped in the COMPILE::JS
tag.
Keep in mind however, that when you specify an API (public functions or properties) these items should not be limited to
COMPILE::JS
blocks but be universally visible. This is so the properties and functions are available in MXML tags.
Once components are added, if they can be used from MXML, they must appear in the createjs-manifest.xml
file. Classes should also appear in the CreateJSClasses.as
file if they are not MXML components and can be used from ActionScript.