I’m really struggling with gsap.
Im trying to have room-top__flex content to scroll horizontally when room-top is pinned.
It’s working but my issue is that i would like it to be unpinned when the last gsap-room is fully seen (so we still see some part of the second one) but right now its been unpinned when the last gsap-room is on the left of the screen so there is a blank space on the right.
Is there a way ? i dont mind the last gsap-room expanding to take the full width.
here is the code so far :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GSAP Horizontal Scroll</title>
<style>
* {
box-sizing: border-box;
}
body {
font-family: "FP-ヒラギノ角ゴ ProN W3", sans-serif;
font-style: normal;
font-weight: 300;
width: 100%;
height: 100%;
background: #000;
color: #fff;
font-size: 13px;
letter-spacing: 0.05em;
line-height: 2.5;
word-wrap: break-word;
line-break: strict;
}
#wrapper {
position: relative;
width: 100%;
min-height: 100%;
margin: 0;
overflow: hidden;
}
.main {
display: block;
padding-top: 0;
}
.block {
width: 100%;
height: 100vh;
background: green;
}
.room-tp {
background: pink;
height: 100vh;
position: relative;
overflow: hidden;
width: 100%;
}
.room-tp .top-title {
padding-top: 65px;
font-size: 90px;
text-align: right;
}
.room-tp__flex {
display: flex;
width: max-content;
}
.room-top__img {
width: 80vw;
height: calc(100vh - 160px);
}
.room-top__img img {
object-fit: cover;
width: 100%;
}
.room-tp__container {
display: block;
position: relative;
}
.big-space {
width: 100%;
height: 100vh;
background-color: red;
text-align: center;
font-size: 30px;
}
.blue {
background-color: teal;
}
.gsap-about-flex {
display: flex;
width: 100%;
height: 100vh;
background-image: url("https://picsum.photos/200");
background-position: center;
background-size: cover;
}
.gsap-container {
position: relative;
height: 100vh;
}
.text-container {
position: absolute;
top: 50%;
left: 50%;
text-align: center;
}
.text-container h2, .text-container p {
color: white;
mix-blend-mode: difference;
}
.gsap-about-before {
width: 50%;
height: 100vh;
background-color: white;
}
.gsap-about-after {
width: 50%;
height: 100vh;
background-color: white;
}
</style>
</head>
<body>
<div id="wrapper">
<main class="main">
<div class="block"></div>
<div class="gsap-container">
<div class="gsap-about-flex">
<div class="gsap-about-before"></div>
<div class="gsap-about-after"></div>
</div>
<div class="text-container">
<h2>Hello</h2>
<p>this is some text</p>
</div>
</div>
<section class="room-tp">
<h2 class="top-title top-title--right">ROOM</h2>
<div class="room-tp__wrapper">
<div class="room-tp__flex">
<div class="gsap-room">
<a href="/room/#room401" class="room-tp__container">
<div class="room-top__img">
<img src="https://picsum.photos/id/19/200/300" alt="">
</div>
<div class="room-top__info">
<p class="room-top__list">meeting</p>
<p class="room-top__info-title">401</p>
<a href="/room/#room401" class="room-top__button">VIEW MORE <i class="ico-arrow"></i></a>
</div>
</a>
</div>
<div class="gsap-room">
<a href="/room/#room402" class="room-tp__container">
<div class="room-top__img">
<img src="https://picsum.photos/id/20/200/300" alt="">
</div>
<div class="room-top__info">
<p class="room-top__list">meeting</p>
<p class="room-top__info-title">¥402</p>
<a href="/room/#room402" class="room-top__button">VIEW MORE <i class="ico-arrow"></i></a>
</div>
</a>
</div>
<div class="gsap-room">
<a href="/room/#room501" class="room-tp__container">
<div class="room-top__img">
<img src="https://picsum.photos/id/21/200/300" alt="">
</div>
<div class="room-top__info">
<p class="room-top__list">offline</p>
<p class="room-top__info-title">501</p>
<a href="/room/#room501" class="room-top__button">VIEW MORE <i class="ico-arrow"></i></a>
</div>
</a>
</div>
</div>
</div>
</section>
<div class="block"></div>
</main>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.7.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.7.1/ScrollTrigger.min.js"></script>
<script>
gsap.registerPlugin(ScrollTrigger);
gsap.to(".gsap-about-before", {
scrollTrigger: {
trigger: ".gsap-container",
start: "top top",
end: "+=100%",
scrub: true,
pin: true,
toggleActions: "play none none reverse"
},
x: '-100%',
duration: 3
});
gsap.to(".gsap-about-after", {
scrollTrigger: {
trigger: ".gsap-container",
start: "top top",
end: "+=100%",
scrub: true,
pin: false,
toggleActions: "play none none reverse"
},
x: '100%',
duration: 3
});
let sections = gsap.utils.toArray(".gsap-room");
// Calculate the width to stop scrolling when half of the second gsap-room is visible
const stopWidth = document.querySelector(".gsap-room").offsetWidth * 1.5;
gsap.to(sections, {
xPercent: -100 * (sections.length - 1),
ease: "none",
scrollTrigger: {
trigger: ".room-tp",
pin: true,
scrub: true,
snap: 1 / (sections.length - 1),
end: () => "+=" + (stopWidth - window.innerWidth),
markers: true,
}
});
</script>
</body>
</html>
You can try something like this
gsap.to(sections, {
xPercent: -90 * (sections.length - 1),
ease: "none",
scrollTrigger: {
trigger: ".room-tp",
pin: true,
scrub: true,
snap: 1 / (sections.length - 1),
end: () => "+=" + (stopWidth - window.innerWidth),
markers: true,
}
});
.room-top__img {
width: 100vw;
height: calc(100vh - 160px);
}
.room-tp__flex:first-child{
transform: translateX( -20vw);
}
.gsap-room:first-child .room-top__img{
width: 100vw;
padding-left: 20vw;
box-sizing: border-box;
}
Cis-wq is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.