0

I have a carousel of images, which I have tilted diagonally, and now I want to scroll through the images. The only problem is that if I add more images to the carousel track than the four I have, the images get clipped by the container because of the large width of the carousel track. How can I change my CSS or JavaScript to accommodate N images and never get clipped? Below is a minimal reproducible example:

window.addEventListener('load', () => {
  if (typeof gsap === 'undefined') return;

  gsap.registerPlugin(ScrollTrigger);

  const diagonalTrack = document.querySelector('.diagonal-carousel .carousel-track');
  if (!diagonalTrack) return;

  const extraOffset = 1000; // tweak as needed

  // Total distance the track needs to move horizontally
  const totalDiagonalScroll = diagonalTrack.scrollWidth - window.innerWidth;

  gsap.to(diagonalTrack, {
    x: () => -totalDiagonalScroll + window.innerWidth * 0.05 - extraOffset,
    ease: "none",
    scrollTrigger: {
      trigger: ".diagonal-carousel",
      start: "top top",
      end: () => `+=${totalDiagonalScroll + extraOffset}`,
      scrub: 1,
      pin: true,
      anticipatePin: 1,
      invalidateOnRefresh: true,
      markers: true // turn on markers for debugging
    }
  });
});
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  min-height: 200vh;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: #050711;
  color: #f5f5f5;
}

.spacer {
  height: 80vh;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  justify-content: center;
}

/* Basic button for card */
.btn.sm {
  padding: 6px 12px;
  font-size: 0.9rem;
  border-radius: 8px;
  border: none;
  cursor: pointer;
}

/* === Diagonal Carousel Effect (extracted from your file) === */

.diagonal-carousel {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 120vh;
}

/* Center inside the container */
.diagonal-carousel .carousel-inner {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  transform-style: preserve-3d;
  perspective: 700px;
}

/* Apply the tilt and manage width */
.diagonal-carousel .carousel-track {
  display: flex;
  gap: 60px;
  transform-style: preserve-3d;
  transform: rotate3d(2, 0, 1, 20deg) scale(0.8); /* Scale down + diagonal tilt */
  width: max-content;
  padding: 0 20vw;
  transform-origin: bottom right;
}

/* Each card */
.diagonal-carousel .case-card {
  position: relative;
  flex: 0 0 80vw;
  height: 70vh;
  border-radius: 24px;
  overflow: hidden;
  background: #181b25;
  box-shadow: 0 10px 40px rgba(0,0,0,0.5);
  transform-style: preserve-3d;
}

/* Image + hover zoom */
.case-card .card-image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  transition: transform 0.5s ease;
}
.case-card:hover .card-image img {
  transform: scale(1.05);
}

/* Text overlay */
.case-card .card-text {
  position: relative;
  z-index: 1;
  padding: 32px;
  max-width: 400px;
  color: #fff;
  backdrop-filter: blur(8px);
  background: rgba(0, 0, 0, 0.45);
  border-radius: 16px;
  margin: 0 0 32px 32px;
}

.case-card h3 { margin: 0 0 4px; font-size: 1.4rem; }
.case-card h4 { margin: 0 0 12px; font-weight: 600; opacity: 0.85; }
.case-card p  { margin: 0 0 16px; line-height: 1.4; color: #e5e5e5; }

@media (max-width: 720px) {
  .diagonal-carousel .case-card { flex: 0 0 90vw; height: 60vh; }
  .case-card .card-text { padding: 20px; margin: 0 0 20px 20px; }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Minimal Diagonal Scroll Demo</title>
  <link rel="stylesheet" href="styles.css" />

  <!-- GSAP + ScrollTrigger from CDN -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js" defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js" defer></script>
  <script src="main.js" defer></script>
</head>
<body>
  <main>
    <section class="spacer">
      <h1>Scroll down to see diagonal carousel</h1>
      <p>Minimal demo of the diagonal scroll effect.</p>
    </section>

    <!-- Diagonal Carousel -->
    <section class="diagonal-carousel">
      <div class="carousel-inner">
        <div class="carousel-track">
          <article class="case-card">
            <div class="card-image">
              <img src="https://images.pexels.com/photos/374870/pexels-photo-374870.jpeg" alt="Card 1" />
            </div>
            <div class="card-text">
              <h3>Diagonal Card 1</h3>
              <h4>NUTTER BUTTER, YOU GOOD?</h4>
              <p>This 56-year-old cookie’s rabbit hole of absurdist escapism consumed the internet.</p>
              <button class="btn sm">View case</button>
            </div>
          </article>

          <article class="case-card">
            <div class="card-image">
              <img src="https://images.pexels.com/photos/196652/pexels-photo-196652.jpeg" alt="Card 2" />
            </div>
            <div class="card-text">
              <h3>Diagonal Card 2</h3>
              <h4>CRUNCH TIME CAMPAIGN</h4>
              <p>A nostalgic voyage through cereal seas – reviving childhood joy for adults.</p>
              <button class="btn sm">View case</button>
            </div>
          </article>

          <article class="case-card">
            <div class="card-image">
              <img src="https://images.pexels.com/photos/66997/pexels-photo-66997.jpeg" alt="Card 3" />
            </div>
            <div class="card-text">
              <h3>Diagonal Card 3</h3>
              <h4>LAUNCH LAB</h4>
              <p>Experiments in motion, copy, and creative strategy for bold brands.</p>
              <button class="btn sm">View case</button>
            </div>
          </article>

          <article class="case-card">
            <div class="card-image">
              <img src="https://images.pexels.com/photos/325185/pexels-photo-325185.jpeg" alt="Card 4" />
            </div>
            <div class="card-text">
              <h3>Diagonal Card 4</h3>
              <h4>NIGHT DRIVE</h4>
              <p>Moody, cinematic explorations of color, light, and narrative.</p>
              <button class="btn sm">View case</button>
            </div>
          </article>
        </div>
      </div>
    </section>

    <section class="spacer">
      <p>End of demo.</p>
    </section>
  </main>
</body>
</html>

New contributor
Mohammad Tahsiri is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
4
  • google.com/… Commented Nov 18 at 8:03
  • You code snippet works, but, as you have probably noted as well, due to the tilt of the carousel, not all images are visible. I agree that the shape of the viewport here is somewhat unusual, but a phone in landscape mode has a reasonably similar viewport. This problem will only get worse when more images are allowed in the carousel and are shown even lower than they are now. Did you think of this? Commented Nov 18 at 10:45
  • yes, this is exactly the problem that I have outlined in my question. I am looking for a solution on how to fix it Commented Nov 18 at 10:55
  • Sorry, I did not understand that that was your problem, from your question. Can you scroll the carousel container upwards slowly while progressing through the carousel? I strongly advice you to add the GSAP tag to your question, because this question can only be answered by someone familiar with it. By adding the correct tags you attract the right audience for your question. Commented Nov 18 at 11:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.