southernmonsarysupply/components/hero-cinema.tsx

131 lines
3.5 KiB
TypeScript

"use client";
import { useEffect, useRef, useState } from "react";
import Image from "next/image";
import { siteConfig } from "@/data/site-content";
const slides = [
{
src: "/herosection/A_massive_perfectly_organized_masonry_supply_yard__delpmaspu.webp",
alt: "Masonry Supply Yard",
},
{
src: "/herosection/Closeup_cinematic_macro_shot_of_a_stack_of_premium_delpmaspu.webp",
alt: "Premium Masonry Materials",
},
{
src: "/herosection/Ultrarealistic_cinematic_wide_shot_for_a_professio_delpmaspu.webp",
alt: "Professional Masonry Project",
},
{
src: "/herosection/Wide_angle_architectural_shot_of_a_contemporary_st_delpmaspu.webp",
alt: "Contemporary Stone Architecture",
},
];
export function HeroCinema() {
const [current, setCurrent] = useState(0);
const [previous, setPrevious] = useState<number | null>(null);
const currentRef = useRef(0);
const clearPreviousTimerRef = useRef<number | null>(null);
function transitionTo(nextIndex: number) {
if (nextIndex === currentRef.current) {
return;
}
setPrevious(currentRef.current);
setCurrent(nextIndex);
currentRef.current = nextIndex;
if (clearPreviousTimerRef.current) {
window.clearTimeout(clearPreviousTimerRef.current);
}
clearPreviousTimerRef.current = window.setTimeout(() => {
setPrevious(null);
clearPreviousTimerRef.current = null;
}, 1400);
}
useEffect(() => {
const timer = window.setInterval(() => {
transitionTo((currentRef.current + 1) % slides.length);
}, 4500);
return () => {
window.clearInterval(timer);
if (clearPreviousTimerRef.current) {
window.clearTimeout(clearPreviousTimerRef.current);
}
};
}, []);
const renderedSlides =
previous === null
? [current]
: [previous, current].filter(
(index, position, values) => values.indexOf(index) === position,
);
return (
<div className="hc-root">
{renderedSlides.map((index) => {
const slide = slides[index];
const isCurrent = index === current;
return (
<div
key={`${index}-${isCurrent ? "current" : "previous"}`}
className="hc-slide-full"
style={{
opacity: isCurrent ? 1 : 0,
transition: "opacity 1.4s ease",
zIndex: isCurrent ? 2 : 1,
}}
>
<Image
src={slide.src}
alt={slide.alt}
fill
sizes="(max-width: 1100px) 100vw, 50vw"
quality={72}
className="cover-image"
priority={isCurrent && index === 0}
/>
</div>
);
})}
<div className="hc-overlay" />
<div className="hc-dots">
{slides.map((_, i) => (
<button
key={i}
className={`hc-dot${i === current ? " hc-dot-active" : ""}`}
onClick={() => transitionTo(i)}
aria-label={`Show image ${i + 1}`}
/>
))}
</div>
<div className="hc-video-card">
<video
className="hc-video-small"
autoPlay
muted
loop
playsInline
poster={siteConfig.heroMedia.featureCardImage}
aria-label={siteConfig.heroMedia.featureCardAlt}
>
<source src={siteConfig.heroMedia.featureCardVideo} type="video/mp4" />
</video>
<div className="hc-video-card-badge">LIVE FROM THE YARD</div>
</div>
</div>
);
}