Skip to content

Commit

Permalink
fix: update Carousel loading behavior in Akash Insiders page (#453)
Browse files Browse the repository at this point in the history
fix: update Carousel loading behavior in Akash Insiders page
  • Loading branch information
HoomanDgtl authored Dec 10, 2024
1 parent 73213b2 commit 32b40c1
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 90 deletions.
88 changes: 0 additions & 88 deletions src/components/community-pages/carousel.tsx

This file was deleted.

42 changes: 42 additions & 0 deletions src/components/community-pages/custom-carousel/Carousel.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.carousel-container {
position: relative;
width: 100%;
overflow: hidden;
}

.carousel-track {
display: flex;
width: fit-content;
will-change: transform;
}

@keyframes smooth-scroll {
from {
transform: translateX(0);
}
to {
transform: translateX(calc(-1 * var(--scroll-width)));
}
}

.animate-scroll {
animation: smooth-scroll var(--animation-duration) linear infinite;
animation-fill-mode: forwards;
}

.carousel-track {
width: fit-content;
will-change: transform;
}

.carousel-item img {
max-width: 100%;
height: auto;
}

@media (min-width: 768px) {
.carousel-item img {
height: 100%;
object-fit: cover;
}
}
38 changes: 38 additions & 0 deletions src/components/community-pages/custom-carousel/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react";
import { CarouselItem } from "./CarouselItem";
import { useCarousel } from "./useCarousel";
import type { CarouselProps } from "./types";
import "./Carousel.css";

export const Carousel: React.FC<CarouselProps> = ({
images,
speed = 50,
gap = 20,
}) => {
const { containerRef, trackRef, isLoaded } = useCarousel(speed);

const displayImages = [...images, ...images, ...images];

return (
<div
ref={containerRef}
className="carousel-container w-full overflow-hidden bg-background"
aria-label="Image Carousel"
>
<div
ref={trackRef}
className="carousel-track flex"
style={{ gap: `${gap}px` }}
>
{displayImages.map((image, index) => (
<CarouselItem
key={`${image.src}-${index}`}
src={image.src}
alt={image.alt}
isLoaded={isLoaded}
/>
))}
</div>
</div>
);
};
31 changes: 31 additions & 0 deletions src/components/community-pages/custom-carousel/CarouselItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';

interface CarouselItemProps {
src: string;
alt: string;
isLoaded: boolean;
}

export const CarouselItem: React.FC<CarouselItemProps> = ({ src, alt, isLoaded }) => (
<div className="carousel-item mx-3 flex-shrink-0 md:mx-5 lg:mx-[28px]">
<img
src={src}
alt={alt}
width={260}
height={380}
className={`
aspect-auto
max-h-[14rem]
w-auto
md:h-full
md:max-h-[unset]
md:object-cover
${isLoaded ? 'opacity-100' : 'opacity-0'}
transition-opacity
duration-300
`}
draggable={false}
loading="lazy"
/>
</div>
);
10 changes: 10 additions & 0 deletions src/components/community-pages/custom-carousel/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface CarouselImage {
src: string;
alt: string;
}

export interface CarouselProps {
images: CarouselImage[];
speed?: number;
gap?: number;
}
50 changes: 50 additions & 0 deletions src/components/community-pages/custom-carousel/useCarousel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useEffect, useRef, useState } from "react";

export const useCarousel = (speed = 50) => {
const [isLoaded, setIsLoaded] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const trackRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const track = trackRef.current;
if (!track) return;

const images = Array.from(track.getElementsByTagName("img"));
Promise.all(
images.map(
(img) =>
new Promise((resolve) => {
if (img.complete) resolve(null);
img.onload = () => resolve(null);
img.onerror = () => resolve(null);
}),
),
).then(() => {
setIsLoaded(true);
});
}, []);

useEffect(() => {
if (!isLoaded) return;

const track = trackRef.current;
if (!track) return;

const totalWidth = track.scrollWidth;
const duration = totalWidth / speed;

track.style.setProperty("--scroll-width", `${totalWidth}px`);
track.style.setProperty("--animation-duration", `${duration}s`);
track.classList.add("animate-scroll");

return () => {
track.classList.remove("animate-scroll");
};
}, [isLoaded, speed]);

return {
containerRef,
trackRef,
isLoaded,
};
};
14 changes: 12 additions & 2 deletions src/pages/community/akash-insiders.astro
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
---
import Carousel from "@/components/community-pages/carousel";
import { Carousel } from "@/components/community-pages/custom-carousel/Carousel";
import PointerSection from "@/components/community-pages/pointer-section.astro";
import CommunityHero from "@/components/mdx-cards/community-hero.astro";
import ButtonLink from "@/components/ui/button-link.astro";
import TopMargin from "@/components/ui/top-margin.astro";
import Layout from "@/layouts/layout.astro";
const images = [
{ src: "/images/slides/slide1.webp", alt: "Slide 1" },
{ src: "/images/slides/slide2.webp", alt: "Slide 2" },
{ src: "/images/slides/slide3.webp", alt: "Slide 3" },
{ src: "/images/slides/slide4.webp", alt: "Slide 4" },
{ src: "/images/slides/slide5.webp", alt: "Slide 5" },
{ src: "/images/slides/slide6.webp", alt: "Slide 6" },
{ src: "/images/slides/slide7.webp", alt: "Slide 7" },
{ src: "/images/slides/slide8.webp", alt: "Slide 8" },
];
---

<Layout
Expand All @@ -23,7 +33,7 @@ import Layout from "@/layouts/layout.astro";
/>
<div class="flex flex-col gap-20 lg:gap-40">
<div>
<Carousel client:visible />
<Carousel client:only images={images} speed={100} gap={0} />
</div>
<div class="container-reader flex flex-col gap-20 lg:gap-40">
<PointerSection
Expand Down

0 comments on commit 32b40c1

Please sign in to comment.