Spaces:
Build error
Build error
File size: 1,725 Bytes
75fefa7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
"use client";
import { motion } from "motion/react";
import React from "react";
interface DotGridLoaderProps {
size?: number; // pixel size of each dot
cols?: number;
rows?: number;
className?: string;
animated?: boolean;
intensityMap?: number[]; // per-dot base opacity 0..1, length cols*rows
}
export function DotGridLoader({
size = 10,
cols = 3,
rows = 3,
className,
animated = true,
intensityMap,
}: DotGridLoaderProps) {
const total = cols * rows;
const defaultMap = Array.from({ length: total }).map((_, i) => {
// Row alphas tuned to hero prompt style: top=0.4, middle=1, bottom=0.12
const row = Math.floor(i / cols);
if (row === 0) return 0.4; // top
if (row === 1) return 1.0; // middle
return 0.12; // bottom
});
const bases =
intensityMap && intensityMap.length === total ? intensityMap : defaultMap;
return (
<div
className={className}
style={{
display: "grid",
gridTemplateColumns: `repeat(${cols}, ${size}px)`,
gap: Math.max(2, Math.round(size / 3)),
}}
>
{Array.from({ length: total }).map((_, i) => {
const base = bases[i] ?? 0.8;
return (
<motion.div
key={i}
initial={{ opacity: base }}
animate={
animated ? { opacity: [base, 1, base] } : { opacity: base }
}
transition={
animated
? { duration: 1.1, repeat: Infinity, delay: i * 0.08 }
: undefined
}
style={{ width: size, height: size }}
className="rounded-[2px] bg-heat-100"
/>
);
})}
</div>
);
}
export default DotGridLoader;
|