DEV Community

Cover image for Theatre.js: Create intricate and powerful animations in JavaScript
Matt Angelosanto for LogRocket

Posted on • Originally published at blog.logrocket.com

Theatre.js: Create intricate and powerful animations in JavaScript

Written by Eze Sunday✏️

There’s plenty of buzz in the dev world around the relatively new Theatre.js. So, is it just another JavaScript animation library?

The answer is no, not really. Theatre.js is a motion graphics library that allows you to build powerful animations easily. According to the creators, “Theatre.js is an animation library for high-fidelity motion graphics. It is designed to help you express detailed animation, enabling you to create intricate movement, and convey nuance.”

And, unlike other JavaScript and CSS animation libraries, Theatre.js is an animation library with a graphical user interface (GUI). The GUI allows you to build the animations visually with the editor integrated into your browser.

It literally turns your browser into an animation studio — you’ll most likely only need to write the setup code, and that’s it.

It even animates the DOM, WebGL, Three.js, HTML, and other JavaScript variables, meaning you can set it up and allow even a non-developer to create the animations on the browser with the Theatre.js editor.

Here is an example:

Theatre Sample

Throughout this article, we’ll explore how to set up and create your own animation lab with JavaScript and Theatre.js.

Requirements

Setting up Theatre.js

You can use Theatre.js with Vanilla JavaScript or any JavaScript Library like React or Angular. In this article, we’ll use Theatre.js with Vanilla JavaScript and the Parcel build tool.

First, let’s create a directory, initialize it with npm init, and run the command below to install Theatre Core and Theatre Studio. Theatre Core is the main library, while Theatre Studio is the editor, which you’ll only need in design and development.

Theatre Core:

 npm install @theatre/core --save
Enter fullscreen mode Exit fullscreen mode

Theatre Studio:

npm install @theatre/studio --save-dev
Enter fullscreen mode Exit fullscreen mode

Next, we’ll create the necessary files we need to run the application. To make it easy to follow along, I’ve created a boilerplate for this article. Run git clone https://github.com/ezesundayeze/theatrejs on your terminal to grab a copy of it.

Edit the HTML document with the following content:

src/index.html

<style>
  body {
    background: rgb(6, 143, 113);
    margin: 0;
  }
  #box {
    position: absolute;
    width: 100%;
    top: 0;
    height: 50%;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 8px;
    --box-size: 40px;
  }
  .boxContainer {
    width: var(--box-size);
    position: relative;
  }

</style>
<div class="boxContainer">
  <div id="box"></div>
</div>
<script type ="module" async src="index.ts"></script>
Enter fullscreen mode Exit fullscreen mode

Next, let’s add the JavaScript code we linked to the HTML. Create an index.js file and import Theatre and Theatre Studio, as shown below:

import * as core from "@theatre/core";
import studio from "@theatre/studio";
Enter fullscreen mode Exit fullscreen mode

After that, initialize Theatre Studio by adding studio.initialize() to the existing code. It should now look like this:

import * as core from "@theatre/core";
import studio from "@theatre/studio";

studio.initialize()
Enter fullscreen mode Exit fullscreen mode

Run the application with npm run dev to see Theatre Studio in action. The little icon at the top left corner of the page shows that Studio is active.

Icon Top Left

However, we still won’t be able to do anything just yet, as our studio setup is incomplete.

In Theatre.js, you’ll come across and use the following:

  • Projects
  • Sheets
  • Objects
  • Sequences

Let’s set them up in our studio.

Projects in Theatre.js

A project in Theatre.js is the workspace in which all animation work will be done. Creating a project is as easy as adding the following line to your code after you’ve imported Theatre.js and Studio:

const project = core.getProject("soccer ball Animation");
Enter fullscreen mode Exit fullscreen mode

Using sheets in Theatre.js

A sheet is similar to a component in React. It holds objects that are animated together, and you can have more than one sheet within a project.

This is how you add a sheet to a project:

const ballSheet = project.sheet("ballSheet");
Enter fullscreen mode Exit fullscreen mode

Objects

An object in Theatre.js refers to the actual object to animate. In this object, we’ll set the default properties we’d like to animate. These props can be modified in the animation editor to create the type of animated look and feel we want.

Here is an example on how to add the object props:

const ballObj = sheet.object("ballSheet", {
    y: 100,
    x: 150,
    angle: 0,
    stretch:1
});
Enter fullscreen mode Exit fullscreen mode

Let’s take a look at how object properties will show up as controls in the editor when you run the app. You’ll need to slide them left to right, or vice-versa, to get the desired animation.

Object Properties

Sequences

A sequence defines the order and manner in which related items follow each other. In Theatre.js, sequences define the order in which object properties move. It’s this movement that creates the actual animation.

The section below is what allows you to create and modify the sequences:

Sequences

Each sequence has a [position](https://docs.theatrejs.com/in-depth/#sequence-position), which determines progress within the animation. The figures at the top of the bar show the position of the object at a certain instance. The default unit is in seconds.

Creating animations in Theatre.js

So, let’s add some animation to the HTML we used initially. First, select the target element, add the image we intend to use (it’s not required to be an image — you can create shapes or animate any item at all), and add some basic CSS to align the element on the page.

const boxDiv = document.getElementById("box");
const ball = document.createElement("img");
ball.src = "soccer ball.png";
boxDiv.appendChild(ball);
ball.style.position = "absolute";
ball.style.width = "100px";
ball.style.height = "100px";
Enter fullscreen mode Exit fullscreen mode

For this example, I’ll start the animation by clicking on the soccer ball. So, let’s add an eventListener to the ball element.

ball.addEventListener("click", () => {
    const sequence = sheet.sequence.play({ iterationCount: Infinity, rate: 1, range: [1, 6] })
});
Enter fullscreen mode Exit fullscreen mode

When the ball is clicked, we can play the sequence by calling the sequence.play() method. You can customize the sequence by passing an object with properties, such as rate, which sets the speed of the sequence, and iterationCount, which sets the number of times you want the sequence to play.

Theatre JS

In the example above, I set it to play forever. Range is the position range you want it to run through. We set ours to run from position 1 to 6. You can find more props in the docs.

To see the animation progression, we’ll use the .onValueChange method of the ball object and then set the CSS transformation to match the expected behavior.

ballObj.onValuesChange(({ y, x, angle, stretch }) => {
boxDiv.style.cssText = `
    transform: translateX(${x}px) rotate(${angle}deg) translateY(${y}px) scale(${1 / stretch}, ${stretch});
`;
});
Enter fullscreen mode Exit fullscreen mode

In the transformation (transform adds a 2D or 3D transformation to an element), we are using the translateY and translateX properties to modify the behavior of the transformation.

We’ve now set up our Theatre.js animation studio to animate a soccer ball. You can view this in action below or click on this link to see the demo on CodeSandbox.

https://codesandbox.io/embed/late-pond-c039j?fontsize=14&hidenavigation=1&theme=dark

In production, you might want to turn off the studio. You can do so by calling the studio.ui.hide() method. To restore it in development, call the studio.ui.restore() method.

Finally, after playing around with the studio and creating your desired animation for the objects, you can export the studio state by clicking on Project, then Export, as shown below.

Export

You can now link this state to your project by importing and adding it to your project instance, like so:

import state from "./state.json"
const project = core.getProject("soccer ball Animation", {state});
Enter fullscreen mode Exit fullscreen mode

Congratulations, you’ve set up your Theatre Studio and have explored some of its features. We have only scratched the surface. Keep in mind that there is still a lot to learn, as this project is less than two months old and still developing at the time of this writing.

Conclusion

Theatre.js is an amazing project that gives you the power to craft your own animation studio. This has the potential to shape the web animation ecosystem as it gathers more adoption from the community, so now is a great time to jump in and start exploring Theatre.JS or contribute to developing the library further.


Are you adding new JS libraries to improve performance or build new features? What if they’re doing the opposite?

There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.

LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.

LogRocket Dashboard Free Trial Banner

LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.

Build confidently — Start monitoring for free.

Top comments (1)

Collapse
 
jai_type profile image
Jai Sandhu

This is amazing, really excited to use it