Examples

SVG loading spinner

import "./styles.css"
import { animate, stagger } from "motion"
  
const numSegments = document.querySelectorAll(".segment").length

/**
 * Stagger offset (in seconds)
 * Decrease this to speed the animation up or increase
 * to slow it down.
 */
const offset = 0.09

setTimeout(() => {
  animate(
    ".segment",
    { opacity: [0, 1, 0] },
    {
      offset: [0, 0.1, 1],
      duration: numSegments * offset,
      delay: stagger(offset),
      repeat: Infinity,
    }
  )
}, 1000)

SVG path drawing timeline

import "./styles.css"
import { timeline } from "motion"
  
/**
 * Remember to set the pathLength="1" SVG attribute on
 * the elements you want to draw. This makes it easy
 * to use the same animation logic for elements of a
 * different path length.
 */

const draw = (progress) => ({
  // This property makes the line "draw" in when animated
  strokeDashoffset: 1 - progress,

  // Each line will be hidden until it starts drawing
  // to fix a bug in Safari where the line can be
  // partially visible even when progress is at 0
  visibility: "visible",
})

timeline([
  ["circle", draw(1), { duration: 0.8, delay: 1 }],
  ["path", draw(1), { duration: 0.6, at: "-0.2" }],
])

Scroll-triggered animation

import { inView, animate } from "motion";

inView("section", ({ target }) => {
  animate(
    target.querySelector("span"),
    { opacity: 1, transform: "none" },
    { delay: 0.2, duration: 0.9, easing: [0.17, 0.55, 0.55, 1] }
  );
});

Animating HTML text

import "./styles.css"
import { animate } from "motion"

setTimeout(() => {
  const h1 = document.querySelector("h1")

  animate(
    (progress) => h1.innerHTML = Math.round(progress * 100),
    { duration: 2, easing: "ease-out" }
  )
}, 1000)

Morph SVG path

import { animate } from "motion";
import { interpolate } from "flubber";
import { paths } from "./paths";

const path = document.querySelector("path");

let currentPath = paths.star;

path.setAttribute("fill", currentPath.color);
path.setAttribute("d", currentPath.d);

const transition = { duration: 0.5 };

function togglePath() {
  currentPath = currentPath === paths.star ? paths.heart : paths.star;

  const mixPaths = interpolate(path.getAttribute("d"), currentPath.d, {
    maxSegmentLength: 0.1
  });

  animate(path, { fill: currentPath.color }, transition);
  animate((progress) => path.setAttribute("d", mixPaths(progress)), transition);
}

setTimeout(togglePath, 1000);

path.addEventListener("click", togglePath);

P5

Mixing Motion One custom animations with the P5 library.

import P5 from "p5";
import { animate, spring } from "motion";
import { mix, progress, wrap } from "@motionone/utils";

new P5(function (p5) {
  let x = 0;
  let y = 0;
  let radius = 50;
  let weight = 3;
  let currentAnimation;

  const startAnimation = (targetX, targetY) => {
    const originX = x;
    const originY = y;

    currentAnimation && currentAnimation.stop();
    currentAnimation = animate(
      (progress) => {
        x = mix(originX, targetX, progress);
        y = mix(originY, targetY, progress);
      },
      {
        easing: spring({ stiffness: 300, damping: 10, restDistance: 0.001 })
      }
    );
  };

  p5.setup = () => {
    const { width, height, elt: element } = p5.createCanvas(
      Math.max(document.documentElement.clientWidth, window.innerWidth || 0),
      Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
    );

    x = width / 2;
    y = height / 2;

    element.addEventListener("click", (event) => {
      startAnimation(event.pageX, event.pageY);
    });
  };

  p5.draw = () => {
    p5.noFill();
    p5.strokeWeight(weight);
    p5.stroke(`hsl(${getHue(performance.now())}, 100%, 50%)`);
    p5.circle(x, y, radius);
  };
});

const duration = 4000;
function getHue(t) {
  const looped = wrap(0, duration, t);
  const p = progress(0, duration, looped);
  return Math.round(mix(0, 360, p));
}

Scroll

Page progress bar

Element-based progress bar

Parallax and scroll-snapping

Fade on enter/exit

Video scrubbing

3D camera

Custom easing function

Have you seen Motion DevTools?

It's an incredible new developer tool for Chrome that let you inspect, edit and export Motion One and CSS animations. Animate like the good-ol' days of Flash!