home-hero-background-carousel.tsx 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. "use client";
  2. import { useEffect, useState } from "react";
  3. type HomeHeroBackgroundCarouselProps = {
  4. images: string[];
  5. intervalMs?: number;
  6. };
  7. export function HomeHeroBackgroundCarousel({
  8. images,
  9. intervalMs = 5000,
  10. }: HomeHeroBackgroundCarouselProps) {
  11. const safeImages = images.filter(Boolean);
  12. const [activeIndex, setActiveIndex] = useState(0);
  13. useEffect(() => {
  14. if (safeImages.length <= 1) return;
  15. const timer = window.setInterval(() => {
  16. setActiveIndex((prev) => (prev + 1) % safeImages.length);
  17. }, intervalMs);
  18. return () => window.clearInterval(timer);
  19. }, [intervalMs, safeImages.length]);
  20. if (safeImages.length === 0) return null;
  21. return (
  22. <div className="absolute inset-0 -z-20">
  23. {safeImages.map((src, idx) => (
  24. // eslint-disable-next-line @next/next/no-img-element
  25. <img
  26. key={src}
  27. src={src}
  28. alt=""
  29. aria-hidden="true"
  30. className={`absolute inset-0 h-full w-full object-cover transition-opacity duration-700 ${
  31. idx === activeIndex ? "opacity-100" : "opacity-0"
  32. }`}
  33. />
  34. ))}
  35. {/* 只在左侧做可读性增强,不整屏压暗 Banner */}
  36. <div className="absolute inset-y-0 left-0 w-[48%] bg-gradient-to-r from-slate-950/48 via-slate-950/18 to-transparent" />
  37. <div className="absolute inset-x-0 bottom-0 h-24 bg-gradient-to-t from-slate-950/30 to-transparent" />
  38. </div>
  39. );
  40. }