A grid of dots that plays frame-by-frame animations, for loading and status indicators.
Installation
Usage
<script setup lang="ts">
import type { Frames } from '@animate-ui/vue/primitives/motion-grid';
import { MotionGrid, MotionGridCells } from '@animate-ui/vue/primitives/motion-grid';
// Each frame lists the active cells as [column, row].
const frames: Frames = [
[[1, 1]],
[[0, 1], [1, 0], [1, 2], [2, 1]],
[[0, 0], [0, 2], [2, 0], [2, 2]],
[],
];
</script>
<template>
<MotionGrid :grid-size="[3, 3]" :frames="frames" class="gap-0.5">
<MotionGridCells class="size-1 rounded-full bg-foreground/20 data-[active=true]:bg-foreground" />
</MotionGrid>
</template>Active cells have data-active="true": style them with it, or pass active-props and inactive-props.
Editor
My Animations
Animations stored in local storage
Create New Animation
ms
<script setup lang="ts">import type { Frames } from '@animate-ui/vue/primitives/motion-grid';import { MotionGrid, MotionGridCells } from '@animate-ui/vue/primitives/motion-grid';const frames: Frames = [ [],];</script><template> <MotionGrid :grid-size="[7, 7]" :frames="frames" class="gap-0.5"> <MotionGridCells class="size-1 rounded-full bg-foreground/20 data-[active=true]:bg-foreground" /> </MotionGrid></template>Animation
- The grid shows one frame every
durationmilliseconds, looping. - Cells change with your own CSS transitions or Motion props (
active-props). Motion props takedurationwith an ease-in-out; CSS transitions keep their own timing. - The loop pauses while the grid is off screen or the tab is hidden.
API Reference
MotionGrid
| Prop | Type | Default |
|---|---|---|
as-child? | boolean | false |
grid-size | [number, number] | - |
frames | [number, number][][] | - |
duration? | number | 200 |
animate? | boolean | true |
...props? | HTMLMotionProps<'div'> | - |
MotionGridCells
Renders every cell of the grid.
| Prop | Type | Default |
|---|---|---|
active-props? | HTMLMotionProps<'div'> | - |
inactive-props? | HTMLMotionProps<'div'> | - |
...props? | HTMLMotionProps<'div'> | - |
Credits
- Inspired by Adrien Griveau's post.