Static Methods

Motion.set(), Motion.kill(), Motion.killAll(), Motion.reset(), Motion.refreshScrollTriggers().

Static methods on the Motion object let you manage the global timeline registry, set properties instantly, and handle cleanup for SPAs and dynamic content.


Overview

MethodSignatureDescription
Motion.set()set(target: TargetInput, vars: AnimationVars): voidImmediately apply CSS properties with no animation
Motion.get()get(name: string): Timeline | undefinedSafe timeline retrieval — undefined if not found
Motion.has()has(name: string): booleanCheck if a named timeline is registered
Motion.getNames()getNames(): string[]Array of all registered timeline names
Motion.kill()kill(name: string): voidKill one timeline by name, restore initial CSS
Motion.killAll()killAll(): voidKill every registered timeline
Motion.reset()reset(targets: TargetInput): voidKill animations, revert text splits, clear transform cache
Motion.refreshScrollTriggers()refreshScrollTriggers(): voidRecalculate all scroll trigger positions
Motion.cleanup()cleanup(): voidRemove ScrollTrigger spacer and marker DOM nodes
Motion.context()context(fn: () => void): MotionContextCreate a scoped context for grouped teardown
Motion.utilsUtility functions

Motion.set()

Motion.set() immediately applies CSS properties to one or more elements — a zero-duration snapshot with no animation played.

typescript
import { Motion } from "@motion.page/sdk";

// Set a single element's initial state
Motion.set("#hero", { opacity: 0, y: 40 });

// Set multiple elements at once
Motion.set(".card", { scale: 0.95, opacity: 0 });

// Set CSS custom properties
Motion.set(":root", { "--accent": "#6633EE" });
ParameterTypeDescription
targetTargetInputCSS selector, Element, NodeList, or array of elements
varsAnimationVarsThe same property object accepted by from / to

Use cases

Set initial state before animating — hide elements before a page-load animation so they don’t flash:

typescript
import { Motion } from "@motion.page/sdk";

// Hide immediately, then animate in
Motion.set(".hero-title, .hero-sub, .hero-cta", { opacity: 0, y: 30 });

Motion("hero", [
  { target: ".hero-title", to: { opacity: 1, y: 0 }, duration: 0.7 },
  { target: ".hero-sub",   to: { opacity: 1, y: 0 }, duration: 0.6, position: "+=0.1" },
  { target: ".hero-cta",   to: { opacity: 1, y: 0 }, duration: 0.5, position: "+=0.1" },
]).onPageLoad();

Reset after animation completes:

typescript
Motion("slide", ".panel", { from: { x: -300 }, duration: 0.6 })
  .onComplete(() => {
    // Snap back without a visible animation
    Motion.set(".panel", { x: 0 });
  })
  .onPageLoad();

Registry Methods

The timeline registry tracks every named Motion timeline. These helpers let you inspect it safely without risking a thrown error.

MethodReturnsDescription
Motion.get(name)Timeline | undefinedReturns the timeline, or undefined if not registered
Motion.has(name)booleantrue if the timeline exists in the registry
Motion.getNames()string[]All currently registered timeline names
typescript
import { Motion } from "@motion.page/sdk";

// Safe conditional control
if (Motion.has("hero")) {
  Motion.get("hero")?.pause();
}

// Debug — log all active timelines
console.log(Motion.getNames()); // ["hero", "nav-reveal", "card-hover"]

These are most useful when you need to control a timeline from a different scope than where it was created. See Timeline Control for the full set of playback and state methods available on a retrieved timeline.


Motion.kill()

Motion.kill(name) removes a single timeline from the registry by name and, by default, restores all CSS properties the animation touched to their pre-animation values.

typescript
import { Motion } from "@motion.page/sdk";

Motion("modal-in", "#modal", {
  from: { opacity: 0, scale: 0.92 },
  duration: 0.4,
}).onPageLoad({ paused: true });

// Show modal
document.querySelector("#open-modal")?.addEventListener("click", () => {
  Motion("modal-in").play();
});

// Dismiss and clean up
document.querySelector("#close-modal")?.addEventListener("click", () => {
  Motion.kill("modal-in");
});

