A Pen by Hasan ALDOY on CodePen.
Last active
August 14, 2025 06:24
-
-
Save aldoyh/74d26ec7663a9ec0ef44d84716cc5480 to your computer and use it in GitHub Desktop.
Swiped Scrolled Website Design v2.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Ensure this file is loaded after the libraries in your HTML (gsap, observer, split-type) | |
| document.addEventListener("DOMContentLoaded", () => { | |
| gsap.registerPlugin(Observer); | |
| const sections = gsap.utils.toArray(".slide"); | |
| const headings = gsap.utils.toArray(".slide__heading"); | |
| const countEl = document.querySelector(".count"); | |
| let animating = false; | |
| let currentIndex = 0; | |
| const wrap = gsap.utils.wrap(0, sections.length); | |
| // Split headings into characters for animation | |
| const splitHeadings = headings.map((heading) => { | |
| return new SplitType(heading, { | |
| types: "chars", | |
| charClass: "char" | |
| }); | |
| }); | |
| // Set initial states for all elements | |
| gsap.set(".slide:not(:first-child)", { | |
| visibility: "hidden" | |
| }); | |
| gsap.set(".char", { | |
| yPercent: 120, | |
| rotationZ: 15 | |
| }); | |
| // Set initial state for the first slide's characters | |
| if (splitHeadings.length > 0) { | |
| gsap.set(splitHeadings[0].chars, { yPercent: 0, rotationZ: 0 }); | |
| } | |
| function animateCounter(newIndex) { | |
| const tl = gsap.timeline(); | |
| tl | |
| .to(countEl, { y: -20, opacity: 0, duration: 0.3, ease: "power2.in" }) | |
| .set(countEl, { innerText: newIndex + 1 }) | |
| .fromTo( | |
| countEl, | |
| { y: 20, opacity: 0 }, | |
| { y: 0, opacity: 1, duration: 0.3, ease: "power2.out" } | |
| ); | |
| } | |
| function gotoSection(index, direction) { | |
| if (animating) return; | |
| animating = true; | |
| index = wrap(index); | |
| const currentSection = sections[currentIndex]; | |
| const nextSection = sections[index]; | |
| const currentChars = splitHeadings[currentIndex].chars; | |
| const nextChars = splitHeadings[index].chars; | |
| const currentImage = currentSection.querySelector(".slide__img"); | |
| const nextImage = nextSection.querySelector(".slide__img"); | |
| const nextColor = nextSection.dataset.color; | |
| const tl = gsap.timeline({ | |
| defaults: { duration: 1.2, ease: "power4.inOut" }, | |
| onStart: () => { | |
| gsap.set(nextSection, { visibility: "visible" }); | |
| }, | |
| onComplete: () => { | |
| gsap.set(currentSection, { visibility: "hidden" }); | |
| currentIndex = index; | |
| animating = false; | |
| } | |
| }); | |
| tl | |
| .to("body", { backgroundColor: nextColor }, 0) | |
| // Animate outgoing elements | |
| .to( | |
| currentChars, | |
| { yPercent: -120, rotationZ: -15, stagger: 0.03, duration: 1 }, | |
| 0 | |
| ) | |
| .to( | |
| currentImage, | |
| { | |
| xPercent: direction * 50, | |
| scale: 1.2, | |
| skewX: direction * 15, | |
| filter: "blur(10px)", | |
| duration: 1.5 | |
| }, | |
| 0 | |
| ) | |
| .to( | |
| currentSection.querySelector(".slide__inner"), | |
| { | |
| clipPath: | |
| direction === 1 | |
| ? "polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%)" | |
| : "polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%)", | |
| duration: 1.5 | |
| }, | |
| 0 | |
| ) | |
| // Animate incoming elements | |
| .fromTo( | |
| nextSection.querySelector(".slide__inner"), | |
| { | |
| clipPath: | |
| direction === 1 | |
| ? "polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%)" | |
| : "polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%)" | |
| }, | |
| { | |
| clipPath: "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)", | |
| duration: 1.5 | |
| }, | |
| 0 | |
| ) | |
| .from( | |
| nextImage, | |
| { | |
| xPercent: -direction * 50, | |
| scale: 1.2, | |
| skewX: -direction * 15, | |
| filter: "blur(10px)", | |
| duration: 1.5 | |
| }, | |
| 0 | |
| ) | |
| .to( | |
| nextChars, | |
| { yPercent: 0, rotationZ: 0, stagger: 0.03, duration: 1 }, | |
| 0.2 | |
| ); | |
| animateCounter(index); | |
| } | |
| Observer.create({ | |
| type: "wheel,touch,pointer", | |
| wheelSpeed: -1, // Invert wheel direction for natural scrolling | |
| onUp: () => gotoSection(currentIndex + 1, 1), | |
| onDown: () => gotoSection(currentIndex - 1, -1), | |
| tolerance: 10, | |
| preventDefault: true | |
| }); | |
| document.addEventListener("keydown", (e) => { | |
| if (e.key === "ArrowUp" || e.key === "ArrowLeft") { | |
| gotoSection(currentIndex - 1, -1); | |
| } | |
| if (e.key === "ArrowDown" || e.key === "ArrowRight" || e.key === " ") { | |
| gotoSection(currentIndex + 1, 1); | |
| } | |
| }); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script src="https://assets.codepen.io/16327/gsap-latest-beta.min.js"></script> | |
| <script src="https://assets.codepen.io/16327/ScrollTrigger.min.js"></script> | |
| <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/SplitText3.min.js"></script> | |
| <script src="https://unpkg.com/gsap@3/dist/TextPlugin.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @font-face { | |
| font-family: "Bandeins Sans & Strange Variable"; | |
| src: url("https://res.cloudinary.com/dldmpwpcp/raw/upload/v1566406079/BandeinsStrangeVariable_esetvq.ttf"); | |
| } | |
| @import url("https://fonts.googleapis.com/css2?family=Sora:wght@400;700&display=swap"); | |
| :root { | |
| --bg-color: #4361ee; | |
| --text-color: #f2f1fc; | |
| } | |
| * { | |
| box-sizing: border-box; | |
| user-select: none; | |
| } | |
| body { | |
| color: var(--text-color); | |
| background-color: var(--bg-color); | |
| font-family: "Sora", sans-serif; | |
| height: 100vh; | |
| width: 100vw; | |
| overflow: hidden; | |
| margin: 0; | |
| -webkit-font-smoothing: antialiased; | |
| } | |
| body::before { | |
| content: ""; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100vw; | |
| height: 100vh; | |
| background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAACnRSTlMAzDPKzsozvHBeC8/1amIAAAAZSURBVDjLY2AYwYAQhTBwsgAUVxgxMHYwAgAAVQYAgB9gKRAAAAAASUVORK5CYII="); | |
| opacity: 0.04; | |
| z-index: 1000; | |
| pointer-events: none; | |
| } | |
| figure { | |
| margin: 0; | |
| overflow: hidden; | |
| } | |
| footer { | |
| position: fixed; | |
| z-index: 999; | |
| bottom: 0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 0 2rem; | |
| width: 100%; | |
| height: 7em; | |
| font-size: clamp(1rem, 2vw, 1.2rem); | |
| } | |
| a { | |
| color: var(--text-color); | |
| text-decoration: none; | |
| font-weight: 700; | |
| } | |
| .ui { | |
| position: fixed; | |
| z-index: 10; | |
| top: 0; | |
| right: 0; | |
| padding: 2rem; | |
| text-align: right; | |
| } | |
| .ui__counter { | |
| font-size: clamp(3rem, 4vw, 5rem); | |
| border-bottom: 5px solid var(--text-color); | |
| font-weight: 700; | |
| line-height: 1; | |
| overflow: hidden; | |
| } | |
| .ui__counter .count { | |
| display: inline-block; | |
| } | |
| .slide { | |
| height: 100vh; | |
| width: 100vw; | |
| top: 0; | |
| left: 0; | |
| position: fixed; | |
| visibility: hidden; | |
| } | |
| .slide__outer, | |
| .slide__inner { | |
| width: 100%; | |
| height: 100%; | |
| overflow: hidden; | |
| } | |
| .slide__inner { | |
| clip-path: polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%); | |
| } | |
| .slide__content { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| position: absolute; | |
| height: 100%; | |
| width: 100%; | |
| top: 0; | |
| background-color: var(--slide-bg); | |
| } | |
| .slide__container { | |
| position: relative; | |
| width: 100%; | |
| max-width: 1400px; | |
| height: 100%; | |
| margin: 0 auto; | |
| display: grid; | |
| grid-template-columns: repeat(12, 1fr); | |
| grid-template-rows: repeat(12, 1fr); | |
| padding: 2rem; | |
| } | |
| .slide__heading { | |
| grid-area: 4 / 2 / 6 / 12; | |
| font-family: "Bandeins Sans & Strange Variable"; | |
| font-size: clamp(5rem, 15vw, 15rem); | |
| font-weight: 900; | |
| font-variation-settings: "wdth" 200; | |
| margin: 0; | |
| padding: 0; | |
| color: var(--text-color); | |
| z-index: 3; | |
| line-height: 0.9; | |
| mix-blend-mode: difference; | |
| } | |
| .slide__heading .char { | |
| display: inline-block; | |
| will-change: transform, opacity; | |
| } | |
| .slide__img-cont { | |
| grid-area: 5 / 6 / 11 / 11; | |
| overflow: hidden; | |
| z-index: 2; | |
| will-change: transform; | |
| } | |
| .slide__img-cont img { | |
| width: 100%; | |
| height: 100%; | |
| object-fit: cover; | |
| will-change: transform, filter; | |
| } | |
| .slide:first-child { | |
| visibility: visible; | |
| } | |
| .slide:first-child .slide__inner { | |
| clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); | |
| } | |
| @media screen and (max-width: 900px) { | |
| .slide__heading { | |
| grid-area: 3 / 2 / 5 / 12; | |
| } | |
| .slide__img-cont { | |
| grid-area: 4 / 2 / 10 / 12; | |
| } | |
| footer, | |
| .ui { | |
| padding: 1.5rem; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>GSAP Kinetic Morph Scroll</title> | |
| <link rel="stylesheet" href="style.css"> | |
| </head> | |
| <body> | |
| <div class="ui"> | |
| <div class="ui__counter">0<span class="count">1</span></div> | |
| </div> | |
| <section class="slide" data-color="#6d597a"> | |
| <div class="slide__outer"> | |
| <div class="slide__inner"> | |
| <div class="slide__content"> | |
| <div class="slide__container"> | |
| <h2 class="slide__heading">Kinetic</h2> | |
| <figure class="slide__img-cont"> | |
| <img class="slide__img" src='https://images.unsplash.com/photo-1567016376408-0226e4d0c1ea?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800' alt='Minimalist chair'> | |
| </figure> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="slide" data-color="#355070"> | |
| <div class="slide__outer"> | |
| <div class="slide__inner"> | |
| <div class="slide__content"> | |
| <div class="slide__container"> | |
| <h2 class="slide__heading">Morph</h2> | |
| <figure class="slide__img-cont"> | |
| <img class="slide__img" src='https://images.unsplash.com/photo-1558603668-6570496b66f8?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&w=800' alt='Interior with wooden chair'> | |
| </figure> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="slide" data-color="#b56576"> | |
| <div class="slide__outer"> | |
| <div class="slide__inner"> | |
| <div class="slide__content"> | |
| <div class="slide__container"> | |
| <h2 class="slide__heading">Fluid</h2> | |
| <figure class="slide__img-cont"> | |
| <img class="slide__img" src='https://images.unsplash.com/photo-1537165924986-cc3568f5d454?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&w=800' alt='Pink velvet armchair'> | |
| </figure> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="slide" data-color="#9a8c98"> | |
| <div class="slide__outer"> | |
| <div class="slide__inner"> | |
| <div class="slide__content"> | |
| <div class="slide__container"> | |
| <h2 class="slide__heading">Scroll</h2> | |
| <figure class="slide__img-cont"> | |
| <img class="slide__img" src='https://images.unsplash.com/photo-1589271243958-d61e12b61b97?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800' alt='Modern white chair'> | |
| </figure> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <footer> | |
| <a href="https://gsap.com/">GSAP</a> | |
| <p>Enhanced Demo</p> | |
| </footer> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/Observer.min.js"></script> | |
| <script src="https://unpkg.com/split-type"></script> | |
| <script src="script.js"></script> | |
| </body> | |
| </html> |
A Pen by Hasan ALDOY on CodePen.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
