Gallery animation

Animation with GSAP and ScrollTrigger.

var itemsImg = document.querySelectorAll(".item img") itemsImg.forEach(function(item, i) { item.src = "https://source.unsplash.com/random/?iceland&" + i }) var TL = gsap.timeline({scrollTrigger: { trigger: "main", pin: ".items", pinSpacing: false, scrub: 2, start: () => window.innerHeight + " bottom", end: "bottom bottom", invalidateOnRefresh: true }}) TL.to(".items__inner", {rotate: 0}, 0) TL.fromTo(".items .items__col:nth-child(2n + 0)", {y: "-0vh"}, {y: "50vh"}, 0) TL.fromTo(".items .items__col:nth-child(2n + 1)", {y: "50vh"}, {y: "0vh"}, 0) TL.to(".item", {width: "50vw"}, 0) TL.fromTo(".item img", {scale: 2}, {scale: 1}, 0) var contentTL = gsap.timeline({scrollTrigger: { trigger: "main", scrub: 2, start: () => window.innerHeight * 1 + " bottom", end: "bottom bottom", invalidateOnRefresh: true }}) contentTL.fromTo(".content", 1, {borderRadius: "100%", scale: 0}, {borderRadius: "0%", scale: 1}) contentTL.fromTo(".content h1", 1, {scale: 0}, {scale: 1}) contentTL.fromTo(".content p", 1, {scale: 0}, {scale: 1})
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;900&display=swap'); * { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; scroll-behavior: smooth; } :root { --font1: "Poppins"; } body { margin: 0; font-family: var(--font1); background-color: #000; color: #fff; overflow-x: hidden; } .flex, .flex__col { display: flex; justify-content: center; align-items: center; } .flex__col { flex-direction: column; } ul { margin: 0; padding: 0; list-style: none; } main.flex { width: 100%; height: 200vh; align-items: flex-start; } .items { position: relative; width: 100vw; height: 100vh; overflow: hidden; } .items__inner { position: absolute; top: 50%; left: 50%; width: 150vw; height: 150vw; gap: 2vw; transform: translate(-50%, -50%) rotate(45deg); will-change: transform; } .items__col { position: relative; gap: 2vw; will-change: transform; } .item { position: relative; width: 25vw; height: auto; aspect-ratio: 1/1; overflow: hidden; will-change: width; } .item img { position: absolute; top: 50%; left: 50%; width: 100%; height: 100%; object-fit: cover; transform: translate(-50%, -50%); will-change: transform; } .content { position: absolute; top: 50%; left: 50%; width: 60%; height: 60%; padding: 20%; align-items: flex-start; background-color: rgba(0,0,0,0.3); backdrop-filter: blur(10px); border-radius: 100%; transform: translate(-50%, -50%) scale(0); will-change: border-radius transform; } h1 { font-size: 4vw; font-weight: 700; line-height: 4vw; margin: 0; transform-origin: top left; transform: scale(0); will-change: transform; } p { font-size: 1.2vw; font-weight: 600; transform-origin: top left; transform: scale(0); will-change: transform; } .noise { position: fixed; z-index: 1001; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; background-image: url("https://www.paulrogerdev.fr/codepen/noise.png"); }