Greensock + ScrollMagic

Simple ScrollMagic Tutorial

Following up on my previous ScrollMagic tutorial, we’ll add some more content and learn how to animate GreenSock tween and timeline using ScrollMagic, how to control the duration of our pin and much more.

VIEW DEMO RELATED CODEPEN

What you will learn:

  • How to animate GreenSock TweenMax
  • How to animate GreenSock TimelineMax
  • How to add multiple ScrollMagic scenes to a page
  • How to precisely control the duration and timing
  • and much more…

In the previous ScrollMagic Tutorial – Fullscreen Slideshow you’ve learned how to pin sections when they reach the top of the viewport.

Today we’ll add a short pause to our pin and animate a few other tweens and timelines.

If this is your first time checking out ScrollMagic, then I recommend going through my previous ScrollMagic tutorial first and downloading the following toolkit.

Download Free Toolkit

All you need to know to get started with GreenSock and ScrollMagic, in one single package. Straight into your inbox.

100% Privacy. Guaranteed! Powered by ConvertKit

1. HTML and CSS

ScrollMagic HTML Markup

The first section will have a content centered similar to last time.

The sections 2,3 and 4 will have a ScrollMagic card on the left and the copy on the right.

Before we start animating anything with ScrollMagic we’ll create the HTML and CSS for our page.

<html>
<head></head>
<body>

<section id="one">
    <div class="inner innerS1">
        <h1>Simple ScrollMagic Tutorial</h1>
        <p>Learn how to create a <strong>simple scrolling website</strong> using ScrollMagic</p>
    </div>
</section>
<section id="two">
    <div class="innerText innerS2">
        <h2>Why to learn ScrollMagic?</h2>
        <ul class="features">
            <li>It's great for <strong>story telling websites</strong></li>
            <li>It gives you <strong>endless creative power</strong></li>
            <li>It's <strong>easy to use</strong> once you get it</li>
        </ul>
    </div>
</section>
<section id="three">
    <div class="innerText innerS3">
        <h2>When to use ScrollMagic?</h2>
        <ul class="features">
            <li>When building <strong>interactive infographics</strong></li>
            <li>When introducing your <strong>product or service</strong></li>
            <li>When sharing your <strong>unique story or timeline</strong></li>
        </ul>
    </div>
</section>
<section id="four">
    <div class="innerText innerS4">
        <h2>Want to learn more?</h2>
    </div>
    <div class="iphone">
        <p class="screen screenHat"><img src="img/img_scrollMagic.png" /></p>
        <p class="screen screenA">A</p>
        <p class="screen screenB">B</p>
        <p class="screen screenC">C</p>
    </div>
</section>

</body>
</html>

The html is pretty straight forward, we have 4 sections with a unique ID and content inside.

I assume that you are familiar with what is going into the head of the document (stylesheet, fonts etc.).

.inner makes content of the first section centered, other sections are using .innerText which aligns text next to the card.

I named the “card” .iphone, because this could be easily a screenshot of your iPhone app or website on mobile and scrolling down could reveal different screenshots.

body {
  font: 16px/1.5 'Open Sans', Helvetica, Helvetica Neue, Arial, sans-serif;
  color: rgba(0, 0, 0, 0.9);
}

html, body {
  height: 100%;
  margin: 0;
}

h1 {
  padding: 20% 0 0 0;
  margin: 0;
  text-align: center;
  font-size: 36px;
  color: rgba(0, 0, 0, 0.9);
  position: relative;
}
h1:before {
  content: '❤';
  display: block;
  position: absolute;
  bottom: 50px;
  left: 50%;
  text-align: center;
  width: 100px;
  margin-left: -50px;
  color: #ff466a;
  font-size: 30px;
}

p {
  text-align: center;
  color: rgba(0, 0, 0, 0.5);
}

strong {
  color: rgba(0, 0, 0, 0.9);
}
section {
  height: 100%;
  position: relative;
  text-align: center;
}

/* Center aligned first section */
section .inner {
  margin: 0 auto;
  max-width: 85%;
}

/* Content of the following sections aligned next to the iphone */
section .innerText {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-100px, -50%);
  text-align: left;
}

