Introduction to Stage.js

Share this article

Stage.js
is a lightweight and open-source JavaScript library that you can use for cross-platform 2D HTML5 game development. This library uses a DOM-like model to manipulate the canvas and manages the rendering cycles of your application all by itself. In this tutorial, I’ll introduce you to this library, trying to cover everything you may need to know how to start using it with ease.
Let’s start!

Setup and Usage

Firstly, you have to download the library. You can get the latest version of Stage.js from its GitHub repository (here are included a few examples to get you started). If you prefer, you can also load it directly from a CDN. After including the core file, you have to add your own JavaScript file but be careful to not include your application files before the library.
<script src="https://cdnjs.cloudflare.com/ajax/libs/stage.js/0.8.2/stage.web.min.js"></script>
<script src="path/to/your/stage/application.js"></script>
Applications in Stage.js are created by passing callback function to Stage(). The library will then load all the required components. Finally, it’ll call the callback function and render everything on screen. Every app you create will have a tree, and stage will be at the root of that tree. All the other elements such as images or strings will be its nodes. The application tree is redrawn while the nodes are updated during each rendering cycle.

Pinning

Pinning determines how the nodes are attached to their parents. You can set a lot of options with pinning. A few of these are size, positioning, alignment, and transformation. Below you can find a simple example with the explanation of what it does.
Stage(function (stage) {
    stage.viewbox(700, 700);
    Stage.image('wheel')
        .appendTo(stage)
        .pin('handle', 0.5);
});

Stage({
    name: 'wheel',
    image: 'wheel.png'
});
We begin by specifying the viewbox size. We have appended the image wheel.png referenced as wheel to the stage. After that, we set the initial position of this image or node using handle. The handle on any node, places itself at a specified offset from the align point on its parent. Both handle and align are specified as relative units. For example, 0 is top-left and 1 is bottom-right. The above code positioned the wheel at the center of the viewbox. A live demo of the example is available on CodePen and shown below:

See the Pen YyKQLx by SitePoint (@SitePoint) on CodePen.

To position the image at a specific horizontal distance from the center you can use ‘offsetX’ as shown below:
Stage.image('wheel')
    .appendTo(stage)
    .pin({
        handle: 0.5,
        offsetX: 300
    })
);
Please note that the distance above is not 300px, but it’s 3/14 times the viewbox size. You can also set other values for nodes like scale, skew
, and rotation. To scale in a specific direction (horizontally, for instance), you can use scaleX. The code snippet below will scale the wheel horizontally by a factor of 1.4.
Stage.image('wheel')
    .appendTo(stage)
    .pin({
        handle: 0.5,
        scaleX: 1.4
    })
);
Here is the CodePen demo with scaled wheel applied. Rotation, scaling, and skewing by default will happen with the node center as pivot point. You can also set a different pivot point for nodes using:
node.pin({
    pivotX: x,
    pivotY: y
});
To sum it up, pinning the elements gives you the ability to move them around and scale or rotate them.

Mouse and Touch Events

To update nodes on user interaction you can use various mouse and touch events. Moving a step forward with the example of our wheel above, we could write the following code:
var wheelNode = Stage.image('wheel').appendTo(stage);
wheelNode.pin({
    'handle': 0.5
});
wheelNode.on('click', function () {
    // Do something with the wheel here.    
});
Alternatively, you can define these events like Stage.Mouse.CLICK = 'click';. The updated code would be:
wheelNode.on(click, function () {
     // Do something with the wheel here.    
 });
Another example would be Stage.Mouse.MOVE = 'touchmove mousemove';.

Tweening

Tweening applies smooth transitions to pinning values. This prevents abrupt changes in location or size of concerned nodes. For example, the code below will rotate the wheel abruptly by PI radians and change its position by 600 on each click.
var wheelRotation = Math.PI;
 var wheelPosition = 300;

 wheelNode.on('click', function () {
     wheelRotation = -wheelRotation;
     wheelPosition = -wheelPosition;
     this.pin({
         rotation: wheelRotation,
         offsetX: wheelPosition
     });
 });
This is the demo without tweening which is also shown below:

See the Pen YyKQvx by SitePoint (@SitePoint) on CodePen.

However, adding the tween method makes the transition smooth.
wheelNode.on('click', function () {
    wheelRotation = -wheelRotation;
    wheelPosition = -wheelPosition;
    this.tween(3000)
        .pin({
            rotation: wheelRotation,
            offsetX: wheelPosition
        })
        .ease('bounce');
});
Here you can find a demo with tweening and easing applied, also shown below so that you can see the difference:

See the Pen XmrgBb by SitePoint (@SitePoint) on CodePen.

