<div class="stagger-stage">
<div class="example">
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
<button aria-label="Ripple from here"></button>
</div>
</div>
<script type="module">
import { animate, stagger } from "motion"
const grid = document.querySelector(".example")
const cells = grid.querySelectorAll("button")
// Read the number of columns and rows from the CSS grid
const style = getComputedStyle(grid)
const columns = style.gridTemplateColumns.split(" ").length
const rows = style.gridTemplateRows.split(" ").length
// Fade in from the centre of the grid
animate(
cells,
{ opacity: 1, scale: [0.5, 1] },
{ delay: stagger(0.05, { grid: [columns, rows], from: "center" }) }
)
// Ripple outwards from the clicked cell
cells.forEach((cell, i) => {
cell.addEventListener("click", () => {
animate(
cells,
{ scale: [1, 0.4, 1] },
{
duration: 0.6,
delay: stagger(0.05, { grid: [columns, rows], from: i }),
}
)
// Mark the origin cell
grid.querySelector(".stagger-origin")?.classList.remove("stagger-origin")
cell.classList.add("stagger-origin")
})
})
</script>
<style>
#example-container {
display: flex;
flex: 1;
align-self: stretch;
}
.stagger-stage {
--ink: oklch(0.145 0.01 148);
--paper: oklch(0.94 0.008 96);
--plate: var(--paper);
--origin: oklch(0.88 0.18 96);
position: relative;
display: flex;
flex: 1;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 32px 16px;
background-color: var(--ink);
color: var(--paper);
}
.example {
display: grid;
grid-template-columns: repeat(8, clamp(22px, 6vw, 40px));
grid-template-rows: repeat(6, clamp(22px, 6vw, 40px));
gap: clamp(4px, 1.4vw, 10px);
}
.example button {
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 0;
border: none;
background-color: var(--plate);
cursor: pointer;
opacity: 0;
}
.example button:hover {
background-color: var(--origin);
}
.example button:focus-visible {
outline: 1px solid var(--paper);
outline-offset: 2px;
}
.example button.stagger-origin {
background-color: var(--origin);
}
</style>