/* iPhone/Card positioned to the left - this is a default position */
.iphone {
  width: 290px;
  height: 600px;
  border-radius: 10px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-150%, -50%);
  background-color: #3757D0;
  background-image: -webkit-radial-gradient(#81bcff, #5d7fce);
  background-image: radial-gradient(#81bcff, #5d7fce);
}

/* Centered content of the ScrollMagic card */
.iphone p {
  font-size: 140px;
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: rgba(255, 255, 255, 0.9);
}

/* Letters hidden by default */
.iphone p.screenA, .iphone p.screenB, .iphone p.screenC {
  opacity: 0;
  visibility: hidden;
}

/* ScrollMagic hat on top of letters */
.iphone p.screenHat {
  z-index: 2;
}
.iphone p.screenHat img {
  max-width: 130px;
}

/* Bullet list */
.features {
  list-style: none;
  margin: 0;
  padding: 0;
  color: rgba(0, 0, 0, 0.6);
}
.features li {
  position: relative;
  padding-left: 17px;
}

/* A heart instead of a bullet */
.features li:before {
  content: '❤';
  font-size: 11px;
  position: absolute;
  left: 0;
  top: 5px;
  display: block;
  color: #ff466a;
}

We are positioning the iPhone screen in the middle of the viewport on pulling it 150% to the left.

.innerText is also centered in the viewport, but is pulled only slightly to the left by 100px.

Simple ScrollMagic Tutorial Layout

The letters A, B and C (.screenA, .screenB, .screenC) are hidden by default, we’ll be animating them with ScrollMagic shortly.

2. Include ScrollMagic and GSAP plugin

ScrollMagic Tutorial

We’ll include jQuery, GSAP TweenMax, ScrollMagic and GSAP plugin for ScrollMagic at the bottom of the page.

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script>
      window.jQuery || document.write('<script src="js/vendor/jquery-1.11.0.min.js"><\/script>')
    </script>

    <!-- Include ScrollMagic and GSAP plugin -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.0/TweenMax.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.3/ScrollMagic.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.3/plugins/animation.gsap.min.js"></script>
    <script src="js/main.js"></script>
  </body>
</html>

Since ScrollMagic 2.0 we need to also include animation.gsap.min.js if we want to use GreenSock for our animation.

This used to be part of the core of ScrollMagic, but has been moved to a separate plugin file in the 2.0 update.

main.js will contain our custom ScrollMagic code and needs to be referenced after all required plugins.

3. Declare Variables First

ScrollMagic Variables

The first thing we’ll do in the main.js is to declare all our variables.

(function($) {
    var wh = window.innerHeight,
        $iphone = $('.iphone'),
        $innerS1 = $('.innerS1'),
        $innerS2 = $('.innerS2'),
        $innerS3 = $('.innerS3'),
        $innerS4 = $('.innerS4'),
        $screenHat = $('.screenHat'),
        $screenA = $('.screenA'),
        $screenB = $('.screenB'),
        $screenC = $('.screenC');

    // Keep adding code here

})(jQuery);

These are all the html elements that we want to animate. If you are not familiar with how to select html elements using jQuery check out the jQuery for Complete Beginners articles.

The variables are self-explanatory, but to recap: we’ll animate the card ($iphone) the content of all 4 sections ($innerS1 - $innerS4), hat ($screenHat) and the letters A, B and C ($screenA - $screenC).

4. Create ScrollMagic Controller and Pause Our Sections For A Moment

ScrollMagic Controller

Similar to my previous ScrollMagic tutorial, we’ll create a controller and pin our sections when they reach the top of the viewport.

// init
var ctrl = new ScrollMagic.Controller({
    globalSceneOptions: {
        triggerHook: 'onLeave'
    }
});

// Create scene
$("section").each(function() {
  
    new ScrollMagic.Scene({
        triggerElement: this,
        duration: '50%'
    })
    .setPin(this)
    .addTo(ctrl);
});

The only difference is the addition of duration: '50%'. This will pin the section for a 50% of the viewport height and then the next section will come into the view.

Pretty simple, huh? Or not?

If you feel overwhelmed by the JavaScript, Skrollr might be a better option for you.

Parallax Scrolling Master Class

5. Create a Simple GreenSock Tween

Greensock Tweenmax

Now lets create a simple GreenSock tween to move the card from the center of the viewport to the position defined in the stylesheet.

// iPhone intro animation Tween
var iphoneIntro = TweenMax.from($iphone, 1, {
    yPercent: 50,
    xPercent: 100,
    ease: Cubic.easeOut
});

We are creating iphoneIntro tween, that will move $iphone from yPercent: 50, xPercent: 100 to the original stylesheet position.

If this is a first time you hear about GSAP animations, check out my GreenSock tutorials or Jump Start JS demo from the GreenSock team.

If you save the page or CodePen demo now, you’ll see the card animating automatically for a duration of 1 second.

Greensock TweenMax + ScrollMagic

Nice move, but we want to “hook” this animation onto the scrollbar movement right?

For that we’ll create another ScrollMagic scene and give it a 70% duration.

// iPhone back to stylesheet position
new ScrollMagic.Scene({
    duration: '70%'
})
.setTween(iphoneIntro)
.triggerElement($('body')[0])
.addTo(ctrl);

By using the .setTween(iphoneIntro) we are attaching this tween to the scrollbar (controller).

Now you should see the card moving based on the scrollbar position.

This is the simplest GSAP – ScrollMagic animation you can create.

TweenMax is great for moving ONE thing from or to or fromTo a defined position.

What we want is to also fade the first section content out at the same time.

For that we’ll need a timeline.

6. Create a Simple GreenSock Timeline

Greensock TimelineMax

If we want to animate two elements at the same time or in a sequence we can create a TimelineMax() timeline.

// iPhone intro animation Timeline
var iphoneIntroTl = new TimelineMax();
iphoneIntroTl
    .from($iphone, 1, {yPercent: 50,xPercent: 100, ease: Power4.easeInOut})
    .to($innerS1, 0.5, {opacity: 0, yPercent: -5, scale: 0.98}, '0');

This lets us define two tweens.

The first $iphone tween is the same as the tween created in the previous step. For timelines I prefer to list individual tweens on it’s own line.

Then we are fading the $innerS1 out, moving it slightly up and scaling down at the same time.

To make sure that both of these tweens are happening at the same time, we are including '0' at the end.

This will add the second tween to the absolute start of the iphoneIntroTl timeline instead of after the first tween.

To “hook” this timeline to the scrollbar, we’ll simply update the .setTween(iphoneIntro) reference to this:

// iPhone back to stylesheet position
new ScrollMagic.Scene({
    duration: '70%'
})
.setTween(iphoneIntroTl)
.triggerElement($('body')[0])
.addTo(ctrl);

This will make sure that we are animating both elements at the same time, while the user scrolls down the page.

Still with me? Keep reading;)

