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.
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.
1. HTML and CSS
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
.
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
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
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
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.
5. Create a Simple GreenSock Tween
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
.
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
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
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
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
).
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.
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
- ScrollMagic Tutorial – Fullscreen Slideshow
- How To Animate SVG With GreenSock
- SVG Scrolling Animation Triggered By ScrollMagic
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.
Another good and step by step tutorial..
Thanks for the nice feedback Fahim!
Exactly what I was wanting to learn about Greensock.
Thanks Petr!
Thanks Christian and let me know if you have any other suggestions for my future tutorials and demos. Cheers
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!
Thanks Simon. Don’t forget to fork the CodePen and play with the code.
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.
Thanks for the nice feedback Sherrie, that keeps me going!
How to get pixie dust effect using skrollr?
Please help…
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.
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 ?
Hi Nicolas,
vh
unit support is quite good, but I had some issues with it especially on older iOS devices.I am not sure what your concept is, but have you tried to use the
%
instead ofvh
?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/
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!
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.
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