<div class="stage">
    <header class="header">
        <div class="logo">Doyle</div>
        <a href="#" class="nav-btn">
            <svg class="nav-btn__svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56 30">
                <rect class="nav-rect" width="40" height="2" x="8" y="8" fill="#242423" />
                <rect class="nav-rect" width="40" height="2" x="8" y="14" fill="#242423" />
                <rect width="40" height="2" x="8" y="20" fill="#242423" />
            </svg>
        </a>
    </header>

    <section class="intro slide--0" id="slide-0">
        <div class="intro__content">
            <h1 class="intro__title">Bauhaus</h1>
            <p class="intro__txt">The timeless principles of Bauhaus design still hold up, and to this day, the iconic Bauhaus style inspires graphic designers worldwide.</p>
        </div>
        <img class="intro__img intro__img--1" src="https://assets.codepen.io/7773162/Screen+Shot+2022-04-30+at+9.02.33+PM.png" />
        <img class="intro__img intro__img--2" src="https://assets.codepen.io/7773162/Screen+Shot+2022-04-30+at+9.05.23+PM.png" />
    </section>

    <section class="slide slide--1" id="slide-1">
        <div class="col col--1">
            <div class="col__content col__content--1">
                <h2 class="col__content-title"><span class="line__inner">Exhibition</span><br /><span class="line__inner">1923</span></h2>
                <div class="col__content-wrap">
                    <p class="col__content-txt">This Bauhaus exhibition poster exemplifies experimentation with white space and primary colors coming together to create a minimalist yet vibrant aesthetic.</p>
                    <a href="#" class="slide-link">
                        <div class="slide-link__circ"></div>
                        <div class="slide-link__line"></div>
                    </a>
                </div>
            </div>
            <a href="#slide-2" class="slide__scroll-link">
                <div class="slide__scroll-line"></div>
            </a>
        </div>
        <div class="col col--2">
            <div class="col__image-wrap">
                <img class="img img--1" src="https://assets.codepen.io/7773162/Screen+Shot+2022-04-30+at+9.20.12+PM.png" />
            </div>
        </div>
    </section>

    <section class="slide slide--2" id="slide-2">
        <div class="col col--1">
            <div class="col__content col__content--2">
                <h2 class="col__content-title"><span class="line__inner">Beethoven</span><br /><span class="line__inner">1955</span></h2>
                <div class="col__content-wrap">
                    <p class="col__content-txt">The Beethoven poster was designed in 1955 by Josef Muller-Brockmann. He is most known for his clean typography, simple designs and geometric shapes that he used throughout his work. This poster is perhaps one of Muller-Brockmann’s most celebrated designs.</p>
                    <a href="#" class="slide-link">
                        <div class="slide-link__circ"></div>
                        <div class="slide-link__line"></div>
                    </a>
                </div>
            </div>
            <a href="#slide-3" class="slide__scroll-link">
                <div class="slide__scroll-line"></div>
            </a>
        </div>
        <div class="col col--2">
            <div class="col__image-wrap">
                <img class="img img--1" src="https://assets.codepen.io/7773162/Screen+Shot+2022-04-30+at+9.26.53+PM.png" />
            </div>
        </div>
    </section>

    <section class="slide slide--3" id="slide-3">
        <div class="col col--1">
            <div class="col__content col__content--3">
                <h2 class="col__content-title"><span class="line__inner">Microtonal</span><br /><span class="line__inner">1968</span></h2>
                <div class="col__content-wrap">
                    <p class="col__content-txt">Piedra Blanca (aka Alex Steinweiss), artwork for album cover Microtonal Fantasy, The music of John Eaton, 1968. Decca Records.</p>
                    <a href="#" class="slide-link">
                        <div class="slide-link__circ"></div>
                        <div class="slide-link__line"></div>
                    </a>
                </div>
            </div>
            <a href="#slide-4" class="slide__scroll-link">
                <div class="slide__scroll-line"></div>
            </a>
        </div>
        <div class="col col--2">
            <div class="col__image-wrap">
                <img class="img img--1" src="https://assets.codepen.io/7773162/Screen+Shot+2022-04-30+at+9.38.32+PM.png" />
            </div>
        </div>
    </section>

    <section class="slide slide--4" id="slide-4">
        <div class="col col--1">
            <div class="col__content col__content--4">
                <h2 class="col__content-title"><span class="line__inner">Poster</span><br /><span class="line__inner">1923</span></h2>
                <div class="col__content-wrap">
                    <p class="col__content-txt">Less = More</p>
                    <a href="#" class="slide-link">
                        <div class="slide-link__circ"></div>
                        <div class="slide-link__line"></div>
                    </a>
                </div>
            </div>
            <a href="#slide-5" class="slide__scroll-link">
                <div class="slide__scroll-line"></div>
            </a>
        </div>
        <div class="col col--2">
            <div class="col__image-wrap">
                <img class="img img--1" src="https://assets.codepen.io/7773162/Screen+Shot+2022-04-30+at+9.57.27+PM.png" />
            </div>
        </div>
    </section>

    <section class="slide slide--5" id="slide-5">
        <div class="col col--1">
            <div class="col__content col__content--5">
                <h2 class="col__content-title"><span class="line__inner">Exhibition</span><br /><span class="line__inner">1923</span></h2>
                <div class="col__content-wrap">
                    <p class="col__content-txt">Yet another 1923 Exhibition Poster.</p>
                    <a href="#" class="slide-link">
                        <div class="slide-link__circ"></div>
                        <div class="slide-link__line"></div>
                    </a>
                </div>
            </div>
            <a href="#slide-6" class="slide__scroll-link">
                <div class="slide__scroll-line"></div>
            </a>
        </div>
        <div class="col col--2">
            <div class="col__image-wrap">
                <img class="img img--1" src="https://assets.codepen.io/7773162/Screen+Shot+2022-04-30+at+10.04.22+PM.png" />
            </div>
        </div>
    </section>

    <section class="slide slide--6" id="slide-6">
        <div class="col col--1">
            <div class="col__content col__content--6">
                <h2 class="col__content-title"><span class="line__inner">Flyer</span><br /><span class="line__inner">1923</span></h2>
                <div class="col__content-wrap">
                    <p class="col__content-txt">This flyer is yet another Exhibition Poster from 1923. Are you suprised yet? Lol.</p>
                    <a href="#" class="slide-link">
                        <div class="slide-link__circ"></div>
                        <div class="slide-link__line"></div>
                    </a>
                </div>
            </div>
            <a href="#slide-7" class="slide__scroll-link">
                <div class="slide__scroll-line"></div>
            </a>
        </div>
        <div class="col col--2">
            <div class="col__image-wrap">
                <img class="img img--1" src="https://assets.codepen.io/7773162/Screen+Shot+2022-04-30+at+10.06.07+PM.png" />
            </div>
        </div>
    </section>

    <footer class="footer" id="slide-7">
        <a class="footer__link" href="http://tylerjdoyle.myportfolio.com/" target="_blank">Tyler Doyle</a>
        <a class="footer__link-top" href="#slide-0">Top<span class="footer__link-top-line"></span></a>
        <p class="footer__copyright">Thanks for viewing this project. Please Consider Appreciating this project and Following me, this project took a lot of time, effort, and energy.</p>
    </footer>