7. Animate ScrollMagic Hat

Greensock + ScrollMagic

We’ll create a few more timelines and ScrollMagic scenes.

var iphoneContentHat = new TimelineMax();
iphoneContentHat		
    .to($screenHat, 1, {yPercent: -50, ease: Power4.easeOut})
    .fromTo($screenA, 1, {yPercent: 20, autoAlpha: 0, scale: 0.8}, {yPercent: 0, autoAlpha: 1, scale: 1, ease: Power4.easeOut}, '0')
    .from($innerS2, 1, {autoAlpha: 0}, '-=0.3');

new ScrollMagic.Scene({
    offset: wh*0.6,
    triggerElement: $('body')[0],
    duration: '80%'
})
.setTween(iphoneContentHat)
.addTo(ctrl);

Here we are moving the hat up and at the same time fading in the letter A.

Again we are animating both tweens at the same time thanks to the absolute position '0' of the second tween.

The third tween of the content ($innerS2) is brought forward by 0.3s by '-=0.3'.

Thanks to GreenSock’s elegant syntax you can fine tune even the most complex animation sequences and precisely control the timing of all your scrolling animations.

The offset for this scene is set to 60% of the viewport height (offset: wh*0.6), this means that the hat starts animating only after the card moves back to the right position, the duration of that scene is 50%.

8. Animate Letters A, B, C

Greensock + ScrollMagic

You should be able to read and deconstruct the following two timelines and scenes quite easily.

var iphoneContent1Tl = new TimelineMax();
iphoneContent1Tl		
    .to($screenA, 0.3, {yPercent: -30, autoAlpha: 0, ease: Power4.easeInOut})
    .fromTo($screenB, 1, {yPercent: 20, autoAlpha: 0}, {yPercent: 0, autoAlpha: 1, ease: Power4.easeInOut})
    .from($innerS3, 1, {autoAlpha: 0}, '-=0.7');

