UNPKG

lightswind

Version:

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

86 lines (85 loc) 4.82 kB
"use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { motion } from "framer-motion"; // Main Component export const ThreeDMarquee = ({ images, className = "", onImageClick, }) => { // Divide images into 4 groups const groupSize = Math.ceil(images.length / 4); const imageGroups = Array.from({ length: 4 }, (_, index) => images.slice(index * groupSize, (index + 1) * groupSize)); const handleImageClick = (image, globalIndex) => { if (onImageClick) { onImageClick(image, globalIndex); } else if (image.href) { window.open(image.href, image.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", { style: { transform: "rotateX(55deg) rotateY(0deg) rotateZ(45deg)", }, className: "relative grid w-full h-full origin-center \r\n grid-cols-4 gap-6 transform-3d place-items-center", children: imageGroups.map((imagesInGroup, idx) => (_jsxs(motion.div, { 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" }), imagesInGroup.map((image, imgIdx) => { const globalIndex = idx * groupSize + imgIdx; const isClickable = image.href || onImageClick; return (_jsxs("div", { className: "relative", children: [_jsx(HorizontalGridLine, { extraStyles: "-top-4", spacing: "20px" }), _jsx(motion.img, { whileHover: { y: -10 }, transition: { duration: 0.3, ease: "easeInOut" }, src: image.src, alt: image.alt, width: 970, height: 700, className: `aspect-[970/700] 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" : ""}`, onClick: () => handleImageClick(image, globalIndex) })] }, `img-${imgIdx}`)); })] }, `column-${idx}`))) }) }) }) })); }; // Horizontal Grid Line const HorizontalGridLine = ({ extraStyles = "", spacing = "200px", }) => { 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", }; 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 const VerticalGridLine = ({ extraStyles = "", spacing = "150px", }) => { 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", }; 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 }); }; export default ThreeDMarquee;