"use client"; import { useEffect, useRef } from "react"; import { motion } from "framer-motion"; import { Palette, Monitor, FileImage, ArrowRight, LucideIcon } from "lucide-react"; import Link from "next/link"; import gsap from "gsap"; const categories = [ { icon: Monitor, title: "Digital Art", description: "Create stunning digital masterpieces using any software of your choice.", color: "from-violet-500 to-purple-600", bgColor: "bg-violet-500", }, { icon: Palette, title: "Paintings", description: "Traditional paintings in any medium - oil, acrylic, watercolor.", color: "from-orange-500 to-red-500", bgColor: "bg-orange-500", }, { icon: FileImage, title: "Poster Making", description: "Design impactful posters that communicate powerful messages.", color: "from-lime-500 to-green-500", bgColor: "bg-lime-500", }, ]; // BounceCards Component for Category Cards interface CategoryCard { icon: LucideIcon; title: string; description: string; color: string; bgColor: string; } interface BounceCardsProps { className?: string; cards: CategoryCard[]; containerWidth?: number; containerHeight?: number; animationDelay?: number; animationStagger?: number; easeType?: string; transformStyles?: string[]; enableHover?: boolean; } function BounceCards({ className = "", cards, containerWidth = 500, containerHeight = 400, animationDelay = 0.5, animationStagger = 0.08, easeType = "elastic.out(1, 0.8)", transformStyles = [ "rotate(-8deg) translate(-200px)", "rotate(0deg)", "rotate(8deg) translate(200px)", ], enableHover = true, }: BounceCardsProps) { const containerRef = useRef(null); useEffect(() => { const ctx = gsap.context(() => { gsap.fromTo( ".card", { scale: 0 }, { scale: 1, stagger: animationStagger, ease: easeType, delay: animationDelay, } ); }, containerRef); return () => ctx.revert(); }, [animationDelay, animationStagger, easeType]); const getNoRotationTransform = (transformStr: string): string => { const hasRotate = /rotate\([\s\S]*?\)/.test(transformStr); if (hasRotate) { return transformStr.replace(/rotate\([\s\S]*?\)/, "rotate(0deg)"); } else if (transformStr === "none") { return "rotate(0deg)"; } else { return `${transformStr} rotate(0deg)`; } }; const getPushedTransform = ( baseTransform: string, offsetX: number ): string => { const translateRegex = /translate\(([-0-9.]+)px\)/; const match = baseTransform.match(translateRegex); if (match) { const currentX = parseFloat(match[1]); const newX = currentX + offsetX; return baseTransform.replace(translateRegex, `translate(${newX}px)`); } else { return baseTransform === "none" ? `translate(${offsetX}px)` : `${baseTransform} translate(${offsetX}px)`; } }; const pushSiblings = (hoveredIdx: number) => { const q = gsap.utils.selector(containerRef); if (!enableHover || !containerRef.current) return; cards.forEach((_, i) => { const selector = q(`.card-${i}`); gsap.killTweensOf(selector); const baseTransform = transformStyles[i] || "none"; if (i === hoveredIdx) { const noRotation = getNoRotationTransform(baseTransform); gsap.to(selector, { transform: noRotation, zIndex: 10, duration: 0.4, ease: "back.out(1.4)", overwrite: "auto", }); } else { const offsetX = i < hoveredIdx ? -80 : 80; const pushedTransform = getPushedTransform(baseTransform, offsetX); const distance = Math.abs(hoveredIdx - i); const delay = distance * 0.05; gsap.to(selector, { transform: pushedTransform, zIndex: 1, duration: 0.4, ease: "back.out(1.4)", delay, overwrite: "auto", }); } }); }; const resetSiblings = () => { if (!enableHover || !containerRef.current) return; const q = gsap.utils.selector(containerRef); cards.forEach((_, i) => { const selector = q(`.card-${i}`); gsap.killTweensOf(selector); const baseTransform = transformStyles[i] || "none"; gsap.to(selector, { transform: baseTransform, zIndex: cards.length - i, duration: 0.4, ease: "back.out(1.4)", overwrite: "auto", }); }); }; return (
{cards.map((card, idx) => (
pushSiblings(idx)} onMouseLeave={resetSiblings} > {/* Icon */}
{/* Title */}

{card.title}

{/* Description */}

{card.description}

{/* Submit Link */}
Submit Now
))}
); } export default function Categories() { const transformStyles = [ "rotate(-8deg) translate(-220px)", "rotate(0deg)", "rotate(8deg) translate(220px)", ]; return (
{/* Section Header */} CATEGORIES

Three Ways to Express

Choose your canvas, unleash your creativity. Each category offers a unique way to showcase your artistic vision.

{/* BounceCards with Category Cards */}
); }