Files
reui-blocks/blocks/gallery21.tsx
T

185 lines
5.5 KiB
TypeScript

"use client";
import "swiper/css/effect-coverflow";
import "swiper/css/pagination";
import "swiper/css/navigation";
import "swiper/css";
import "swiper/css/effect-cards";
import { motion } from "framer-motion";
import { ArrowRight } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import type { Swiper as SwiperType } from "swiper";
import { Autoplay, EffectCoverflow } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
const IMAGES = [
{
src: "/block-media/shadcnblocks/block/lummi/random11.jpeg",
alt: "اجرای زنده موسیقی در فضای شهری",
},
{
src: "/block-media/shadcnblocks/block/lummi/random1.jpeg",
alt: "نوازنده در استودیو ضبط",
},
{
src: "/block-media/shadcnblocks/block/lummi/random2.jpeg",
alt: "جمعیت در کنسرت روباز",
},
{
src: "/block-media/shadcnblocks/block/lummi/random11.jpeg",
alt: "صحنه اجرای موسیقی الکترونیک",
},
{
src: "/block-media/shadcnblocks/block/lummi/random1.jpeg",
alt: "تمرین گروه موسیقی",
},
{
src: "/block-media/shadcnblocks/block/lummi/random2.jpeg",
alt: "جشن موسیقی در فضای باز",
},
];
const css = `
.mySwiper21 {
width: 100%;
height: 420px;
padding-bottom: 50px;
}
.mySwiper21 .swiper-slide {
background-position: center;
background-size: cover;
width: 300px;
}
.mySwiper21 .swiper-slide img {
display: block;
width: 100%;
}
.swiper-3d .swiper-slide-shadow-left {
background-image: none;
}
.swiper-3d .swiper-slide-shadow-right {
background: none;
}
`;
interface Gallery21Props {
className?: string;
}
const Gallery21 = ({ className }: Gallery21Props) => {
const swiperRef = useRef<SwiperType | null>(null);
const swiperContainerRef = useRef<HTMLDivElement>(null);
const [swiperReady, setSwiperReady] = useState(false);
useEffect(() => {
const swiper = swiperRef.current;
if (!swiper || !swiperReady) {
return;
}
const updateSwiper = () => {
swiper.update();
swiper.slideToLoop(swiper.realIndex, 0);
};
updateSwiper();
const container = swiperContainerRef.current;
if (!container) {
return;
}
const resizeObserver = new ResizeObserver(updateSwiper);
resizeObserver.observe(container);
return () => {
resizeObserver.disconnect();
};
}, [swiperReady]);
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<style>{css}</style>
<div className="container">
<div className="relative mx-auto flex w-full max-w-4xl flex-col items-center gap-10">
<div
ref={swiperContainerRef}
dir="rtl"
className="relative h-[420px] w-full overflow-hidden"
>
<div className="pointer-events-none absolute inset-y-0 start-0 z-10 w-16 bg-gradient-to-r from-background to-transparent sm:w-24 lg:w-32" />
<div className="pointer-events-none absolute inset-y-0 end-0 z-10 w-16 bg-gradient-to-l from-background to-transparent sm:w-24 lg:w-32" />
<motion.div
className="relative mx-auto flex h-full w-full items-center justify-center"
initial={{ opacity: 0, translateY: 20 }}
animate={{ opacity: 1, translateY: 0 }}
transition={{
duration: 0.3,
delay: 0.5,
}}
>
<Swiper
spaceBetween={50}
autoplay={{
delay: 1500,
disableOnInteraction: false,
}}
effect="coverflow"
grabCursor={true}
centeredSlides={true}
centeredSlidesBounds={true}
loop={true}
slidesPerView={2.447}
coverflowEffect={{
rotate: 0,
stretch: 0,
depth: 100,
modifier: 2.5,
}}
className="mySwiper21"
modules={[EffectCoverflow, Autoplay]}
onSwiper={(swiper) => {
swiperRef.current = swiper;
setSwiperReady(true);
}}
>
{IMAGES.map((image, index) => (
<SwiperSlide key={`${image.alt}-${index}`}>
<img
className="h-full w-full overflow-hidden rounded-3xl object-cover shadow-lg"
src={image.src}
alt={image.alt}
/>
</SwiperSlide>
))}
</Swiper>
</motion.div>
</div>
<div className="flex flex-col items-center justify-center text-center">
<h3 className="max-w-sm px-2 text-xl font-medium tracking-tight">
موسیقی را بشنوید: تجربه‌ای بی‌سابقه
</h3>
<Button
variant="secondary"
className="group mt-10 flex items-center justify-center gap-2 rounded-full tracking-tight"
>
کشف موسیقی
<ArrowRight className="size-4 -rotate-45 transition-all ease-out group-hover:rotate-0 rtl:rotate-[135deg] rtl:group-hover:rotate-0" />
</Button>
</div>
</div>
</div>
</section>
);
};
export { Gallery21 };