I want to create a website with the scrolling effect like the following: Scrolling Effect
The height of the middle section is dynamic, and may change while first and last section have full screen heights. Can you suggest any library or way to create such a scrolling effect ?
CodePudding user response:
Updated Answer (what OP wants):
Ok so this question is poorly stated but after understanding what we want to achieve, possibly the only way to do that with a dynamic content is to use grid
block rows. See the below sample (I will also keep my initial answer since I believe is a far "cleaner" way):
gsap.registerPlugin(ScrollTrigger);
const allPanels = gsap.utils.toArray(".panel");
const triggerPanels = gsap.utils.toArray(".panel:not(.last)");
triggerPanels.forEach(function (panel, i) {
gsap.fromTo( allPanels,
{ xPercent: -(100 * i) },
{
xPercent: -(100 * (i 1)),
immediateRender: false,
ease: "none",
scrollTrigger: {
trigger: panel,
id: "panel-" i,
start: () => "bottom bottom",
end: () => " =" document.querySelector(".panel").offsetWidth,
pin: ".container",
pinnedContainer: ".container",
scrub: 0.2, // Change this for a "smoother transition" effect
}
}
);
});
ScrollTrigger.addEventListener("refresh", clear);
function clear() {
if (document.documentElement.scrollTop < ScrollTrigger.getById("panel-0").start){
gsap.set(allPanels, { clearProps: "xPercent" });
}
}
html, body {margin: 0;padding: 0;overflow-x: hidden;font-size: 20px;font-family: sans-serif;color: white;}
.container {display: grid;grid-template-columns: 1fr 1fr 1fr;grid-template-rows: 1fr 1px 1px 1px;}
/* Width -4rem due to padding */
.panel {position: relative;width: calc(100vw - 4rem);padding: 2rem;}
.p1 {height: calc(100vh - 4rem);background: firebrick;grid-column: 1 / 2;grid-row: 1 / 2;}
.p2 {background: teal;grid-column: 2 / 3;grid-row: 1 / 3;}
.p3 {background: orange;grid-column: 3 / 4;grid-row: 2 / 4;margin-top: -100vh;}
<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script>
<script src="https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js"></script>
<div >
<div >
<div >
<h2>100 VH</h2>
</div>
<div >
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sollicitudin ante vitae tempor pulvinar. Nunc placerat volutpat augue. Maecenas cursus velit vitae velit aliquet faucibus. Mauris eget libero est. Nullam scelerisque nisl at tristique
lobortis. Nullam nunc enim, posuere a auctor et, scelerisque nec diam. Maecenas sed nunc ante. Vestibulum iaculis molestie placerat. Maecenas iaculis, lectus vitae congue iaculis, nunc arcu elementum lorem, vitae mattis diam neque eget justo.
Nulla facilisi. Phasellus at dignissim elit. Nam pretium purus tortor, sit amet dapibus erat mattis sit amet. Curabitur scelerisque commodo dolor iaculis sollicitudin. Aliquam felis lacus, pellentesque nec rhoncus mollis, gravida quis odio. Duis
sed dapibus augue, eleifend mattis ligula. Aliquam interdum maximus nisl tempus viverra.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sollicitudin ante vitae tempor pulvinar. Nunc placerat volutpat augue. Maecenas cursus velit vitae velit aliquet faucibus. Mauris eget libero est. Nullam scelerisque nisl at tristique
lobortis. Nullam nunc enim, posuere a auctor et, scelerisque nec diam. Maecenas sed nunc ante. Vestibulum iaculis molestie placerat. Maecenas iaculis, lectus vitae congue iaculis, nunc arcu elementum lorem, vitae mattis diam neque eget justo.
Nulla facilisi. Phasellus at dignissim elit. Nam pretium purus tortor, sit amet dapibus erat mattis sit amet. Curabitur scelerisque commodo dolor iaculis sollicitudin. Aliquam felis lacus, pellentesque nec rhoncus mollis, gravida quis odio. Duis
sed dapibus augue, eleifend mattis ligula. Aliquam interdum maximus nisl tempus viverra.</p>
</div>
<div >
<h2>100 VH AGAIN</h2>
</div>
</div>
</div>
Initial Answer:
Since OP asks about third-party libraries, you can use GSAP Scroll Trigger for free.
There you go, please check the comments in the snippet to understand how this works.
gsap.registerPlugin(ScrollTrigger);
const horizontally = gsap.utils.toArray(".horizontally");
horizontally.forEach(element => {
gsap.to(element, {
xPercent: -50, // To make this responsive if you add 200vw to horizontal divs
// then you need to make this scroll 50% right, because your screen
// already shows the 100vw.
ease: "none",
scrollTrigger: {
trigger: element,
pin: true,
scrub: 1,
end: () => " =" document.querySelector(".horizontally").offsetWidth
}
});
});
html, body {padding: 0;margin: 0;overflow-x: hidden;}
.horizontally {
width: 200vw; /* Set this according to your JS settings */
height: 100vh;
display: grid;
justify-content: center;
align-items: center;
align-content: center;
color: #fff;
background: linear-gradient(45deg, #000, #222);
}
.vertically {
padding: 1rem;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
color: #fff;
background: linear-gradient(45deg, #222, #444);
}
<script src="https://assets.codepen.io/16327/ScrollTrigger.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js"></script>
<div >
<h2>Scroll Horizontally</h2>
<p>Really long text that will go on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on</p>
</div>
<div >
<h2>Scroll Vertically</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sollicitudin ante vitae tempor pulvinar. Nunc placerat volutpat augue. Maecenas cursus velit vitae velit aliquet faucibus. Mauris eget libero est. Nullam scelerisque nisl at tristique lobortis. Nullam nunc enim, posuere a auctor et, scelerisque nec diam. Maecenas sed nunc ante. Vestibulum iaculis molestie placerat. Maecenas iaculis, lectus vitae congue iaculis, nunc arcu elementum lorem, vitae mattis diam neque eget justo. Nulla facilisi.</p>
</div>
<div >
<h2>Scroll Horizontally</h2>
<p>Really long text that will go on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on and on</p>
</div>