"CodePen Home Vertical Slider with ScrollTrigger"
Bootstrap 4.1.1 Snippet by ranjit1602

<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <!------ Include the above in your HEAD tag ----------> <div class="intro"> <div class="visual"> <img src="https://images.unsplash.com/photo-1478766191016-3cb2df3122ef" class="bg-img"/> </div> <h1 class="title">Let's go for a ride</h1> </div> <div class="slide-container"> <section id="slide-1" class="slide slide-odd"> <img src="https://images.unsplash.com/photo-1530143584546-02191bc84eb5" class="bg-img" /> <h2 class="slide-title">slide 1</h2> </section> <section id="slide-2" class="slide slide-even"> <img src="https://images.unsplash.com/photo-1503669678209-c68d00b3765d" class="bg-img" /> <h2 class="slide-title">slide 2</h2> </section> <section id="slide-3" class="slide slide-odd"> <img src="https://images.unsplash.com/photo-1496147539180-13929f8aa03a" class="bg-img" /> <h2 class="slide-title">slide 3</h2> </section> <section id="slide-4" class="slide slide-even"> <img src="https://images.unsplash.com/photo-1497515098781-e965764ab601" class="bg-img" /> <h2>slide 4</h2> </section> <div class="slide-progress"><span class="progress-thumb" /></div> </div> <footer> <h2>THE END</h2> </footer> <header> <a href="https://greensock.com/scrolltrigger"> <img class="greensock-icon" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/scroll-trigger-logo-light.svg" width="200" height="64" /> </a> </header>
.intro { position: relative; height: 90vh; background-color: #000; color: #fff; .visual { position: absolute; top: 0; left: 0; width: 100%; height: 100%; &::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(rgba(0, 0, 0, 0) 20%, rgba(0, 0, 0, 0.5)); } } .bg-img { will-change: transform filter; filter: brightness(50%); } } .title { position: relative; } .bg-img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; } footer { height: 50vh; background-color: darken(#4ea59f, 30%); color: #fff; } .slide-container { height: 100vh; position: relative; overflow: hidden; } .intro, .slide, footer { display: flex; flex-direction: column; justify-content: center; align-items: center; } .slide { position: absolute; width: 100%; height: 100%; overflow: hidden; color: #fff; will-change: transform; // &.slide-odd { // background-color: hotpink; // } // &.slide-even { // background-color: #4ea59f; // } &::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.25)); } .bg-img { width: 120%; height: 120%; left: -10%; } } .slide-title { position: relative; } .slide-progress { position: absolute; top: 20px; left: 20px; right: 20px; height: 4px; background-color: rgba(255, 255, 255, 0.25); } .progress-thumb { display: block; height: 100%; background-color: rgba(255, 255, 255, 0.5); transform: scaleX(0); transform-origin: left; }
const lenis = new Lenis(); function raf(time) { lenis.raf(time) requestAnimationFrame(raf) } requestAnimationFrame(raf) gsap.registerPlugin(ScrollTrigger); // parallax effect on the header img gsap.to('.intro .bg-img', { y: '80%', ease: Power0.easeNone, scrollTrigger: { trigger: '.intro', start: 'top 1px', end: 'bottom 100px', scrub: true, // markers: true, }, }); // gradually darken and blur the header img gsap.to('.intro .bg-img', { filter: 'brightness(0.25) blur(16px)', ease: Power0.easeNone, scrollTrigger: { trigger: '.intro', start: 'center top', scrub: true, // markers: true, }, }); // the header title gsap.to('.intro .title', { y: '45vh', ease: Power0.easeNone, scrollTrigger: { trigger: '.intro', start: '25% top', scrub: true, } }); const progressTL = gsap.to('.progress-thumb', { scaleX: 1, ease: Power0.easeNone, paused: true }); const slides = gsap.utils.toArray('.slide'); const slidesTL = gsap.timeline(); function slideTL(slide, isFirst = false) { const tl = gsap.timeline(); if (!isFirst) { tl.from(slide, { xPercent: 100, }); tl.from(slide.querySelector('h2'), { duration: 0.25, opacity: 0, x: 100, }, 0.2); } tl.fromTo(slide.querySelector('.bg-img'), { xPercent: isFirst ? 0 : 8, }, { xPercent: -8, }, 0); return tl; } slides.forEach((slide, i) => { if (i === 0) { slidesTL.add(slideTL(slide, true)); } else { slidesTL.add(slideTL(slide), '-=0.1'); } }); ScrollTrigger.create({ animation: slidesTL, trigger: ".slide-container", start: "top top", end: `+=${slides.length * 100}%`, scrub: 1, pin: true, anticipatePin: 1, onUpdate: (self) => { progressTL.progress(self.progress); }, }); gsap.from('footer h2', { opacity: 0, y: 100, duration: 0.6, scrollTrigger: { trigger: 'footer', toggleActions: 'play none none reset', start: 'center bottom', // scrub: 0.5, // markers: true, }, });

Related: See More


Questions / Comments: