Tutorial

In this tutorial, we are going to write some client-side JavaScript to create the following mighty morphing JSON animation:

[]
["World"]
["Hello", "World"]
[
  "Hello",
  "World"
]

View on CodePen

This is a somewhat modest example, but it encompasses almost everything you will ever need to know about Code.Movie. The overall workflow is the same for all other programming languages, more complex animations, or server-side and compile-time applications.

Prerequisites

You will need the following setup for this tutorial:

  1. A non-ancient web browser
  2. Some kind of code editor
  3. A way to serve a web page from localhost. If you happen to have Node.js installed, simply running npx serve will do the job

This tutorial does not require any sort of frontend tooling and uses JavaScript instead of TypeScript.

Get the library and set up a web page

Code.Movie is just a JavaScript library that, at the end of the day, just turns strings into other strings. The library itself is written in TypeScript, but can also be used with plain JavaScript. It works in browsers as well as in server-side environments. You can use your preferred package manager to install the library...

$ npm install @codemovie/code-movie # adjust for use with yarn etc.
1
$ npm install @codemovie/code-movie # adjust for use with yarn etc.

... but for this tutorial, we will use the CDN jsdelivr. We can hotlink all required files straight from there, but the URLs are long and unwieldy. Let's use an Import Map to make our lives easier and, while we are at it, set up a a minmal web page:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Tutorial</title>
    <script type="importmap">






    </script>
    <script type="module">

    </script>
  </head>
  <body></body>
</html>






      {
        "imports": {
          "@codemovie/code-movie": "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/index.js",
          "@codemovie/code-movie/languages/json": "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/languages/json.js"
        }
      }














      // Tutorial continues here
12345678910111213141516171819
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Tutorial</title>
    <script type="importmap">
      {
        "imports": {
          "@codemovie/code-movie": "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/index.js",
          "@codemovie/code-movie/languages/json": "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/languages/json.js"
        }
      }
    </script>
    <script type="module">
      // Tutorial continues here
    </script>
  </head>
  <body></body>
</html>

The <script type="importmap"> aliases the long CDN URLs to the same module names that you would use if you had a "proper" build process. Let's continue inside the second script tag!

Load the main module

Creating an animation involves two steps:

  1. Loading the language module for the programming language that we want to use in out animation (JSON in our case)
  2. Turning frames code into a giant string of HTML that renders the animation

To take care of step 2, there's just one function to load from the main module: animateHTML():

import { animateHTML } from "@codemovie/code-movie";
1
import { animateHTML } from "@codemovie/code-movie";

Load and configure the language

Every programming language that you intend to create animations for must be imported explicitly. For JSON this means importing the module @codemovie/code-movie/languages/json. Every language module exports a function as its sole default export. Calling the function returns an object that represents the language:

import { animateHTML } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";
const language = json();
// "language" now contains everything needed for JSON support
1234
import { animateHTML } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";
const language = json();
// "language" now contains everything needed for JSON support

Having to import every language manually is a tad annoying, but help to keep download and startup times in check. The function call also allows some languages to be configured in detail (like activating or deactivating support for JSX or type annotations in JavaScript).

Rendering the animation

To create an animation, we first need a list of keyframe objects that our animation steps through. This list is an array of objects like this:

let keyframes = [
  { code: `[]` },
  { code: `["World"]` },
  { code: `["Hello", "World"]` },
  { code: `[\n  "Hello",\n  "World"\n]` },
];
123456
let keyframes = [
  { code: `[]` },
  { code: `["World"]` },
  { code: `["Hello", "World"]` },
  { code: `[\n  "Hello",\n  "World"\n]` },
];

Every object represents a keyframe and the transitions between each step gets computed automatically. To make this happen, pass the array into the animateHTML function alongside your choice of tab size and the previously imported and instantiated language object:

import { animateHTML } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";

const language = json();

let keyframes = [
  /* keyframes go here */
];

let html = animateHTML(keyframes, {
  tabSize: 2,
  language,
});
12345678910111213
import { animateHTML } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";

const language = json();

let keyframes = [
  /* keyframes go here */
];

let html = animateHTML(keyframes, {
  tabSize: 2,
  language,
});

animateHTML() parses the code, computes the animation, and finally turns it into plain HTML and CSS. The resulting HTML string is huge and contains everything a browser needs to display the animation.

The animation is advanced by switching between the classes frame0, frame1, frameN etc. on the element with the class cm-animation contained in the HTML. This by itself is not very user-friendly. We can add the companion web component <code-movie-runtime> to our code to get a minimal user interface with equally minimal effort. Wrap the HTML returned by animateHTML() in <code-movie-runtime> tags, dump it into the page and ...

import { animateHTML } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";

const language = json();

let keyframes = [
  /* keyframes go here */
];

let html = animateHTML(keyframes, {
  tabSize: 2,
  language,
});

// Load the web component
import "https://cdn.jsdelivr.net/npm/@codemovie/code-movie-runtime";

// Wrap the generated HTML and use it in the page!
document.body.innerHTML = `<code-movie-runtime controls keyframes="0 1 2 3">
  ${html}
</code-movie-runtime>`;
123456789101112131415161718192021
import { animateHTML } from "@codemovie/code-movie";
import json from "@codemovie/code-movie/languages/json";

const language = json();

let keyframes = [
  /* keyframes go here */
];

let html = animateHTML(keyframes, {
  tabSize: 2,
  language,
});

// Load the web component
import "https://cdn.jsdelivr.net/npm/@codemovie/code-movie-runtime";

// Wrap the generated HTML and use it in the page!
document.body.innerHTML = `<code-movie-runtime controls keyframes="0 1 2 3">
  ${html}
</code-movie-runtime>`;

... we are done!

[]
["World"]
["Hello", "World"]
[
  "Hello",
  "World"
]

View on CodePen

Next steps

You can check out the styling options or read up on API details next.