Transform Origin

Set the origin point for scale, rotation, and transform animations.

Transform origin is the pivot point around which scale, rotate, skew, and other transform animations occur. By default every element transforms from its center (50% 50%), but you can move that anchor to any corner, edge, or custom position.

Basic Usage

Pass transformOrigin as a string inside from or to. It can be set on either endpoint or on both — the origin applies for the duration of the animation.

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

// Rotate around the top-center (pendulum effect)
Motion("pendulum", ".arm", {
  from: { rotate: -30, transformOrigin: "50% 0%" },
  to: { rotate: 30 },
  duration: 1,
  ease: "power1.inOut",
  repeat: { times: -1, yoyo: true },
}).onPageLoad();

Accepted Values

transformOrigin accepts the same syntax as the CSS transform-origin property.

FormatExampleDescription
Keywords"center"Center of the element (same as "50% 50%")
Two keywords"top left"Top-left corner ("0% 0%")
Percentages"50% 100%"Bottom-center
Pixels"0px 0px"Exact pixel coordinates
Mixed"20px 80%"Pixel X, percentage Y

Keyword Reference

KeywordEquivalent
"top left""0% 0%"
"top center""50% 0%"
"top right""100% 0%"
"center left""0% 50%"
"center""50% 50%"
"center right""100% 50%"
"bottom left""0% 100%"
"bottom center""50% 100%"
"bottom right""100% 100%"

Effect on Different Transforms

Rotation

The element pivots around the origin point. Moving the origin to a corner or edge produces a hinge or pendulum effect.

typescript
// Hinge from top-left corner
Motion("hinge", ".door", {
  from: { rotate: 0, transformOrigin: "0% 50%" },
  to: { rotate: 90 },
  duration: 0.6,
  ease: "power2.inOut",
}).onClick({ each: true });

Scale

The element grows or shrinks toward the origin point. A corner origin makes the element appear to emerge from that corner rather than its center.

typescript
// Grow from the bottom-left corner
Motion("corner-pop", ".card", {
  from: { scale: 0, transformOrigin: "0% 100%" },
  duration: 0.5,
  ease: "back.out(1.7)",
}).onPageLoad();

Skew

The shear distortion anchors at the origin, which controls which point of the element stays fixed as the rest of it tilts.

typescript
// Skew with bottom anchored
Motion("tilt", ".panel", {
  from: { skewX: 15, opacity: 0, transformOrigin: "50% 100%" },
  duration: 0.55,
  ease: "power3.out",
}).onPageLoad();

Common Patterns

Corner Pop

Scale an element in from one of its corners — a classic way to make cards, tooltips, or dropdowns feel anchored to a fixed point.

typescript
// Dropdown opening from its top-left corner
Motion("dropdown", ".dropdown-menu", {
  from: { scale: 0.8, opacity: 0, transformOrigin: "0% 0%" },
  duration: 0.25,
  ease: "power2.out",
}).onClick({ each: true });

Pendulum Swing

Set the origin to the top-center so the element rotates like a pendulum hanging from that point.

typescript
Motion("swing", ".pendulum", {
  from: { rotate: -25, transformOrigin: "50% 0%" },
  to: { rotate: 25 },
  duration: 1.4,
  ease: "power1.inOut",
  repeat: { times: -1, yoyo: true },
}).onPageLoad();

Grow from Bottom

Reveal bar charts, progress indicators, or loaders that rise from the bottom edge.

typescript
Motion("bar-reveal", ".bar", {
  from: { scaleY: 0, transformOrigin: "50% 100%" },
  duration: 0.7,
  ease: "power3.out",
  stagger: 0.08,
}).onScroll({ scrub: false, toggleActions: "play none none none" });

Click-to-Fold Toggle

Use an edge-anchored origin with onClick to make an element fold open and shut like a flap.

typescript
Motion("flap", ".flap", {
  to: { rotateX: 90, transformOrigin: "50% 0%" },
  duration: 0.35,
  ease: "power2.inOut",
}).onClick({ each: true, onLeave: "reverse" });

Notes

  • transformOrigin is not animated between from and to — it sets a fixed anchor for the entire animation. Place it in either endpoint; the value is applied before the tween begins.
  • The default is "50% 50%" (element center). You only need to set it when you want a non-center pivot.
  • Pixel values are relative to the element’s top-left corner, not the page.
  • For transforms applied across a multi-step timeline, set transformOrigin in the first step that needs the custom anchor.

See Scale, Skew, and Rotation for the transform properties that transformOrigin affects.