</div>
:root {
    --dark: #242423;
}

html {
  box-sizing: border-box;
    // scroll-behavior: smooth;
    // scroll-snap-type: y mandatory;
}

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

html, body {
  min-height: 100vh;
}

body {
    background-color: white;
    font-family: 'Noto Sans', sans-serif;
    font-size: 14px;
    color: var(--dark);
    line-height: 1.3;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    // overflow: hidden;
}

.logo,
h1,
h2 {
    margin: 0;
    line-height: 1;
    font-family: 'Cinzel', serif;
    font-weight: 350;
}

p {
    margin: 0;
}

.stage {
  position: relative;
    background: white;
  visibility: hidden;
}

/*  ========================================================================== 
    Nav Header
    ========================================================================== */

.header {
    position: fixed;
    left: 40px;
    top: 24px;
    z-index: 100;
    display: flex;
    
    @media all and (max-width: 768px) {
        display: block;
        left: 24px;
    }
}

.logo {
    font-size: 27px;
    letter-spacing: -1px;
}

.nav-btn,
.nav-btn__svg {
    width: 56px;
    height: 30px;
}

.nav-btn {
    display: block;
    margin: -2px 0 0 56px;
    
    @media all and (max-width: 768px) {
        margin: 18px 0 0 -6px;
    }
}

