troylusty.com/src/components/Slideshow.astro

79 lines
2.2 KiB
Text
Raw Normal View History

---
import { Image } from "astro:assets";
import type { CollectionEntry } from "astro:content";
interface Props {
images: CollectionEntry<"projects">[];
interval?: number;
}
const { interval = 3000, images } = Astro.props;
---
<div
2025-02-25 13:17:10 +00:00
class="group relative min-h-[50svh] w-full overflow-hidden"
data-interval={interval}
>
{
images.map((image: any, index: number) => (
<div
class="absolute top-0 left-0 h-full w-full transition-opacity duration-500"
style={`opacity: ${index === 0 ? 1 : 0}; z-index: ${
index === 0 ? 10 : 1
}`}
data-slide-index={index}
>
<a href={`/${image.collection}/${image.slug}`}>
<Image
src={image.data.image.url}
alt={`Slide ${index + 1}`}
2025-02-25 13:17:10 +00:00
class="h-full w-full rounded-sm object-cover transition-all duration-300 group-hover:brightness-50"
loading="eager"
2025-06-20 10:56:34 +01:00
{...(index === 0 && { priority: true })}
/>
<div class="relative opacity-0 transition-all delay-100 duration-300 ease-in-out group-hover:opacity-100">
2025-05-06 22:50:48 +01:00
<p class="absolute right-5 bottom-5 font-medium text-white">
{image.data.title}
</p>
</div>
</a>
</div>
))
}
</div>
<script>
2025-07-18 23:29:03 +01:00
const images = Array.from(
document.querySelectorAll<HTMLElement>("[data-slide-index]"),
);
let currentImageIndex = 0;
2025-07-18 23:29:03 +01:00
const closestRelativeElement = document
.querySelector<HTMLElement>("[data-slide-index]")
?.closest(".relative") as HTMLElement | null;
const interval = Number(closestRelativeElement?.dataset?.interval) || 3000;
for (let i = images.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[images[i], images[j]] = [images[j], images[i]];
}
images.forEach((img, index) => {
img.style.opacity = index === 0 ? "1" : "0";
img.style.zIndex = index === 0 ? "10" : "1";
});
function showNextImage() {
images[currentImageIndex].style.opacity = "0";
images[currentImageIndex].style.zIndex = "1";
2025-07-18 23:29:03 +01:00
currentImageIndex = (currentImageIndex + 1) % images.length;
2025-07-18 23:29:03 +01:00
images[currentImageIndex].style.opacity = "1";
images[currentImageIndex].style.zIndex = "10";
}
setInterval(showNextImage, interval);
</script>