Start by creating a new node project at the root of your repo and install some dependencies:

Commands
$
npm init @motion-canvas@latest -- --name motion-canvas-github-actions --path ./motion-canvas-github-actions --language ts
$
cd animations
$
npm i
$
npm i -S @motion-canvas/player
$
npm run serve

Create your animation:

animations/src/scenes/example.tsx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { makeScene2D, Circle } from "@motion-canvas/2d";
import { createRef, all } from "@motion-canvas/core";

export default makeScene2D(function* (view) {
  const myCircle = createRef<Circle>();

  view.add(
    <Circle ref={myCircle} x={-300} width={140} height={140} fill="#e13238" />
  );

  yield* all(
    myCircle().position.x(300, 1).to(-300, 1),
    myCircle().fill("#e6a700", 1).to("#e13238", 1)
  );
});

Update your vite config in the animations folder:

animations/vite.config.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { defineConfig } from "vite";
import motionCanvas from "@motion-canvas/vite-plugin";

export default defineConfig({
  plugins: [motionCanvas()],
  build: {
    rollupOptions: {
      input: {
        main: "index.html",
      },
      output: {
        dir: "dist/",
        entryFileNames: "[name].js",
      },
    },
  },
});

Add a main script to load the player, and a script to add the base URL for the GitHub Pages subdirectory structure:

web/player.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import '@motion-canvas/core';
import '@motion-canvas/player';

// Run this function so that the player can be used with relative paths, such as
// a github pages deployment. Since this is a separate build file, vite doesn't
// know how to add the base url to the player's src attribute.
(function prependBase() {
  // If there's no BASE_URL, then there's nothing to do
  const base = import.meta.env.BASE_URL;
  if (!base) {
    return;
  }
  document.querySelectorAll('motion-canvas-player').forEach(player => {
    let url = player.getAttribute('src');
    // URL is absolute
    if (url?.startsWith('/')) {
      // Copy everything after the '/'
      url = base + url.slice(1);
      // Create a new player
      const newElement = document.createElement('motion-canvas-player');
      // Set the same attributes
      newElement.setAttribute('auto', player.getAttribute('auto') ?? 'true');
      newElement.setAttribute('src', url);
      // Replace the old player
      player.replaceWith(newElement);
    }
  });
})();

Add a root-level index.html:

index.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        motion-canvas-player {
            width: 100%;
            height: 100%;
            display: block;
        }
    </style>
</head>
<body>
    <motion-canvas-player src="/project.js"></motion-canvas-player>   
    <script type="module" src="web/player.ts"></script>
</body>
</html>

Build the site:

Command
$
npm run build

Note that you cannot open the generated html file and have it work; you will have to serve it:

Command
$
npx light-server -s dist -p 8000

You should see the animation working at http://localhost:8000. Now to build it in GitHub actions, add a workflow file:

.github/workflows/deploy.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
name: Deploy

on:
  push:
    branches:
      - main

permissions:
  contents: read
  pages: write
  id-token: write

# Allow one concurrent deployment
concurrency:
  group: "pages"
  cancel-in-progress: true

jobs:
  build:
    name: Deploy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repo
        uses: actions/checkout@v3

      - name: Setup Node
        uses: actions/setup-node@v3

      - name: Install dependencies
        run: npm ci

      - name: Install animation dependencies
        run: npm ci
        working-directory: animations

      - name: Build project
        run: npm run build -- --base=/${{ github.event.repository.name }}/

      - name: Setup Pages
        uses: actions/configure-pages@v3

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          path: "./dist"

      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1

And be sure to configure GitHub pages to deploy from GitHub Actions.