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:...