<div class="main-container">
<div class="container">
<div class="intro">
Intro Section
</div>
<div class="slider-container">
<ul class="slider">
<li class="slide">
<img class="home-slider__image" src="https://placehold.co/500x650" />
</li>
<li class="slide">
<img class="home-slider__image" src="https://placehold.co/500x650" />
</li>
<li class="slide">
<img class="home-slider__image" src="https://placehold.co/500x650" />
</li>
</ul>
</div>
<div class="drag-proxy"></div>
</div>
</div>
html,
body {
overflow-x: hidden;
margin: 0;
scroll-behavior: auto !important;
}
body {
postiton: relative;
}
.intro {
height: 100vh;
background: slateblue;
display: flex;
align-items: center;
justify-content: center;
font-size: 5vw;
}
img {
max-width: 100%;
height: auto;
}
.slider-container {
display: flex;
align-items: center;
height: 100vh;
background-color: #000;
.slider {
list-style: none;
margin: 0;
padding: 0;
position: relative;
display: inline-flex;
align-items: center;
.slide {
border: 1px solid #fff;
width: 25vw;
height: 33.33333vw;
margin-left: calc(37.5vw - 7.2rem);
text-align: center;
color: #fff;
&:first-child {
margin-left: 37.5vw;
}
&:last-child {
margin-right: 37.5vw;
}
}
}
}
.buttons {
position: absolute;
top: 20px;
left: 20px;
a {
padding: 20px;
font-size: 2vw
}
}
.active {
border: 10px solid red;
}
a {
text-decoration: none;
color: #fff;
}
.drag-proxy {
visibility: hidden;
position: absolute;
}
.headings {
position: absolute;
bottom: 30%;
left: 10%;
width: 400px;
list-style: none;
h1 {
position: absolute;
top: 0;
color: yellow;
}
}
.headingPos {
display: none;
position: absolute;
bottom: 50px;
left: 200px;
h1 {
color: grey
}
}
View Compiled
gsap.registerPlugin(ScrollTrigger, Draggable);
let smoother = ScrollSmoother.create({
wrapper: ".main-container",
content: ".container",
smooth: 2,
smoothTouch: 0.1,
effects: true
});
let sections = gsap.utils.toArray(".slide");
let maxWidth = 0;
const getMaxWidth = () => {
maxWidth = 0;
sections.forEach((section) => {
maxWidth += section.offsetWidth;
});
};
getMaxWidth();
ScrollTrigger.addEventListener("refreshInit", getMaxWidth);
const width = document.querySelector(".slider").getBoundingClientRect().width;
let scrollTween = gsap.to(sections, {
x: () => `-${width - window.innerWidth}`,
ease: "none"
});
let horizontalScroll = ScrollTrigger.create({
animation: scrollTween,
trigger: ".slider-container",
pin: true,
onEnter: () => console.log("enter"),
scrub: 1,
snap: {
snapTo: 1 / (sections.length - 1),
duration: 0.05
},
// base vertical scrolling on how wide the container is so it feels more natural.
end: () => `+=${width}`,
markers: "true"
});
sections.forEach((section, index) => {
let tl = gsap.timeline({
scrollTrigger: {
containerAnimation: scrollTween,
trigger: section,
start: "left 50%",
end: "right 50%",
markers: {
startColor: "green",
endColor: "red",
fontSize: "1rem"
}
}
});
});
var dragRatio = maxWidth / (maxWidth - window.innerWidth);
var drag = Draggable.create(".drag-proxy", {
trigger: ".slider-container",
type: "x",
allowContextMenu: true,
onPress() {
this.startScroll = horizontalScroll.scroll();
this.maxScroll = ScrollTrigger.maxScroll(window);
},
onDrag() {
horizontalScroll.scroll(
Math.min(this.startScroll - (this.x - this.startX) * dragRatio, this.maxScroll)
);
}
})[0];
This Pen doesn't use any external CSS resources.