# Tutorial

In this tutorial, we are going to create the following mighty morphing JSON animation:

<iframe height="300" style="width: 100%;" scrolling="no" title="Code.Movie Tutorial V2" src="https://codepen.io/SirPepe/embed/preview/wvLWYvy?default-tab=result&theme-id=light" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/SirPepe/pen/wvLWYvy">
  Code.Movie Tutorial V2</a> by Peter Kröner (<a href="https://codepen.io/SirPepe">@SirPepe</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<small>[View on CodePen](https://codepen.io/SirPepe/pen/JjqpZae?editors=0010)</small>

This is a somewhat modest example, but the process is essentially the same for other programming languages and larger, more complex animations.

## Get the library

The library 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...

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

... but for particularly easy use in web browsers, you can also load the library from a CDN: [https://cdn.jsdelivr.net/npm/@codemovie/code-movie](https://cdn.jsdelivr.net/npm/@codemovie/code-movie)

## Load the modules

Creating an animation involves three steps:

0. Loading the **language module** for our programming language
1. Turning frames code into animation information (a **scene data object**)
2. Turning the animation information into something that actually moves, which takes the form of a giant **string of HTML**

To take care of steps 1 and 2, there's two functions to load from the main module: `fromStringsToScene` and `toAnimationHTML`. Assuming we are using a web browser, we import both functions from `@code-movie/code-movie` in a module:

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Tutorial</title>
    <script type="module">
      import {
        fromStringsToScene,
        toAnimationHTML,
      } from "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/index.js";
    </script>
  </head>
  <body></body>
</html>
```

## Load and configure the language

Support for programming languages must be imported explicitly, which for JSON means importing `@codemovie/code-movie/languages/json`. Every language module exports a function as its sole default export. Calling the function yields an object that represents the language and that we can use in the next step:

```javascript
import json from "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/languages/json.js";
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 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).

## Create the scene

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

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

This array then gets passed into the `fromStringsToScene` function alongside our choice of tab size and the language we previously imported:

```javascript
import {
  fromStringsToScene,
  toAnimationHTML,
} from "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/index.js";
import json from "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/languages/json.js";

const language = json();

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

let sceneData = fromStringsToScene(keyframes, {
  tabSize: 2,
  language,
});
```

`fromStringsToScene` parses the code, computes the animation and finally returns a **scene data object** that contains all the animation information.

## Rendering the animation

A scene data object contains nothing but data, which is not much to look at. Luckily we can quickly turn the scene into an HTML animation by passing it into `toAnimationHTML`:

```javascript
import {
  fromStringsToScene,
  toAnimationHTML,
} from "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/index.js";
import json from "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/languages/json.js";

const language = json();

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

let sceneData = fromStringsToScene(keyframes, {
  tabSize: 2,
  language,
});

let html = toAnimationHTML(sceneData);
// this can take more options, all of which we ignore for now
```

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, which by itself is not very user-friendly. We can add the custom element [`<code-movie-runtime>`](https://github.com/CodeMovie/code-movie-runtime) to our code to get a minimal user interface with equally minimal effort. Wrap the HTML returned by `toAnimationHTML` in `<code-movie-runtime>` tags, dump it into the page and we are done!

```javascript
import {
  fromStringsToScene,
  toAnimationHTML,
} from "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/index.js";
import json from "https://cdn.jsdelivr.net/npm/@codemovie/code-movie/dist/languages/json.js";

const language = json();

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

let scene = fromStringsToScene(keyframes, {
  tabSize: 2,
  language,
});

let html = toAnimationHTML(scene);

// Load the custom element
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>`;
```

## Next steps

You can check out the [styling options](../styling/Readme.md) or read up on [API details](../animations/Readme.md) next.
