81 lines
2.6 KiB
TypeScript
81 lines
2.6 KiB
TypeScript
import { useMemo } from "react";
|
|
|
|
const ARTISTS = [
|
|
"Kastelruther Spatzen", "Melanie Payer", "Linda Feller", "Die Edlseer",
|
|
"Hansi Berger", "Sašo Avsenik", "Die Grubertaler", "Pagger Buam",
|
|
"John Prisco", "Igor und seine Oberkrainer", "Die Kaiser", "Marlena Martinelli",
|
|
"Spitzbua Markus", "Julia Raich", "Meissnitzer Band", "Tauern Echo",
|
|
"Brennholz", "Charly Kaiser", "Franz Nolf", "Franz Steiner",
|
|
"Die 3 Z'widern", "Mark Ed", "Natascha", "Meli Stein",
|
|
"SUSAL", "Pfundskerle", "Da Wadltreiber", "Sanny",
|
|
"Alex Reichinger", "Sigrid & Marina", "Folx Stadl", "Gipfelstammtisch",
|
|
"Wildecker Herzbuben", "Herzilein", "Jonny Hill", "Ramona Martiness",
|
|
"Kayla Kristin", "Kevin Neon", "Robi Zupan", "Oberkrainer",
|
|
];
|
|
|
|
function seededRandom(seed: number) {
|
|
let s = seed;
|
|
return () => {
|
|
s = (s * 16807 + 0) % 2147483647;
|
|
return s / 2147483647;
|
|
};
|
|
}
|
|
|
|
interface Props {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
seed?: number;
|
|
}
|
|
|
|
export default function ArtistPatternBg({ children, className = "", seed = 42 }: Props) {
|
|
const items = useMemo(() => {
|
|
const rng = seededRandom(seed);
|
|
const result: { name: string; x: number; y: number; size: number; opacity: number; rotation: number; italic: boolean }[] = [];
|
|
const rows = 20;
|
|
const cols = 6;
|
|
for (let row = 0; row < rows; row++) {
|
|
for (let col = 0; col < cols; col++) {
|
|
const cellW = 100 / cols;
|
|
const cellH = 100 / rows;
|
|
result.push({
|
|
name: ARTISTS[Math.floor(rng() * ARTISTS.length)],
|
|
x: col * cellW + rng() * cellW * 0.8,
|
|
y: row * cellH + rng() * cellH * 0.7,
|
|
size: 10 + rng() * 8,
|
|
opacity: 0.07 + rng() * 0.11,
|
|
rotation: -20 + rng() * 40,
|
|
italic: rng() > 0.6,
|
|
});
|
|
}
|
|
}
|
|
return result;
|
|
}, [seed]);
|
|
|
|
return (
|
|
<div className={`relative overflow-hidden ${className}`}>
|
|
<div className="absolute inset-0 pointer-events-none select-none" aria-hidden="true">
|
|
{items.map((item, i) => (
|
|
<span
|
|
key={i}
|
|
className="absolute whitespace-nowrap text-foreground"
|
|
style={{
|
|
left: `${item.x}%`,
|
|
top: `${item.y}%`,
|
|
fontSize: `${item.size}px`,
|
|
opacity: item.opacity,
|
|
transform: `rotate(${item.rotation}deg)`,
|
|
fontStyle: item.italic ? "italic" : "normal",
|
|
fontWeight: item.italic ? 300 : 400,
|
|
}}
|
|
>
|
|
{item.name}
|
|
</span>
|
|
))}
|
|
</div>
|
|
<div className="relative z-[1]">
|
|
{children}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|