After Motion.kill("modal-in"), calling Motion("modal-in") will throw. Guard with Motion.has() or use Motion.get() which returns undefined safely.


Motion.killAll()

Motion.killAll() kills every timeline currently in the registry. Use it for full-page teardown — SPA route changes, modal unmounts that own several animations, or any situation where you want a clean slate.

typescript
import { Motion } from "@motion.page/sdk";

// SPA router — clean up before navigating away
router.beforeEach(() => {
  Motion.killAll();
});
typescript
// Vue Router equivalent
router.afterEach(() => {
  Motion.killAll();
});

Motion.reset()

Motion.reset(targets) is a more thorough cleanup than kill. In addition to stopping animations, it:

  • Reverts any Text Splitter splits on the targets (re-merges characters/words/lines)
  • Clears the internal transform cache for those elements
  • Restores initial CSS
typescript
import { Motion } from "@motion.page/sdk";

// After a page section is removed from the DOM
Motion.reset(".hero-section");

// Reset all animated elements before reinitialising
Motion.reset(".animate-in");
Motion("page-reveal", ".animate-in", {
  from: { opacity: 0, y: 20 },
  duration: 0.5,
  stagger: 0.08,
}).onPageLoad();
ParameterTypeDescription
targetsTargetInputCSS selector, Element, NodeList, or array of elements

Use Motion.reset() when reinitialising animations on elements that previously had split text or complex transform sequences — it prevents stale state from carrying over.


Motion.refreshScrollTriggers()

Motion.refreshScrollTriggers() recalculates the start and end scroll positions for all active scroll-based animations. Call it any time the page layout changes after scroll triggers were created.

Common situations that require a refresh:

  • Dynamic content finishes loading (images, async data, lazy components)
  • An accordion or disclosure opens/closes
  • A tab panel becomes visible
  • Fonts finish loading and reflow the page
  • CSS transitions that change element height complete
typescript
import { Motion } from "@motion.page/sdk";

// After async content loads
async function loadItems() {
  const items = await fetchItems();
  renderList(items);

  // Layout has changed — recalculate scroll positions
  Motion.refreshScrollTriggers();
}

Debounced resize handler

Scroll trigger positions are also invalidated by window resizes. Wrap in a debounce to avoid excessive recalculations:

typescript
import { Motion } from "@motion.page/sdk";

let resizeTimer: ReturnType<typeof setTimeout>;

window.addEventListener("resize", () => {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(() => {
    Motion.refreshScrollTriggers();
  }, 150);
});

See Scroll Trigger for full documentation on scroll-based animation options.


Motion.cleanup()

Motion.cleanup() removes the spacer <div> elements and debug marker nodes that ScrollTrigger injects into the DOM. It does not kill animations — combine it with Motion.killAll() for a complete teardown.

typescript
import { Motion } from "@motion.page/sdk";

// Full scroll-animation teardown
function teardown() {
  Motion.killAll();
  Motion.cleanup();
}

// E.g., on SPA route change
document.addEventListener("astro:before-swap", teardown);

Spacer nodes are only present when pin: true is used on a scroll trigger. Markers are visible only in development. cleanup() is safe to call even when neither is present.


Motion.context()

Motion.context(fn) creates a scoped context that tracks every timeline registered inside the callback function. It returns a MotionContext object you can use to revert, refresh, or extend the group later.

This is the recommended pattern for SPAs and any component that creates more than one animation — instead of calling Motion.kill() individually for each timeline, a single ctx.revert() tears them all down.

MotionContext methods

MethodSignatureDescription
revert()revert(): voidKill all timelines created in this context and restore CSS
refresh()refresh(): voidRecalculate scroll trigger positions for timelines in this context
add()add(fn: () => void): voidRegister additional timelines into the context after creation

Basic usage

typescript
import { Motion } from "@motion.page/sdk";

const ctx = Motion.context(() => {
  Motion("nav-fade", ".nav-item", {
    from: { opacity: 0, x: -12 },
    stagger: 0.06,
    duration: 0.4,
  }).onPageLoad();

  Motion("nav-underline", ".nav-link", {
    to: { scaleX: 1 },
    duration: 0.25,
  }).onHover({ onLeave: "reverse" });
});