.nav-btn__svg {
    pointer-events: none;
}

/*  ========================================================================== 
    Intro
    ========================================================================== */

.intro,
.footer {
    height: 100vh;
}

.intro {
    position: relative;
    padding: 5vw;
    background: #C0D7D8;
    overflow: hidden;
}

.intro__content {
    position: absolute;
    right: 8%;
    bottom: 15%;
    z-index: 3;
    
    @media all and (max-width: 768px) {
        right: auto;
    }
}

.intro__title {
    font-size: 20vw;
    overflow: hidden;
    letter-spacing: -2.3vw;
    padding-right: 1.3vw;

    @media all and (max-width: 768px) {
        margin-bottom: 5vh;
    }
}

.intro__img {
    position: absolute;
    width: 35%;
    max-width: 390px;
    height: auto;
    
    @media all and (max-width: 768px) {
        width: 75vw;
    }
}

.intro__img--1 {
    z-index: 2;
    left: 10%;
    bottom: 35%;
    
    @media all and (max-width: 768px) {
        // top: 15vh;
        left: 50%;
        bottom: 50vh;
    }
}

.intro__img--2 {
    z-index: 1;
    left: 25%;
    bottom: 40%;
    
    @media all and (max-width: 768px) {
        // top: 2vh;
        left: 70%;
        bottom: 60vh;
    }
}

.intro__txt {
    max-width: 35vw;
    margin-left: 25vw;
    
    @media all and (max-width: 768px) {
        max-width: 80vw;
        margin-left: 5vw;
    }
}

/*  ========================================================================== 
    Slides
    ========================================================================== */

.slide {
    display: flex;
    align-items: stretch;
    height: 100vh;
    overflow: hidden;
    
    &:nth-of-type(even) {
        background: #C4CDC4;
    }
    
    @media all and (max-width: 768px) {
        display: block;
        position: relative;
    }
}

/*  Columns
    ========================================================================== */

.col {
    flex-basis: 50%;
    
    @media all and (max-width: 768px) {
        display: block;
        width: 100%;
        height: 100vh;
    }
}

.col--1 {
    position: relative;
    z-index: 1;
    
     @media all and (max-width: 768px) {
        position: relative;
        z-index: 1;
    }
}

.col--2 {
    position: relative;
    overflow: hidden;
    
    @media all and (max-width: 768px) {
        position: absolute;
        z-index: 0;
        left: 0;
        top: 0;
    }
}

/*  ========================================================================== 
    Column Content
    ========================================================================== */

.col__content {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    overflow: hidden;
    height: 100%;
    padding: 6vw 6vw 10vw;
    
    @media all and (max-width: 768px) {
        width: 80%;
    }
}

