<main>
  <ul>
    <li style="--x1: 2; --x2: 6; --y1: 1; --y2: 4;">
      <img src="https://picsum.photos/600/600?random=1" alt="">
    </li>
    <li style="--x1: 6; --x2: 8; --y1: 2; --y2: 4;">
      <img src="https://picsum.photos/600/600?random=2" alt="">
    </li>
    <li style="--x1: 1; --x2: 4; --y1: 4; --y2: 7;">
      <img src="https://picsum.photos/600/600?random=3" alt="">
    </li>
    <li style="--x1: 4; --x2: 7; --y1: 4; --y2: 7;">
      <img src="https://picsum.photos/600/600?random=4" alt="">
    </li>
    <li style="--x1: 7; --x2: 9; --y1: 4; --y2: 6;">
      <img src="https://picsum.photos/600/600?random=5" alt="">
    </li>
    <li style="--x1: 2; --x2: 4; --y1: 7; --y2: 9;">
      <img src="https://picsum.photos/600/600?random=7" alt="">
    </li>
    <li style="--x1: 4; --x2: 7; --y1: 7; --y2: 10;">
      <img src="https://picsum.photos/600/600?random=8" alt="">
    </li>
    <li style="--x1: 7; --x2: 10; --y1: 6; --y2: 9;">
      <img src="https://picsum.photos/600/600?random=9" alt="">
    </li>
  </ul>
</main>
@import "https://unpkg.com/open-props/open-props.min.css";
@import "https://unpkg.com/open-props/normalize.min.css";

*,
*:after,
*:before {
  box-sizing: border-box;
}

body {
  display: grid;
  place-items: center;
  min-height: 100vh;
  font-family:  'Google Sans', sans-serif, system-ui;
  width: 100vw;
  overflow-x: hidden;
  height: 300vh;
  background: var(--surface-2);
}

ul {
  --big-tile-size: 50vmin;
  --scale: 0.4;
  --rotation: 270deg;
  --tile-size: calc(var(--big-tile-size) / 3);
  list-style-type: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 1vmin;
  grid-template: repeat(9, var(--tile-size)) / repeat(9, var(--tile-size));
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(var(--scale));
}

img {
  --rotation: -270deg;
  --scale: 1;
  height: 200%;
  min-width: 200%;
  aspect-ratio: 1;
  object-fit: cover;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

li {
  padding: 0;
  position: relative;
  background: hsl(0 0% 75% / 0.2);
  max-inline-size: 100%;
}

li {
  grid-column: var(--x1, auto) / var(--x2, auto);
  grid-row: var(--y1, auto) / var(--y2, auto);
}

li {
  border-radius: var(--radius-3);
  overflow: hidden;
}
import gsap from "https://cdn.skypack.dev/gsap@3.11.0";
import { ScrollTrigger } from "https://cdn.skypack.dev/gsap@3.11.0/ScrollTrigger"

gsap.registerPlugin(ScrollTrigger)

gsap.defaults({
  duration: 2,
  ease: "power1.inOut"
});

gsap
  .timeline({
    scrollTrigger: {
      scrub: 1,
    }
  })
  .to("ul", {
    scale: 1,
    rotate: 270
  })
  .to(
    "img",
    {
      rotate: -270
    },
    0
  );
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.