# <motion-circle>

Text wrapped around a full circle, optionally rotating. Place a logo or
icon inside the default slot to render in the centre.

**Use it for:** rotating badges and stamps, such as a short label that
circles a logo or an icon in the centre slot.

**Avoid it for:** text that people must read quickly, because rotating text
is hard to read. For text along part of a circle, use `motion-arc`.

**Accessibility:** screen readers read the whole text once from a visually
hidden copy. The rotating letters are `aria-hidden`. Content in the centre
slot is read as normal, so give images an `alt` text (empty if they are
decorative). The rotation never stops on its own, and `pause-on-hover`
works with a mouse only. If people must be able to stop it, add a button
that calls `pause()`.

**Reduced motion:** the ring does not rotate. The text stays still around
the circle.

**Common mistakes:** text with no separator at the end. The letters are
spaced evenly around the full circle, so the last word runs into the first;
end the text with a separator such as ` • `, as in the example. Too much
text for the `radius` makes the letters crowd together.

Docs: https://www.motion-components.dev/docs/text/motion-circle/

## Install

```js
import 'motion-components/motion-circle'
```

Or without a build step:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/motion-components@1/dist/motion-circle.js/+esm"></script>
```

## Example

```html
<motion-circle text="ROTATING • TEXT • " radius="100" duration="12">
  <img src="logo.svg" alt="" width="40" />
</motion-circle>
```

## Attributes

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `text` | `string \| undefined` |  | Text to lay out around the circle. |
| `radius` | `number` | `80` | Circle radius in pixels. |
| `duration` | `number` | `8` | Seconds per full rotation. Lower is faster. |
| `direction` | `'cw' \| 'ccw'` | `'cw'` | Rotation direction: `'cw'` (clockwise) or `'ccw'` (counter-clockwise). |
| `upright` | `boolean` | `false` | When `true`, counter-rotate each glyph so it stays visually upright. |
| `pause-on-hover` | `boolean` | `false` | When `true`, pause the rotation while the cursor is over the element. |

## Properties

| Property | Type | Description |
| --- | --- | --- |
| `playState` | `'idle' \| 'running' \| 'paused' \| 'finished'` | Current state: `'idle'`, `'running'`, `'paused'` or `'finished'`. |
| `finished` | `Promise<void>` | Resolves when the current run settles. A new run replaces the promise. |

## Methods

| Method | Description |
| --- | --- |
| `play()` | Starts the animation, or resumes it when paused. Resolves once the run settles. Under `prefers-reduced-motion: reduce` the final state is applied immediately without animating. |
| `pause()` | Holds the animation at its current position. No-op unless running. |
| `finish()` | Jumps to the final state and settles. Fires `motion-finish`. |
| `cancel()` | Reverts to the initial state and returns to idle. Fires `motion-cancel`. |

## Events

The `motion-*` events bubble and are composed.

| Event | Description |
| --- | --- |
| `motion-start` | When a run starts. |
| `motion-finish` | When a run finishes, or `finish()` jumps to the end. |
| `motion-cancel` | When `cancel()` stops a run and resets it. |

## Slots

| Slot | Description |
| --- | --- |
| (default) | Optional content rendered at the centre of the circle. |
