UNPKG

lightswind

Version:

A professionally designed animate react component library & templates market that brings together functionality, accessibility, and beautiful aesthetics for modern applications.

109 lines (108 loc) 6.36 kB
"use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { motion } from "framer-motion"; // Horizontal Grid Line component for visual effect const HorizontalGridLine = ({ extraStyles = "", spacing = "20px", }) => { // Inline styles for the grid line appearance const lineStyles = { "--background": "#ffffff", "--color": "rgba(0, 0, 0, 0.2)", "--height": "1px", "--width": "5px", "--fade-stop": "90%", "--offset": spacing, "--color-dark": "rgba(255, 255, 255, 0.2)", maskComposite: "exclude", }; // Tailwind CSS classes for positioning and appearance const baseClasses = [ "absolute", "left-[calc(var(--offset)/-2)]", "h-[var(--height)]", "w-[calc(100%+var(--offset))]", "bg-[linear-gradient(to_right,var(--color),var(--color)_50%,transparent_0,transparent)]", "[background-size:var(--width)_var(--height)]", "[mask:linear-gradient(to_left,var(--background)_var(--fade-stop),transparent),linear-gradient(to_right,var(--background)_var(--fade-stop),transparent),linear-gradient(black,black)]", "[mask-composite:exclude]", "z-30", "dark:bg-black", extraStyles, ].join(" "); return _jsx("div", { style: lineStyles, className: baseClasses }); }; // Vertical Grid Line component for visual effect const VerticalGridLine = ({ extraStyles = "", spacing = "150px", }) => { // Inline styles for the grid line appearance const lineStyles = { "--background": "#ffffff", "--color": "rgba(0, 0, 0, 0.2)", "--height": "5px", "--width": "1px", "--fade-stop": "90%", "--offset": spacing, "--color-dark": "rgba(0, 0, 0, 0.2)", maskComposite: "exclude", }; // Tailwind CSS classes for positioning and appearance const baseClasses = [ "absolute", "top-[calc(var(--offset)/-2)]", "h-[calc(100%+var(--offset))]", "w-[var(--width)]", "bg-[linear-gradient(to_bottom,var(--color),var(--color)_50%,transparent_0,transparent)]", "[background-size:var(--width)_var(--height)]", "[mask:linear-gradient(to_top,var(--background)_var(--fade-stop),transparent),linear-gradient(to_bottom,var(--background)_var(--fade-stop),transparent),linear-gradient(black,black)]", "[mask-composite:exclude]", "z-30", "dark:bg-black", extraStyles, ].join(" "); return _jsx("div", { style: lineStyles, className: baseClasses }); }; // Main ThreeDCompMarquee component export const ThreeDCompMarquee = ({ compItems, className = "", onCompItemClick, }) => { // Divide items into 4 groups for the columns const groupSize = Math.ceil(compItems.length / 4); const itemGroups = Array.from({ length: 4 }, (_, index) => compItems.slice(index * groupSize, (index + 1) * groupSize)); // Handles click on an item, either via onCompItemClick prop or href const handleItemClick = (item, globalIndex) => { if (onCompItemClick) { onCompItemClick(item, globalIndex); } else if (item.href) { window.open(item.href, item.target || "_self"); } }; return (_jsx("section", { className: `mx-auto block h-[600px] overflow-hidden rounded-2xl max-sm:h-[400px] bg-white dark:bg-black ${className}`, children: _jsx("div", { className: "flex w-full h-full items-center justify-center", children: _jsx("div", { className: "w-[1520px] shrink-0 scale-50 sm:scale-75 lg:scale-100", children: _jsx("div", { // Apply 3D rotation for the marquee effect style: { transform: "rotateX(55deg) rotateY(0deg) rotateZ(35deg)", transformStyle: "preserve-3d", // Ensure child elements can have 3D transforms }, className: "relative grid w-full h-full origin-center grid-cols-4 \r\n gap-6 place-items-center", children: itemGroups.map((itemsInGroup, idx) => (_jsxs(motion.div, { // Animate columns vertically for continuous movement animate: { y: idx % 2 === 0 ? 100 : -100 }, transition: { duration: idx % 2 === 0 ? 10 : 15, repeat: Infinity, repeatType: "reverse", }, className: "flex flex-col items-center gap-6", children: [_jsx(VerticalGridLine, { extraStyles: "-left-4", spacing: "80px" }), itemsInGroup.map((item, itemIdx) => { const globalIndex = idx * groupSize + itemIdx; const isClickable = item.href || onCompItemClick; return (_jsxs(motion.div, { // Hover effect: slight lift and scale up whileHover: { y: -10, scale: 1.05 }, transition: { duration: 0.3, ease: "easeInOut" }, // Styling for the individual component card className: `relative rounded-lg object-cover ring ring-gray-300/30 dark:ring-gray-800/50 shadow-xl dark:shadow-gray-900 hover:shadow-3xl dark:hover:shadow-gray-800 transition-shadow duration-300 ${isClickable ? "cursor-pointer" : ""} min-w-[350px] max-w-[350px] h-[350px] sm:w-[970px] sm:h-[350px] // Responsive fixed size for cards flex items-center justify-center overflow-hidden bg-white dark:bg-black // Background for the component card p-4 // Padding inside the card `, onClick: () => handleItemClick(item, globalIndex), style: { transformStyle: "preserve-3d" }, children: [_jsx(HorizontalGridLine, { extraStyles: "-top-4", spacing: "20px" }), _jsx("div", { className: "w-full h-full flex items-center \r\n justify-center", children: item.content })] }, item.id)); })] }, `column-${idx}`))) }) }) }) })); }; export default ThreeDCompMarquee;