This tutorial leads you through the steps required to create the following mighty morphing JSON animation with a bit of client-side JavaScript:
[]
["World"]
["Hello", "World"]
[ "Hello", "World" ]
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.
You will need the following setup for this tutorial:
localhost
or any other well-defined origin. If you happen to have Node.js installed, running npx serve
will do the job. Typical online code sandboxes will work as well.This tutorial does not require any sort of frontend tooling and uses JavaScript instead of TypeScript.
Code.Movie is a JavaScript library that, when it comes down to it, only turns strings (your input) into other strings (HTML and CSS that make up the animation). The library itself is written in TypeScript, but works just fine with plain JavaScript. Both web browsers and server-side environments are supported. You could use your preferred package manager to install the library...
npm install @codemovie/code-movie # adjust for use with yarn etc.
1npm 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@0.0.22/dist/index.js",
"@codemovie/code-movie/languages/json": "https://cdn.jsdelivr.net/npm/@codemovie/code-movie@0.0.22/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@0.0.22/dist/index.js",
"@codemovie/code-movie/languages/json": "https://cdn.jsdelivr.net/npm/@codemovie/code-movie@0.0.22/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!
Creating an animation involves two steps:
To take care of step 2, we need to import animateHTML()
from from the main module:
import { animateHTML } from "@codemovie/code-movie";
1import { animateHTML } from "@codemovie/code-movie";
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
. Each 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
1234import { 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 helps 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).
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]` },
];
123456let 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 by the library. 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,
});
12345678910111213import { 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. We are more or less done at this point.
Animations can be 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 (unless you know your way around a browser's dev tools). To make things easier for laypersons, we can add the companion web component <code-movie-runtime>
to our code, which gets us a minimal user interface with equally minimal effort. Import @codemovie/code-movie-runtime
, wrap the HTML returned by animateHTML()
in <code-movie-runtime>
tags, dump the HTML into the web 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>`;
123456789101112131415161718192021import { 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>`;
... the animation comes alive!
[]
["World"]
["Hello", "World"]
[ "Hello", "World" ]
This does not look quite as advertised, but do not worry: switching themes is a breeze!
The animation's underwhelming appearance is due to its use of the default theme. You can either manually tweak the 140+ CSS variables control the animation's look or just pick a different theme. Let's do just that by importing a theme from the main module and passing it to the animation function:
import {
animateHTML,
monokaiDark, // also available: monokaiLight, default
} 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,
theme: monokaiDark, // add theme here
});
/* ..remaining code... */
➡️➡️import {
animateHTML,
monokaiDark, // also available: monokaiLight, default
} 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,
theme: monokaiDark, // add theme here
});
/* ..remaining code... */
And with that, we are actually done!
[]
["World"]
["Hello", "World"]
[ "Hello", "World" ]
You can check out the remaining themes, all styling options or read up on API details next.