Scrollmagic Pinned Slideshow

Example of pinned scroll-position-driven horizontal slideshow using ScrollMagic.js and GSAP.

by the_voder

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/ScrollMagic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/animation.gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/debug.addIndicators.min.js"></script>
<!-- Attempt to use semantic HTML tags
<section> defines a visual section the page.
Container <div> is generic -->

<section id="article1">
    <h2>Section 1</h2>
</section>
<section id="article2" class="slideshowSection">
    <div class="slideContainer">
        <section id="slide1" class="slide">
            <h3>Slide 1</h3>
        </section>
        <section id="slide2" class="slide">
            <h3>Slide 2</h3>
        </section>
        <section id="slide3" class="slide">
            <h3>Slide 3</h3>
        </section>
        <section id="slide4" class="slide">
            <h3>Slide 4</h3>
        </section>
    </div>
</section>
<section id="article3">
    <h2>Section 3</h2>
</section>

CSS

/*
Set box-sizing so elements do not expand when padding and borders added (because, why would you want that?)
https://css-tricks.com/box-sizing/ */

html {
    box-sizing: border-box;
}

*,
*:before,
*:after {
    box-sizing: inherit;
}

body {
    margin: 0;
}

/* Applies to all section elements */
section {
    margin: 50px;
    padding: 0;
   /*  Section is full size of viewport using viewport-relative vw/vh units */
	width: 100vw;
    height: 100vh;
}

/* Override section properties for slideshow section */
.slideshowSection {
	margin: 0;
	padding: 0;
	overflow: hidden;
	/* Required for zoom effect */
	-webkit-perspective: 1000;
	perspective: 1000;
}

.slideContainer {
    margin: 0;
    padding: 0;
    width: 400vw;
    height: 100vw;
}

.slide {
    margin: 0;
    padding: 0;
    width: 100vw;
    height: 100vh;
	/* Flex container, to allow centring of contents */
    display: flex;
    justify-content: center;
    align-items: center;
	/* Floats are 'eww'. Could also use Flex, but floats used for simplicity, here */
	float: left;
}

.slide:nth-child(1) { background-color: #F29F05; }
.slide:nth-child(2) { background-color: #F28B30; }
.slide:nth-child(3) { background-color: #BF591F; }
.slide:nth-child(4) { background-color: #8C0303; }

JavaScript

/*
Scroll-driven horizontal slideshow in section of page using pinning.
Requires ScrollMagic and GSAP.

NOTE:
Values are hard-coded in this example for a slideshow consisting of 4 slides. A more flexible approach could be taken, with a little extra code (and a tiny bit of maths), that would work with an arbitrary number of slides.
*/

$(document).ready(function() {
	
	// Init
	var controller = new ScrollMagic.Controller();
	
	// Define movement of panels (basic horizontal slide)
    var wipeAnimation = new TimelineMax()
         // Animate to second panel
         .to(".slideContainer", 1.0, {x: "-25%"},"+=0.5")	// Position property ("+=0.25") delays scrolling so slide remains perfectly centred for a few pixels of scroll
         // Animate to third panel
         .to(".slideContainer", 1.0, {x: "-50%"},"+=0.5")
         // Animate to fourth panel
         .to(".slideContainer", 1.0, {x: "-75%"},"+=0.5")
         .to(".slideContainer", 1.0, {x: "-75%"})			// Hold last value (better method?)
        
   // Slides with zoom effect
   /* var wipeAnimation = new TimelineMax()
            // Animate to second panel
            .to(".slideContainer", 0.5, {z: -150},"+=0.5")	// Move back in 3D space
            .to(".slideContainer", 1.0, {x: "-25%"})		// Move in to first panel
            .to(".slideContainer", 0.5, {z: 0})				// Move back to origin in 3D space
            // Animate to third panel
            .to(".slideContainer", 0.5, {z: -150},"+=0.5")
            .to(".slideContainer", 1.0, {x: "-50%"})
            .to(".slideContainer", 0.5, {z: 0})
            // Animate to fourth panel
            .to(".slideContainer", 0.5, {z: -150},"+=0.5")
            .to(".slideContainer", 1.0, {x: "-75%"})
            .to(".slideContainer", 0.5, {z: 0})
        .to(".slideContainer", 1.0, {z: 0});			// Hold last value (better method?) */
	
	// Create scene for pin and link animation
	new ScrollMagic.Scene({
			triggerElement: "#article2",
			triggerHook:...