Jump to content
Search Community

Smooth page scrolling with TweenMax

janCapricorn test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hi Guys, 


I stumbled on this post http://bassta.bg/2013/05/smooth-page-scrolling-with-tweenmax/ and implement the script there but not the result i wanted.  


Here is the script that 

	var $window = $(window);		//Window object
	var scrollTime = 0.3;			//Scroll time
	var scrollDistance = 50;		//Distance. Use smaller value for shorter scroll and greater value for longer scroll
	$window.on("mousewheel DOMMouseScroll", function(event){
		var delta = event.originalEvent.wheelDelta/120 || -event.originalEvent.detail/3;
		var scrollTop = $window.scrollTop();
		var finalScroll = scrollTop - parseInt(delta*scrollDistance);
		TweenMax.to($window, scrollTime, {
			scrollTo : { y: finalScroll, autoKill:true },
				ease: Power1.easeOut,	//For more easing functions see http://api.greensock.com/js/com/greensock/easing/package-detail.html
				autoKill: true,
				overwrite: 5							


How to achieve something like this smooth page scroll on this page  - https://www.shift-capital.com/about?


Please help.

Link to comment
Share on other sites

Hello @janCapricorn and Welcome to the GreenSock Forum!


You might want to look into throttling and debouncing for scrolling events to prevent jank and get smooth silkiness. Since your code will be firing an insane amount of times due to how the scroll event fires.









  • Like 2
Link to comment
Share on other sites

You should check out the examples i provided for the scrolling event.


But for smooth scrolling you can try and use ScrollMagic, which is a scrolling management tool that uses GSAP as its animation platform.





Also @OSUblake did a simple scroll like magic with less bloat



But some others in the forum might be willing to share there code of something similar :)


  • Like 4
Link to comment
Share on other sites

Hi Blake,


Ok, ok ... no doubt about UX principles.


An article of uxdesign (https://uxdesign.cc/ux-trends-2017-46a63399e3d2) put it in a broader frame.
Here just an extract:


"The products and apps we design are used by millions - sometimes billions - of people, creating new markets, improving the economy, and shaping up how people interact with each other. While delightful animations and novelty technologies can put a smile on someone’s face, we have the tools and responsibility to impact much more than that with our work.

Why does one choose to use Gmail over Yahoo, Medium over Blogger - if the features are 99% the same? It’s definitely not about disrupting usability standards. It’s about that additional layer of sophistication that can only be achieved when you put enough time and brainpower into the tiniest details, the most subtle animations, the most elegant transitions – not just for the sake of creating whimsical dribbble shots."


By the way - I`m not advocating to use scroll speed in 'normal' webs or apps.
In a portfolio site or other creative projects it could provide a special kick.
It depends on concept, content and intended target group.


Well - principles are helpful, but please no orthodox discussion and usage.
You need always a good reason because more than ever the user will response by click.


Open minded ...

Link to comment
Share on other sites

Hi @mikel


By scroll jacking, I'm talking about interrupting or changing the native scroll bar behavior. Much like this demo screws with your mouse.


See the Pen GJJPpV by gunderson (@gunderson) on CodePen


I'm not against scrolling animations or parallaxing. Quite the opposite. I actually do a lot of that stuff... but with my own scroll magic.


Look at the demo Jonathan posted above. There's actually no content being scrolled, yet the scroll bar behaves normally, even with touch.


If you need to do scroll jacking, just hide the scroll bar. You can get the effect you want, but without messing with user expectations. That's what a lot of the apps on GSAP's and Pixi's showcase pages do, most of which have won some type of award.


A couple of the first ones I came across. Some really nice stuff!








  • Like 7
Link to comment
Share on other sites



I'm pretty let down by scroll magics performance on mobile without using i-scroll or some other hack... but love how a lot of the heavy lifting is already done.


Looking for a better solution...


I was looking at Apple's page on mobile and it performs really well: https://www.apple.com/homepod/


I see they are using TweenMax/TimelineMax, but was wondering how they are trigger/tracking things. The animation at the beginning of the homepod rotating is really smooth based on scrolling...




Link to comment
Share on other sites

  • 2 weeks later...

Hi @martis 


I think the way that Apple page works is by virtualizing the scroll. And from what I can tell, that is what i-scroll is doing. Basically its manually adjusting the position of content based on the scroll position, only displaying what should be visible and hiding everything else. There's really not an easy answer for how to implement that. If you want to learn how it works, I would start by searching for tutorials about how to create a virtual scroll container.


  • Like 4
Link to comment
Share on other sites

  • 4 months later...

Hi @OSUblake


I am beginner at animation and getting into GreenSock, I am trying to build scroller basing on your scroller example.

I have a problem with click and hover behavior on content in steps  (bottom layer )

I was trying to mke use of css pointer-event in wrapper element but that has also influence on scroll event.

I am already out of ideas, how to handle that problem.


Link to comment
Share on other sites

Hi @mikel,


In demo I launched demo made by @OSUblake with added text on step1 (should turn red when is hovered by mouse)

I have a problem with catching pointer events like click or hover on content in steps  in virtual scroller when I have wrapper on top.

I dont really have idea how to manage it in different way.


Thank you very muh for help.


Kind regards,



See the Pen vWXbmd by mercyy (@mercyy) on CodePen


Link to comment
Share on other sites

Thank you very much for answer and another demo, but I have a problem in my previous question that element which is blocking pointer events is wrapper  because it is as top layer, in case when I would put wrapper as bottom layer I can`t scrool wrapper where I have eventListener set. I am wondering how I can manage pointer events on steps in case when I need to use wrapper on top. or how I can make animation scrolling with steps with different sizes wihout wrapper.

Link to comment
Share on other sites

  • 2 months later...

UPDATE : It might well be a performance issue related to screen resolution & stuff. I'll investigate on that. I'll keep the post around to see if somebody come up with a solution anyway, provided that you could replicate the issue.


Hey @OSUblake


Just stumble upon that magnificent piece of code a couple of days ago. I'm using it on a project and it works fantastic ! Thanks for you work.


BUT ! yes, of course there's a but... I'm struggling with an issue and i can't figured out what I might be doing wrong. The issue is that, if i've got more than three/four images (give or take) on the screen at the same time, the scroll become painfully slow and jagged... And this is only occuring when i'm using Firefox as a browser. I'm on mac and it shouldn't be a a CPU/GPU related issue as i'm running on the last gen Macbook pro 15.


Any idea of what might be causing the issue ? Do you think it might be code related ? I've tried to work around the requestAnimationFrame as I thought it might be causing the issue but I'm running out of ideas regarding the issue.


I've attached a pen so you can check for yourself. And because it couldn't get any weirder, the problem is not occurring when I resize down my browser to a certain amount... so i'm basically wondering if finally it might be a performance issue on my side but I doubt it.


Enough said, if you or any users knows what might be happening, I'll be glad to hear about that ! 


Thanks !


your original pen : 




See the Pen QqPqbN by osublake (@osublake) on CodePen




my pen (same stuff but updated with a different layout) : 


See the Pen LQNZgv by wooooosky (@wooooosky) on CodePen




  • Like 1
Link to comment
Share on other sites

Hi @wooooosky


I really haven't looked at the issue, but it shouldn't be related to the requestAnimationFrame loop. I've been noticing that Firefox behaves quite differently depending on the graphics card I use. An integrated one seems to perform better than a discrete one, which doesn't make a lot of sense.


Performance can be improved by setting the visibility to hidden on items that are not inside the view port. That's probably a good candidate for using the Intersection Observer.




That's what Scrollama.js uses.



  • Like 3
Link to comment
Share on other sites

  • 4 months later...

Hi Everyone


So i tried to implement the above smooth scroll. Please take a look at the where its being implemented yet it has no way near the effects of the code pen mentioned above. Below is what I used. Any help would be great.


Staged-version:  https://aisg-nyc.herokuapp.com/industry



$('document').ready(() => {
  var html = document.documentElement;
  var body = document.body;
  var scroller = {
    target: document.querySelector("#root"),
    ease: 0.06, // <= scroll speed
    endY: 0,
    y: 0,
    resizeRequest: 1,
    scrollRequest: 0,
  var requestId = null;
  TweenLite.set(scroller.target, {
    rotation: 0.01,
    force3D: true
  window.addEventListener("load", onLoad)
  function onLoad () {
    window.addEventListener("resize", onResize, true);
    document.addEventListener("scroll", onScroll, true);
  function updateScroller () {
    var resized = scroller.resizeRequest > 0;
    if (resized) {    
      var height = scroller.target.clientHeight;
      body.style.height = `${height}px`;
      scroller.resizeRequest = 0;
    var scrollY = window.pageYOffset || html.scrollTop || body.scrollTop || 0;
    scroller.endY = scrollY;
    scroller.y += (scrollY - scroller.y) * scroller.ease;
    if (Math.abs(scrollY - scroller.y) < 0.05 || resized) {
      scroller.y = scrollY;
      scroller.scrollRequest = 0;
    TweenLite.set(scroller.target, { 
      y: -scroller.y
    requestId = scroller.scrollRequest > 0 ? requestAnimationFrame(updateScroller) : null;
  function onScroll() {
    if (!requestId) {
      requestId = requestAnimationFrame(updateScroller);
  function onResize() {
    if (!requestId) {
      requestId = requestAnimationFrame(updateScroller);




Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...