Shows how to use Locomotive Scroll with ScrollTrigger
A Pen by Paul Slawik on CodePen.
<div class="smooth-scroll"> | |
<section class="red" data-scroll-section> | |
<div class="section-inner">Text</div> | |
</section> | |
<section class="blue" data-scroll-section> | |
<div class="section-inner">Text</div> | |
</section> | |
<section class="green" data-scroll-section> | |
<div class="section-inner">Text</div> | |
</section> | |
<section class="purple" data-scroll-section> | |
<div class="section-inner">Text</div> | |
</section> | |
</div> |
Shows how to use Locomotive Scroll with ScrollTrigger
A Pen by Paul Slawik on CodePen.
console.clear(); | |
gsap.registerPlugin(ScrollTrigger); | |
// Using Locomotive Scroll from Locomotive https://github.com/locomotivemtl/locomotive-scroll | |
const locoScroll = new LocomotiveScroll({ | |
el: document.querySelector(".smooth-scroll"), | |
smooth: true | |
}); | |
// each time Locomotive Scroll updates, tell ScrollTrigger to update too (sync positioning) | |
locoScroll.on("scroll", ScrollTrigger.update); | |
// tell ScrollTrigger to use these proxy methods for the ".smooth-scroll" element since Locomotive Scroll is hijacking things | |
ScrollTrigger.scrollerProxy(".smooth-scroll", { | |
scrollTop(value) { | |
return arguments.length ? locoScroll.scrollTo(value, 0, 0) : locoScroll.scroll.instance.scroll.y; | |
}, // we don't have to define a scrollLeft because we're only scrolling vertically. | |
getBoundingClientRect() { | |
return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight}; | |
}, | |
// LocomotiveScroll handles things completely differently on mobile devices - it doesn't even transform the container at all! So to get the correct behavior and avoid jitters, we should pin things with position: fixed on mobile. We sense it by checking to see if there's a transform applied to the container (the LocomotiveScroll-controlled element). | |
pinType: document.querySelector(".smooth-scroll").style.transform ? "transform" : "fixed" | |
}); | |
const sections = gsap.utils.toArray('section') | |
sections.forEach( function(section) { | |
const inner = section.querySelector('.section-inner') | |
ScrollTrigger.create({ | |
scroller: '.smooth-scroll', | |
trigger: section, | |
start: 'top top', | |
end: '+=100%', | |
pin: inner, | |
pinSpacing: false, | |
pinType: 'transform' | |
}) | |
}) | |
// each time the window updates, we should refresh ScrollTrigger and then update LocomotiveScroll. | |
ScrollTrigger.addEventListener("refresh", () => locoScroll.update()); | |
// after everything is set up, refresh() ScrollTrigger and update LocomotiveScroll because padding may have been added for pinning, etc. | |
ScrollTrigger.refresh(); |
<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script> | |
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/ScrollTrigger.min.js?v=3.4.0.1"></script> | |
<script src="https://cdn.jsdelivr.net/npm/locomotive-scroll@3.5.4/dist/locomotive-scroll.min.js"></script> |
body { | |
font-family: sans-serif; | |
overflow-x: hidden; | |
} | |
.smooth-scroll { | |
overflow: hidden !important; | |
} | |
section { | |
height: 100vh; | |
width: 100vw; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
color: white; | |
font-size: 40px; | |
font-weight: 800; | |
} | |
.red { | |
background: red; | |
} | |
.blue { | |
background: blue; | |
} | |
.green { | |
background: green; | |
} | |
.purple { | |
background: purple; | |
} |
<link href="https://cdn.jsdelivr.net/npm/locomotive-scroll@3.5.4/dist/locomotive-scroll.css" rel="stylesheet" /> |