motion-circle
Positions text characters evenly around a circle and spins them continuously. Great for badges, labels, and decorative type.
Preview
Import
import 'motion-components/motion-circle' // just this one
import 'motion-components' // or the whole libraryUsage
<motion-circle
text="MOTION COMPONENTS · SPIN IT · "
radius="90"
duration="8"
></motion-circle>Counterclockwise
Set
<motion-circle
text="COUNTERCLOCKWISE · REVERSE · "
radius="90"
duration="10"
direction="ccw"
></motion-circle>Upright characters
Add upright to keep each character vertically oriented instead of radiating outward from the center.
<motion-circle
text="UPRIGHT · READABLE · TEXT · "
radius="90"
duration="9"
upright
></motion-circle>With slotted content
Place any element inside motion-circle to anchor it at the center. The slot content stays still. Only the text ring rotates.
<motion-circle text="AVAILABLE FOR WORK · HIRE ME · " radius="80" duration="10">
<img src="avatar.jpg" width="80" height="80" alt="Avatar" />
</motion-circle>Pause on hover
Add pause-on-hover to freeze the rotation when the cursor enters and resume it on leave.
<motion-circle
text="HOVER TO PAUSE · SPIN IT · "
radius="90"
duration="8"
pause-on-hover
></motion-circle>How it works
Each character is wrapped in an absolutely positioned span centered in the container. A CSS transform chain places each character at its position on the ring: rotate(angle) translateY(-radius). The .ring container then spins continuously via Motion's animate with
repeat: Infinity and
ease: "linear".
When upright is set, a counter-rotation (rotate(-angle)) is appended to each character's transform so characters stay
axis-aligned regardless of their position on the ring.
Properties
| Attribute | Property | Type | Default | Description |
|---|---|---|---|---|
| | | string | — | Text to arrange around the circle |
| | | number | 80 | Circle radius in px |
| | | number | 8 | Seconds per full rotation. Lower is faster |
| | | string | 'cw' | Spin direction: |
| | | boolean | false | Keep characters vertically oriented |
| | | boolean | false | Pause the rotation on mouseenter, resume on mouseleave |
JavaScript API
Control the circle programmatically with play(), pause(), finish(), and cancel().
Accessibility
When prefers-reduced-motion is set, the ring does not animate and the text renders statically around the circle.