'use client'; import React, { useRef, useId, useEffect, CSSProperties } from 'react'; import { animate, useMotionValue, AnimationPlaybackControls, motion } from 'framer-motion'; import { cn } from '../lib/utils'; // Type definitions interface ResponsiveImage { src: string; alt?: string; srcSet?: string; } interface AnimationConfig { preview?: boolean; scale: number; speed: number; } interface NoiseConfig { opacity: number; scale: number; } interface ShadowOverlayProps { type?: 'preset' | 'custom'; presetIndex?: number; customImage?: ResponsiveImage; sizing?: 'fill' | 'stretch'; color?: string; animation?: AnimationConfig; noise?: NoiseConfig; style?: CSSProperties; className?: string; title?: string; description?: string; } function mapRange( value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number ): number { if (fromLow === fromHigh) { return toLow; } const percentage = (value - fromLow) / (fromHigh - fromLow); return toLow + percentage * (toHigh - toLow); } const useInstanceId = (): string => { const id = useId(); const cleanId = id.replace(/:/g, ""); const instanceId = `shadowoverlay-${cleanId}`; return instanceId; }; export function ShadowSection({ sizing = 'fill', color = 'rgba(99, 102, 241, 0.6)', animation = { scale: 50, speed: 15 }, noise = { opacity: 0.1, scale: 0.5 }, style, className, title = "Cognitive Core", description = "The unseen intelligence powering your most critical decisions." }: ShadowOverlayProps) { const id = useInstanceId(); const animationEnabled = animation && animation.scale > 0; const feColorMatrixRef = useRef(null); const hueRotateMotionValue = useMotionValue(180); const hueRotateAnimation = useRef(null); const displacementScale = animation ? mapRange(animation.scale, 1, 100, 20, 100) : 0; const animationDuration = animation ? mapRange(animation.speed, 1, 100, 1000, 50) : 1; useEffect(() => { if (feColorMatrixRef.current && animationEnabled) { if (hueRotateAnimation.current) { hueRotateAnimation.current.stop(); } hueRotateMotionValue.set(0); hueRotateAnimation.current = animate(hueRotateMotionValue, 360, { duration: animationDuration / 25, repeat: Infinity, repeatType: "loop", repeatDelay: 0, ease: "linear", delay: 0, onUpdate: (value: number) => { if (feColorMatrixRef.current) { feColorMatrixRef.current.setAttribute("values", String(value)); } } }); return () => { if (hueRotateAnimation.current) { hueRotateAnimation.current.stop(); } }; } }, [animationEnabled, animationDuration, hueRotateMotionValue]); return (
{animationEnabled && ( )}
{title} {description}
{noise && noise.opacity > 0 && (
)} {/* Bottom Vignette */}
); }