Docs
Water Drop Grid
A water drop grid is a visual effect where grid elements ripple or distort like water droplets when interacted with, creating a fluid and organic animation.
Installation
Install dependencies
npm install framer-motion lucide-react
Run the following command
It will create a new file water-drop-grid.tsx
inside the components/mage-ui/background
directory.
mkdir -p components/mage-ui/background && touch components/mage-ui/background/water-drop-grid.tsx
Paste the code
Open the newly created file and paste the following code:
"use client";
import anime from "animejs";
import React from "react";
const WaterDropGrid: React.FC = () => {
return (
<div className="relative grid place-content-center bg-slate-900 px-8 py-12">
<DotGrid />
</div>
);
};
const GRID_WIDTH = 25;
const GRID_HEIGHT = 20;
const DotGrid: React.FC = () => {
const handleDotClick = (e: React.MouseEvent<HTMLDivElement>) => {
const target = e.target as HTMLElement;
// Safely access dataset.index with fallback
const index = parseInt(target.dataset?.index || "0");
anime({
targets: ".dot-point",
scale: [
{ value: 1.35, easing: "easeOutSine", duration: 250 },
{ value: 1, easing: "easeInOutQuad", duration: 500 },
],
translateY: [
{ value: -15, easing: "easeOutSine", duration: 250 },
{ value: 0, easing: "easeInOutQuad", duration: 500 },
],
opacity: [
{ value: 1, easing: "easeOutSine", duration: 250 },
{ value: 0.5, easing: "easeInOutQuad", duration: 500 },
],
delay: anime.stagger(100, {
grid: [GRID_WIDTH, GRID_HEIGHT],
from: index,
}),
});
};
const dots: JSX.Element[] = [];
let index = 0;
for (let i = 0; i < GRID_WIDTH; i++) {
for (let j = 0; j < GRID_HEIGHT; j++) {
dots.push(
<div
className="group cursor-crosshair rounded-full p-2 transition-colors hover:bg-slate-600"
data-index={index}
key={`${i}-${j}`}
>
<div
className="dot-point h-2 w-2 rounded-full bg-gradient-to-b from-slate-700 to-slate-400 opacity-50 group-hover:from-indigo-600 group-hover:to-white"
data-index={index}
/>
</div>
);
index++;
}
}
return (
<div
onClick={handleDotClick}
style={{ gridTemplateColumns: `repeat(${GRID_WIDTH}, 1fr)` }}
className="grid w-fit"
>
{dots}
</div>
);
};
export default WaterDropGrid;