new ScrollMagic.Scene({
    triggerElement: $('.innerS2 h2')[0],
    duration: '50%'
})
.setTween(iphoneContent1Tl)
.addTo(ctrl);

var iphoneContent2Tl = new TimelineMax();
iphoneContent2Tl		
    .to($screenB, 0.3, {yPercent: -30, autoAlpha: 0, ease: Power4.easeInOut})
    .fromTo($screenC, 1, {yPercent: 20, autoAlpha: 0}, {yPercent: 0, autoAlpha: 1, ease: Power4.easeInOut})
    .from($innerS4, 1, {autoAlpha: 0}, '-=0.7');

new ScrollMagic.Scene({
    triggerElement: $('.innerS3 h2')[0],
    duration: '50%'
})
.setTween(iphoneContent2Tl)
.addTo(ctrl);

The first iphoneContent1Tl timeline animates the letter A ($screenA) out of the view, then animates letter B ($screenB) into the view and fades the content of our third section in ($innerS3).

Greensock TimelineMax + ScrollMagic

The second iphoneContent2Tl timeline animates the letter B ($screenB) out of the view, then animates letter C ($screenC) into the view and fades the content of our third section in ($innerS4).

We’ve also changed the triggerElement to the h2 of each of the sections.

VIEW DEMO RELATED CODEPEN

If ScrollMagic, JavaScript or jQuery are not your taste, you can still create amazing scrolling animations using Skrollr.

Check out my Skrollr tutorials and courses to get you started.

Related ScrollMagic and GreenSock articles

Conclusion

There is much more to both GreenSock and ScrollMagic, I hope that this tutorial gave you a good start and showed you how you could use these powerful tools on your own project.

Do you struggle with anything GSAP or ScrollMagic related? Have you used any of them? Let me know in the comments below.

Until next time, happy scrolling.

Download Free Toolkit

All you need to know to get started with GreenSock and ScrollMagic, in one single package. Straight into your inbox.

100% Privacy. Guaranteed! Powered by ConvertKit

16 thoughts on “Simple ScrollMagic Tutorial

  1. Simon

    Pretty awesome tutorial!

    Now i need to read some of the ScrollMagic and GSAP documentation to familiarise with their syntax a little more.. but this is really helpful, particularly the CodePen demo!

    Reply
  2. justawebbie

    Great tutorial as always Petr. I could use more tutorials like this with these scripts. Keep up the good work! You have a way with making it all look so easy.

    Reply
    1. Petr Tichy Post author

      Hi Saroj, you mean the spark effect from the ScrollMagic demo page right?

      It has a lot of keyframes and random values to create the realistic effect, in summary you need to create and animate x number of sparks and animate them along a random path.

      I might create a demo or tutorial explaining similar effect in the future, for now explore the source code of the demo to get an idea how it was done.

      Reply
  3. Nicodev

    Be aware that if you are using some vh units this won’t work… For example, applying body {height: 100vh;} broke everything for me. Any idea how to work with both scrollmagic and vh ?

    Reply
  4. Derek

    Hey Petr,
    I’m having a little trouble. I followed one of your tutorials/codepens to create a parallax of 5 sections on my page. Each section has two columns, one of which contains varying height of text content. I have my js so that the text in that column scrolls up and out of view right before the next section slides up. However, because of different screen resolutions, it seems the scrolling effort is quite differential to the extent that my boss isnt happy with weeks of work. lol.

    Do you have any suggestions?

    Thanks

    http://168.61.221.128/~high5partners/our-services/digital-media/

    Reply
    1. halogenmod

      make your content responsive! make your graphics svg and work on colors and fonts. no one’s gonna read through the essays on a mobile device unless they are stuck without wifi and mobile data and bored, so make your content responsive!

      Reply
  5. nimit

    does this work when there is more content than the viewport height? in my case eveything is working fine as in all divs there is less content. but except 1 div, in which there is more content (more than 12 paras). the content for this div is getting chopped and content below this div is overlapping.

    Reply
    1. Petr Tichy Post author

      Probably not Nimit, it was made with less content in mind. I would suggest to use the knowledge from this tutorial and build your own custom page from scratch. You will be in full control. Cheers

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.