axi0motion

One script tag, any site, no build step

Get started

One line in a page's head, then mark what should move. It works on any site: the loader fetches only the effects a page uses, each checked against its hash.

1One script tag

Paste this line into the head of any page, on any site. It loads the loader from our CDN; the loader brings its small stylesheet, then only the effects the page uses, and the browser checks each effect file against its hash.

<script src="https://search.axi0.io/axi0/motion/motion.js" defer></script>

The address always serves the current release, so new effects and fixes reach your pages without an edit. To have the base styles from the very first paint, before the script runs (a marquee, or a background that covers its section), add the stylesheet line above it:

<link rel="stylesheet" href="https://search.axi0.io/axi0/motion/motion.css">
<script src="https://search.axi0.io/axi0/motion/motion.js" defer></script>

2Your first effect, in two lines

Mark an element with data-motion and the effect's name. That is the whole API for most effects.

<script src="https://search.axi0.io/axi0/motion/motion.js" defer></script>
<h1 data-motion="split-text">Hello, motion.</h1>

Options are attributes: data-motion-NAME on an element you mark, plain attributes on the <axi0-…> elements that backgrounds and components use, and data-sound on a button that should make a sound. Each effect's page lists its options and has controls that write them for you.

<div class="hero">
  <axi0-aurora cover></axi0-aurora>
  <h1 data-motion="blur-text">Each word comes into focus.</h1>
  <a class="button" data-motion="magnet" href="/start">Start</a>
</div>

Sounds also play from code. The first call loads the sound, then plays it:

axi0Motion.sound("tap-round");
axi0Motion.sound("tap-round", { volume: 0.6, pitch: 2 });

3React and Vue

Put the script tag in your app's index.html once. Every effect page links two thin wrappers: a .tsx file for React, typed from the effect's options, and a .vue file for Vue. Put the one you need beside your components. It renders the same attributes as the HTML; the loader in your head does the rest, and it notices elements your app renders later.

import { SplitText } from "./motion/react/SplitText";

export function Title() {
  return <SplitText>Hello, motion.</SplitText>;
}
<script setup lang="ts">
import SplitText from "./motion/vue/SplitText.vue";
</script>

<template>
  <SplitText>Hello, motion.</SplitText>
</template>

4Reduced motion

Nothing to set up. When a visitor's system asks for reduced motion, every effect shows its final state and nothing moves: text is in place, numbers show their value, backgrounds hold one still frame. Effects also pause when they leave the screen or the tab is hidden, and none of them moves the layout.

To see it yourself: on a Mac, System Settings, Accessibility, Display, Reduce motion; on Windows, Settings, Accessibility, Visual effects, Animation effects off; in Chrome's developer tools, Rendering, Emulate CSS media feature prefers-reduced-motion.

5Sizes

FileGzipWhen it loads
motion.js2.9 KBAlways: the loader
motion.css0.8 KBAlways: the base styles
core.js1.4 KBOnce, with the first effect
gl.js2.1 KBOnce, with the first WebGL background
Each effectunder 4 KBOnly when the page uses it

The build refuses an effect over its budget: 4 KB gzip with its styles, 5 KB for a WebGL background beside the shared runner.

6Browsers and policies

Current Chrome, Edge, Firefox and Safari. The library uses custom elements, IntersectionObserver and ResizeObserver; backgrounds draw with WebGL, Particles runs its physics in WebAssembly, and sounds use the Web Audio API. Our tests run in Chrome; Firefox and Safari support every feature it uses, but we have not run our tests in them yet. Without JavaScript the page stays as written, so its content is always readable.

If your site sends a Content-Security-Policy, allow our CDN where the library reaches: https://search.axi0.io in script-src, style-src and connect-src, and 'wasm-unsafe-eval' in script-src if you use the Particles background.

7Host a copy

The second way: keep the files on your own domain, which also pins one exact release. Copy motion.js, motion.css, the effect tables and the files of the effects you use, all listed with their hashes in manifest.json. The loader finds its effects next to itself, so it works from any folder. Pin the two head lines by their integrity hashes:

<link rel="stylesheet" href="/motion/motion.css?v=6" integrity="sha384-fiCg9OTIU+Rywt9fCbyk220WTIlLZcU/yaAaegxiyk2SR9gp/yjlLLyyYWR/zCYl">
<script src="/motion/motion.js?v=11" integrity="sha384-IwuRNEHDN5frueF83lD5Vvr+kBRmZoA/htD6qLRfhSfMh9ReP0Hpy15eZWVABngv" defer></script>

For our other brands, the build tool copies a pinned set with core and every dependency in one command:

motion-pack vendor --from PUBLISHED_TREE --to YOUR_REPO/motion --only split-text,aurora

Questions, or a project that needs more? Ask us.