// Tears down both timelines in one call
ctx.revert();

React — useEffect cleanup

typescript
import { useEffect } from "react";
import { Motion } from "@motion.page/sdk";

export function HeroSection() {
  useEffect(() => {
    const ctx = Motion.context(() => {
      Motion("hero-title", "#hero h1", {
        from: { opacity: 0, y: 40 },
        duration: 0.7,
        ease: "power3.out",
      }).onPageLoad();

      Motion("hero-body", "#hero p", {
        from: { opacity: 0, y: 20 },
        duration: 0.6,
        position: "+=0.1",
      }).onPageLoad();
    });

    // ctx.revert() kills both timelines when the component unmounts
    return () => ctx.revert();
  }, []);

  return (
    <section id="hero">
      <h1>Welcome</h1>
      <p>Subtitle copy here.</p>
    </section>
  );
}

Astro View Transitions

astro
<script>
  import { Motion } from "@motion.page/sdk";

  let ctx: ReturnType<typeof Motion.context>;

  function initAnimations() {
    ctx = Motion.context(() => {
      Motion("page-reveal", ".animate-in", {
        from: { opacity: 0, y: 20 },
        duration: 0.5,
        stagger: 0.1,
      }).onPageLoad();
    });
  }

  // Initial page load
  initAnimations();

  // Reinitialise after each View Transition
  document.addEventListener("astro:page-load", () => {
    initAnimations();
  });

  // Tear down before the DOM is swapped out
  document.addEventListener("astro:before-swap", () => {
    ctx?.revert();
  });
</script>

Adding timelines after creation

Use ctx.add() to register timelines that are created outside the original callback — for example, inside a dynamic content render:

typescript
import { Motion } from "@motion.page/sdk";

const ctx = Motion.context(() => {
  Motion("list-header", ".list-header", {
    from: { opacity: 0 },
    duration: 0.4,
  }).onPageLoad();
});

// Later — dynamic items loaded; add their animations into the same context
ctx.add(() => {
  Motion("list-items", ".list-item", {
    from: { opacity: 0, y: 12 },
    duration: 0.35,
    stagger: 0.06,
  }).onPageLoad();
});

// ctx.revert() now cleans up all three timelines

Motion.utils

Motion.utils provides utility functions (toArray, clamp, random, snap, interpolate, mapRange, normalize, wrap). See Motion.utils for the full reference.


Common Patterns

Full teardown on SPA navigation

typescript
import { Motion } from "@motion.page/sdk";

// Works with any router that exposes a before-navigate hook
router.beforeEach(() => {
  Motion.killAll();
  Motion.cleanup(); // removes ScrollTrigger spacers and markers
});

Debounced resize with scroll refresh

typescript
import { Motion } from "@motion.page/sdk";

let timer: ReturnType<typeof setTimeout>;

window.addEventListener("resize", () => {
  clearTimeout(timer);
  timer = setTimeout(() => Motion.refreshScrollTriggers(), 150);
});

Reinitialise after dynamic content

typescript
import { Motion } from "@motion.page/sdk";

async function loadAndAnimate() {
  const data = await fetchProducts();
  renderProductGrid(data);

  // Recalculate scroll positions now that new elements exist
  Motion.refreshScrollTriggers();
}

Generic SPA cleanup with context

typescript
import { Motion } from "@motion.page/sdk";

let pageCtx: ReturnType<typeof Motion.context> | null = null;

function onPageEnter() {
  pageCtx = Motion.context(() => {
    Motion("page-in", "main", { from: { opacity: 0 }, duration: 0.35 }).onPageLoad();
    Motion("page-items", ".item", {
      from: { opacity: 0, y: 16 },
      stagger: 0.07,
      duration: 0.4,
    }).onPageLoad();
  });
}

function onPageLeave() {
  pageCtx?.revert();
  Motion.cleanup();
  pageCtx = null;
}

Related: Timeline Control · Scroll Trigger · Motion.utils