Visual Effects
Orbiting Circles
Place items on one or more rings that orbit a shared centre.
Orbiting Circles puts an item on a circular path around a shared centre. Render one instance per item and give each its own radius, duration and startAngle; the layers stack, so several rings can share a single centre.
Each layer rotates about the container's centre and pushes its child out by radius. The child is counter-rotated by the same angle, which keeps an icon upright even at the bottom of the orbit.
Usage
<template>
<div class="relative flex h-96 w-full items-center justify-center overflow-hidden rounded-xl border border-default bg-default">
<div class="z-10 flex size-16 items-center justify-center rounded-full border border-default bg-elevated shadow-sm">
<UIcon
name="i-lucide-sparkles"
class="size-6 text-primary"
/>
</div>
<MOrbitingCircles
:radius="110"
:duration="20"
>
<div class="flex size-10 items-center justify-center rounded-full border border-default bg-elevated">
<UIcon
name="i-lucide-github"
class="size-4"
/>
</div>
</MOrbitingCircles>
<MOrbitingCircles
:radius="110"
:duration="20"
:start-angle="180"
>
<div class="flex size-10 items-center justify-center rounded-full border border-default bg-elevated">
<UIcon
name="i-lucide-twitter"
class="size-4"
/>
</div>
</MOrbitingCircles>
<MOrbitingCircles
:radius="170"
:duration="30"
:reverse="true"
:start-angle="90"
>
<div class="flex size-10 items-center justify-center rounded-full border border-default bg-elevated">
<UIcon
name="i-lucide-figma"
class="size-4"
/>
</div>
</MOrbitingCircles>
</div>
</template>
Examples
Customize
M
Customize
Delay0
Duration20
Path
Radius50
Reverse
Speed1
Start Angle0
Props
| Prop | Type | Default | Description |
|---|---|---|---|
radius | number | 50 | Radius of the orbit, in pixels. Measure it against the container: an item at 110 sits 110px from the centre. |
duration | number | 20 | Seconds for one full revolution at speed 1. |
speed | number | 1 | Multiplier on duration. 2 orbits twice as fast; 0.5 half as fast. |
delay | number | 0 | Seconds to wait before the orbit starts. |
reverse | boolean | false | Travel counter-clockwise. |
startAngle | number | 0 | Where on the circle the item starts, in degrees. 0 is the top, 180 the bottom. |
path | boolean | true | Draw the faint circle the items travel along. Set it on one instance per radius, otherwise the circles are drawn on top of each other. |
class | string | '' | CSS classes to apply to the orbit layer. |
UI
This component's theme exposes the slots below. Override any of them per instance with the ui prop, or app-wide under ui.orbitingCircles in app.config.ts.
| Prop | Type | Default | Description |
|---|---|---|---|
ui | object | - | Per-slot classes merged over the theme defaults. |
| Slot | Props | Description |
|---|---|---|
root | - | absolute inset-0 flex items-center justify-center |
path | - | pointer-events-none absolute inset-0 h-full w-full |
pathCircle | - | stroke-black/10 dark:stroke-white/10 |
orbit | - | orbit absolute flex size-full items-center justify-center rounded-full |