.col__content--1 {
    background: #D8C0C0;
    
    @media all and (max-width: 768px) {
        background: rgba(#D8C0C0, 0.9);
    }
}

.col__content--2 {
    background: #CDD5E0;
    
    @media all and (max-width: 768px) {
        background: rgba(#CDD5E0, 0.9);
    }
}

.col__content--3 {
    background: #F3D3B0;
    
    @media all and (max-width: 768px) {
        background: rgba(#F3D3B0, 0.9);
    }
}

.col__content--4 {
    background: #F8E9E6;
    
    @media all and (max-width: 768px) {
        background: rgba(#F8E9E6, 0.9);
    }
}

.col__content--5 {
    background: #D1E2EC;
    
    @media all and (max-width: 768px) {
        background: rgba(#D1E2EC, 0.9);
    }
}

.col__content--6 {
    background: #D7CEC5;
    
    @media all and (max-width: 768px) {
        background: rgba(#D7CEC5, 0.9);
    }
}

/*  Column Content
    ========================================================================== */

.col__content-title {
    margin: 0 0 2vw;
    font-size: 6vw;
    letter-spacing: -0.7vw;
    
    @media all and (max-width: 768px) {
        margin: 0 0 6vw;
        font-size: 15vw;
    }
}

.col__content-wrap {
    display: flex;
    justify-content: flex-end;
    
    @media all and (max-width: 768px) {
        flex-direction: column;
    }
}

.col__content-txt {
    max-width: 22vw;
    order: 2;
    margin-left: 32px;
    
    @media all and (max-width: 768px) {
        order: 1;
        max-width: 40vw;
        margin: 0 0 10vw 10vw;
    }
}

.slide-link {
    position: relative;
    order: 1;
    display: flex;
    justify-content: flex-end;
    width: 75px;
    height: 53px;
    
    > * {
        pointer-events: none;
    }
    
    @media all and (max-width: 768px) {
        order: 2;
        align-self: flex-end;
    }
}

.slide-link__circ {
    width: 53px;
    height: 53px;
    border-radius: 50%;
    border: 1px solid var(--dark);
}

.slide-link__line {
    position: absolute;
    top: 25px;
    left: 0;
    width: 64px;
    height: 3px;
    background: var(--dark);
}

.line {
    overflow: hidden;
    
    &:nth-of-type(even) {
        margin-top: -1vw;
    }
}

.line__inner {
    display: block;
}

.slide__scroll-link {
    position: absolute;
    right: -113px;
    bottom: 3.5vw;
    display: block;
    width: 140px;
    height: 140px;
    background: var(--dark);
    overflow: hidden;
    
    @media all and (max-width: 768px) {
        display: none;
    }
}

.slide__scroll-line {
    position: absolute;
    left: 26px;
    bottom: 0;
    width: 1px;
    height: 100%;
}

.slide--0 {
    .slide__scroll-line {
        background: #C0D7D8;
    }
}

.slide--1 {
    .slide__scroll-line {
        background: #D8C0C0;
    }
}

.slide--2 {
    .slide__scroll-line {
        background: #CDD5E0;
    }
}

.slide--3 {
    .slide__scroll-line {
        background: #F3D3B0;
    }
}

.slide--4 {
    .slide__scroll-line {
        background: #F8E9E6;
    }
}

.slide--5 {
    .slide__scroll-line {
        background: #D1E2EC;
    }
}

.slide--6 {
    .slide__scroll-line {
        background: #D7CEC5;
    }
}

/*  ========================================================================== 
    Column Image
    ========================================================================== */

.col__image-wrap {
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 100%;
    height: 120vh;
}

.img {
    object-fit: cover;
    width: 100%;
    height: 100%;
}

/*  ========================================================================== 
    Footer
    ========================================================================== */

.footer {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    background: #cecece;
}

.footer__link {
    font-size: 5vw;
    color: var(--dark);
    text-decoration: none;
    font-family: 'Cinzel', serif;
}

.footer__link-top {
    position: absolute;
    left: 50%;
    bottom: 100px;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100px;
    height: 100px;
    background: var(--dark);
    font-size: 18px;
    color: white;
    text-decoration: none;
    font-family: 'Cinzel', serif;
}

.footer__link-top-line {
    position: absolute;
    top: -50px;
    left: 50%;
    width: 1px;
    height: 50px;
    background: var(--dark);
}

.footer__copyright {
    position: absolute;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
}
View Compiled
gsap.registerPlugin(ScrollTrigger);
gsap.registerPlugin(ScrollToPlugin);
gsap.registerPlugin(SplitText);

console.clear();

select = e => document.querySelector(e);
selectAll = e => document.querySelectorAll(e);

const stage = select('.stage');
const slides = selectAll(".slide");
const links = selectAll(".slide__scroll-link");
const titles = selectAll('.col__content-title');
const introTitle = new SplitText('.intro__title', {type: "lines", linesClass: "intro-line"});
const splitTitles = new SplitText(titles, {type: "lines, chars", linesClass: "line", charsClass: "char", position: "relative" });
let slideID = 0;

function initHeader() {
    
    // animate the logo and fake burger button into place
    
    let tl = gsap.timeline({delay: 0.5});
    
    tl.from('.logo', {
        y: -40,
        opacity: 0,
        duration: 2,
        ease: 'power4'
    })
    .from('.nav-btn__svg rect', {
        scale: 0,
        transformOrigin: "center right",
        duration: 0.6,
        ease: 'power4',
        stagger: 0.1
    }, 0.6)
    .to('.nav-rect', {
        scale: 0.8,
        transformOrigin: "center left",
        duration: 0.4,
        ease: 'power2',
        stagger: 0.1
    }, "-=0.6")
    
    // create mouse animations for the faux burger button
    
    let navBtn = select('.nav-btn');
    
    navBtn.addEventListener("mouseover", (e) => {
        gsap.to('.nav-rect', {
            scaleX: 1,
            transformOrigin: "top left",
            duration: 0.4, 
            ease: "power4"
        });
    });
    
    navBtn.addEventListener("mouseout", (e) => {
        gsap.to('.nav-rect', {
            scaleX: 0.8,
            transformOrigin: "top left",
            duration: 0.6, 
            ease: "power4"
        });
    });
}

function initIntro() {
    
    // animate the intro elements into place
    
    let tl = gsap.timeline({delay: 1.2});
    
    tl.from('.intro-line', {
        // x: 100,
        y: 400,
        ease: 'power4',
        duration: 3
    })
    .from('.intro__txt', {
        x: -100,
        opacity: 0,
        ease: 'power4',
        duration: 3
    }, 0.7)
    .from('.intro__img--1', {
        // x: -50,
        y: 50,
        opacity: 0,
        ease: 'power2',
        duration: 10
    }, 1)
    .from('.intro__img--2', {
        // x: 50,
        y: -50,
        opacity: 0,
        ease: 'power2',
        duration: 10
    }, 1);
    
    // set up scrollTrigger animation for the when the intro scrolls out
    
    let stl = gsap.timeline({
        scrollTrigger: {
            trigger: '.intro',
            scrub: 1,
            start: "top bottom", // position of trigger meets the scroller position
            end: "bottom top"
        }
    });
    
    stl.to('.intro__title', {
        x: 400,
        ease: 'power4.in',
        duration: 3,
        
    })
    .to('.intro__txt', {
        y: 100,
        ease: 'power4.in',
        duration: 3,
    }, 0);
}

function initLinks() {
    
    // ScrollToPlugin links
    
    links.forEach((link, index, e) => {     
        
        let linkST = link.querySelector('.slide__scroll-line');
        
        link.addEventListener("click", (e) => {
            e.preventDefault();
            gsap.to(window, {
                duration: 2, 
                scrollTo:{
                    y: "#slide-" + (index + 2)
                },
                ease: "power2.inOut"
            });
            slideID++;
        });
        
        link.addEventListener("mouseover", (e) => {
            gsap.to(linkST, {
                y:40,
                transformOrigin: "bottom center",
                duration: 0.6, 
                ease: "power4"
            });
        });
        
        link.addEventListener("mouseout", (e) => {
            gsap.to(linkST, {
                y: 0,
                transformOrigin: "bottom center",
                duration: 0.6, 
                ease: "power4"
            });
        });
        
    });
    
    // ScrollToPlugin link back to the top
    
    let top = select('.footer__link-top');
    
    top.addEventListener("click", (e) => {
        e.preventDefault();
        scrollTop();
    });
    
    top.addEventListener("mouseover", (e) => {
        gsap.to('.footer__link-top-line', {
            scaleY: 3,
            transformOrigin: "bottom center",
            duration: 0.6, 
            ease: "power4"
        });
    });
    
    top.addEventListener("mouseout", (e) => {
        gsap.to('.footer__link-top-line', {
            scaleY: 1,
            transformOrigin: "bottom center",
            duration: 0.6, 
            ease: "power4"
        });
    });
    
    // Dummy slide links
    
    let slideLinks = selectAll('.slide-link');
    
    slideLinks.forEach((slideLink, index, e) => {
        
        let slideL = slideLink.querySelector('.slide-link__line');
        
        slideLink.addEventListener("mouseover", (e) => {
            gsap.to(slideL, {
                x: 20,
                scaleX: 0.3,
                transformOrigin: "right center",
                duration: 0.8, 
                ease: "power4"
            });
        });
        slideLink.addEventListener("mouseout", (e) => {
            gsap.to(slideL, {
                x: 0,
                scaleX: 1,
                transformOrigin: "right center",
                duration: 0.8, 
                ease: "power4"
            });
        });
    })
}

function initSlides() {
    
    // Animation of each slide scrolling into view
    
    slides.forEach((slide, i) => {   
        
        let tl = gsap.timeline({
            scrollTrigger: {
                trigger: slide,
                start: "40% 50%", // position of trigger meets the scroller position
            }
        });
 
        tl.from(slide.querySelectorAll('.col__content-title'), {
            ease: "power4",
            y: "+=5vh",
            duration: 2.5,
        })
        .from(slide.querySelectorAll('.line__inner'), {
            y: 200,
            duration: 2,
            ease: "power4",
            stagger: 0.1
        }, 0)
        .from(slide.querySelectorAll('.col__content-txt'), {
            x: 100,
            y: 50,
            opacity: 0,
            duration: 2,
            ease: "power4"
        }, 0.4)
        .from(slide.querySelectorAll('.slide-link'), {
            x: -100,
            y: 100,
            opacity: 0,
            duration: 2,
            ease: "power4"
        }, 0.3)
        .from(slide.querySelectorAll('.slide__scroll-link'), {
            y: 200,
            duration: 3,
            ease: "power4"
        }, 0.4)
        .to(slide.querySelectorAll('.slide__scroll-line'), {
            scaleY: 0.6,
            transformOrigin: "bottom left",
            duration: 2.5, 
            ease: "elastic(1,0.5)"
        }, 1.4)
  });
    
    // External footer link scroll animation
    
    gsap.from('.footer__link', {
        scrollTrigger: {
            trigger: '.footer',
            scrub: 2,
            start: "50% 100%", // position of trigger meets the scroller position
            end: "0% 0%",
        },
        y: "20vh",
        ease: 'sine'
    })
}

function initParallax() {
    
    slides.forEach((slide, i) => {
        let imageWrappers = slide.querySelectorAll('.col__image-wrap');
        
        gsap.fromTo(imageWrappers, {
            y: "-30vh"
        },{
            y: "30vh",
            scrollTrigger: {
                trigger: slide,
                scrub: true,
                start: "top bottom", // position of trigger meets the scroller position
                snap: {
                    snapTo: 0.5, // 0.5 'cause the scroll animation range is 200vh for parallax effect
                    duration: 1,
                    ease: 'power4.inOut'
                }
            },
            ease: 'none'
        })
    });
}

function scrollTop() {
    gsap.to(window, {
        duration: 2, 
        scrollTo: {
            y: "#slide-0"
        },
        ease: "power2.inOut"
    });
    gsap.to('.footer__link-top-line', {
        scaleY: 1,
        transformOrigin: "bottom center",
        duration: 0.6, 
        ease: "power4"
    });
}

function initKeys() {
    document.addEventListener('keydown', (e) => {
        e.preventDefault();
        if(event.keyCode == 40) { //down arrow to next slide
            if(slideID <= slides.length) {
                slideID++;
                gsap.to(window, {
                    duration: 2, 
                    scrollTo:{
                        y: "#slide-" + slideID 
                    },
                    ease: "power2.inOut"
                });
            }
        }
        else if(event.keyCode == 38) { // up arrow to top
            slideID = 0;
            scrollTop();
        }
    });
}

function init() {
    gsap.set(stage, { autoAlpha: 1 });
    initHeader();
    initIntro();
  initLinks();
  initSlides();
  initParallax();
    initKeys();
}

window.onload = () => {
  init();
};

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js
  2. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/ScrollToPlugin3.min.js
  3. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/SplitText3.min.js
  4. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/ScrollTrigger.min.js