There are a lot of available options like easing method, duration and delay. In the code above, I have set the duration to 3000 ms and easing function to bounce. Moreover, you can use several easing functions such as linear, quad, cubic
and quart. Setting a delay will start the transition after a specified delay. If there is no need of a node after the animation completes you can call tween.remove(); to remove the node. To perform some other operations, you can execute a callback function after tweening has completed using following snippet:
tween.done(function () {
    //Perform your actions here.
});

Texture Atlas

Textures are used by tree nodes to draw graphics on the canvas. To display graphics on the canvas you can use a sprite sheet also called “texture atlas”. Setting the name of texture atlas is optional. A sprite sheet needs to have a set of named textures. To use these in an application we can reference them by name. You can create animations using an array of textures as frame. An animation or anim itself is a node. Here is an example with an animated warrior:
Stage({
    name: "warriorsprite",
    image: {
        src: "warriorsprite.png"
    },
    textures: {
        w1: {
            x: 0 * 120,
            y: 0,
            width: 120,
            height: 320
        },
        w2: {
            x: 1 * 120,
            y: 0,
            width: 120,
            height: 320
        },
        w3: {
            x: 2 * 128,
            y: 0,
            width: 128,
            height: 320
        },
        w4: {
            x: 3 * 128,
            y: 0,
            width: 128,
            height: 320
        },
        warrior: ['w1', 'w2', 'w3', 'w4']
    }
});
To animate the warrior you need the following code. To make it faster you can increase the fps. :
Stage(function (stage) {
    stage.viewbox(320, 320);
    Stage.anim('warrior')
        .appendTo(stage)
        .pin('align', 0.5)
        .fps(8)
        .on('click', function () {
        this.play();
    });
});
To see the warrior animated, take a look at this demo or at the demo below:

See the Pen RWbgBj by SitePoint (@SitePoint) on CodePen.

anim also has a lot of other methods like gotoFrame(n), which will take you directly to the n-th frame. Depending on the value of n, you can also move n frames forward or backward using moveFrame(n) .

Conclusions

In this introductory tutorial, we covered everything that you need to know how to get started with Stage.js. The concepts discussed should help you creating basic character animations using sprites and interact with user. You can learn more about the library from the official website. I would also suggest you to download the files from its GitHub page. The included demos in downloaded file will further clear things up.

Frequently Asked Questions (FAQs) about Stage.js

What Makes Stage.js Different from Other JavaScript Libraries?

Stage.js is a 2D HTML5 JavaScript library for cross-platform game development. It is lightweight, fast, and highly flexible. Unlike many other JavaScript libraries, Stage.js focuses on providing a simple and intuitive API for creating and managing graphical objects. This makes it an excellent choice for developers who want to create interactive web applications or games without the need for complex coding or extensive knowledge of web graphics.

How Can I Install Stage.js?

Stage.js can be installed using npm (Node Package Manager). You can install it by running the command npm install stage-js. After installation, you can import it into your project using the require function.

Can I Use Stage.js for Mobile Game Development?

Yes, Stage.js is designed to be cross-platform, which means it can be used for developing games on both desktop and mobile platforms. It has a responsive design that automatically adjusts to different screen sizes and resolutions, making it ideal for mobile game development.

How Do I Create a New Stage in Stage.js?

Creating a new stage in Stage.js is straightforward. You can use the Stage.create method to create a new stage. This method takes an options object as a parameter, which can be used to set various properties of the stage, such as its width, height, and background color.

How Can I Add Images to My Stage.js Project?

Stage.js provides a simple and intuitive API for adding images to your project. You can use the Stage.image method to create a new image object, and then add it to your stage using the addChild method.

What is the Role of the TC39 in the Development of Stage.js?

TC39, or Technical Committee 39, is a group that evolves JavaScript. While they are not directly involved in the development of Stage.js, their work on JavaScript standards and proposals can influence the features and capabilities of Stage.js and other JavaScript libraries.

How Can I Contribute to the Development of Stage.js?

Stage.js is an open-source project, and contributions from the community are always welcome. You can contribute by reporting bugs, suggesting new features, or submitting pull requests on the project’s GitHub page.

How Can I Optimize Performance in Stage.js?

Stage.js is designed to be fast and efficient, but there are several things you can do to optimize performance. These include minimizing the number of objects on the stage, using sprite sheets instead of individual images, and avoiding unnecessary calculations in your game loop.

Can I Use Stage.js with Other JavaScript Libraries?

Yes, Stage.js can be used alongside other JavaScript libraries. It does not modify any global objects or prototypes, so it should not interfere with other libraries.

Where Can I Find More Information and Tutorials on Stage.js?

The official Stage.js website and GitHub page are great resources for more information and tutorials. You can also find a wealth of information on various web development forums and blogs.

Baljeet RathiBaljeet Rathi
View Author

Baljeet is a writer and web developer based in India. Although he is a full-stack developer, he is most passionate about things related to the front-end. He has been involved with web development for more than five years now.

AurelioDgame programminggamesJavaScriptjavascript librariesStage.js
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week