Hunter Henrichsen

Hunter Henrichsen

Search Circle
< guide

Using Motion Canvas on GitHub Actions

sprout posted over 1 year ago last updated over 1 year ago 3 min read

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

Terminal window
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
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
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
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
<!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:

Terminal window
npm run build

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

Terminal window
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
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.