<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;
font-smoothing: antialiased;
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();
};
This Pen doesn't use any external CSS resources.