JSFiddle - React, Tailwind, and code Playground
by davidxmartins
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"></script>
<div class="container">
<section class="w-1">
<h1>Text</h1>
</section>
<section class="w-2 pink">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-2 grey">
<h1>Text</h1>
</section>
<section class="w-1 violet">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-2 pink">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-2 grey">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-1 violet">
<h1>Text</h1>
</section>
<section class="w-2 pink">
<h1>Text</h1>
</section>
<section class="w-2 grey">
<h1>Text</h1>
</section>
<section class="w-1 violet">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-2 pink">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-2 grey">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-1 violet">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-2 pink">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
</div>
</section>
<section class="w-1">
<div>
<h1>Heading</h1>
<p>Paragraph after heading</p>
...
CSS
body {
margin: 0;
padding: 0;
}
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-wrap: nowrap;
background-color: red;
overflow-x: scroll;
overflow-y: hidden;
position: absolute;
scrollbar-width: none;
-ms-overflow-style: none;
}
::-webkit-scrollbar {
display: none;
}
h1 {
color: #fff;
text-align: center;
text-transform: uppercase;
}
p {
color: #fff;
text-align: center;
}
section {
display: flex;
flex-wrap: wrap;
align-items: center;
aling-content: center;
justify-content: center;
}
.w-1 {
height: 100vh;
flex: 0 0 100vw;
background-color: blue;
}
.w-2 {
height: 100vh;
flex: 0 0 100vw;
}
.violet {
background-color: violet;
}
.pink {
background-color: pink;
}
.grey {
background-color: grey;
}
JavaScript
gsap.registerPlugin(ScrollTrigger);
let sections = gsap.utils.toArray("section");
let container = document.querySelector(".container");
let elements = gsap.utils.toArray(document.querySelectorAll("section > *"));
let timeline = gsap.timeline();
timeline.to(sections, {
x: () =>
-(container.scrollWidth - document.documentElement.clientWidth) + "px",
ease: "none",
scrollTrigger: {
pin: true,
scrub: 1,
overwrite: "auto",
trigger: container,
end: () => container.scrollWidth - document.documentElement.clientWidth
}
});
let scrollTriggerTimeline = gsap.timeline();
elements.forEach((element) => {
scrollTriggerTimeline.from(element, {
yPercent: 300,
opacity: 0,
overwrite: "auto",
scrollTrigger: {
scrub: 1,
start: () => element.parentNode.offsetLeft - window.innerWidth,
end: () =>
element.parentNode.offsetLeft -
window.innerWidth +
element.parentNode.getBoundingClientRect().width
}
});
});
elements.forEach((element) => {
scrollTriggerTimeline.to(element, {
yPercent: 300,
opacity: 0,
overwrite: "auto",
scrollTrigger: {
scrub: 1,
immediateRender: false,
start: () =>
element.parentNode.offsetLeft -
element.parentNode.getBoundingClientRect().width / 2,
end: () =>
element.parentNode.offsetLeft +
element.parentNode.getBoundingClientRect().width
}
});
});