"use client"; import { useEffect, useRef } from 'react'; import { colors } from '@/lib/colors'; function lerp(a: number, b: number, t: number) { return (b - a) * t + a; } // Convert hex to RGB function hexToRgb(hex: string): { r: number; g: number; b: number } { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16), } : { r: 0, g: 0, b: 0 }; } // Interpolate between two hex colors function interpolateColor(color1: string, color2: string, t: number): string { const rgb1 = hexToRgb(color1); const rgb2 = hexToRgb(color2); const r = Math.round(lerp(rgb1.r, rgb2.r, t)); const g = Math.round(lerp(rgb1.g, rgb2.g, t)); const b = Math.round(lerp(rgb1.b, rgb2.b, t)); return `rgb(${r}, ${g}, ${b})`; } function color(i: number, total: number) { const t = i / total; // Interpolate between Webklar colors: primary (dark green) -> secondary (medium green) -> tertiary (light green-beige) if (t < 0.5) { return interpolateColor(colors.primary, colors.secondary, t * 2); } else { return interpolateColor(colors.secondary, colors.tertiary, (t - 0.5) * 2); } } function createWheel(i: number, total: number) { const distance = i + 3.5; // Slightly increased distance const charWidth = 0.85; const speed = 1; const circum = distance * 2 * Math.PI; const numbers = Math.floor(circum / charWidth); const time = speed * numbers; const t = i / total; return { time, numbers, distance, color: color(i, total), scale: lerp(1, 0.25, t * t * 0.5), // Medium scale }; } export default function SpinningNumbers() { const containerRef = useRef(null); useEffect(() => { if (!containerRef.current) return; const container = containerRef.current; const total = 13; const wheels = Array.from({ length: total }, (_, i) => createWheel(i, total)); wheels.forEach((wheel) => { const { time, numbers, distance, color: wheelColor, scale } = wheel; const angleDiff = (Math.PI * 2) / numbers; const divs = []; for (let i = 0; i < numbers; i++) { divs.push(angleDiff * i); } const wheelDiv = document.createElement('div'); wheelDiv.className = 'wheel'; wheelDiv.style.color = wheelColor; wheelDiv.style.setProperty('--l', `${distance}em`); wheelDiv.style.setProperty('--m', `${numbers}`); wheelDiv.style.setProperty('--t', `${time}s`); wheelDiv.style.setProperty('--r1', Math.random() < 0.5 ? 'reverse' : 'normal'); wheelDiv.style.setProperty('--s', `${scale}`); divs.forEach((angle, i) => { if (Math.sqrt(Math.random()) < scale) { const numberDiv = document.createElement('div'); numberDiv.className = 'number'; numberDiv.style.setProperty('--a', `${(angle * 180) / Math.PI}deg`); numberDiv.style.setProperty('--i', `${i}`); numberDiv.style.setProperty('--r', Math.random() < 0.5 ? 'reverse' : 'normal'); wheelDiv.appendChild(numberDiv); } }); container.appendChild(wheelDiv); }); // Cleanup function return () => { if (container) { container.innerHTML = ''; } }; }, []); return (
); }