OSUblake

Smooth Page Scroll

Recommended Posts

I've been getting a bunch of people asking me about how to do a smooth page scroll effect, so here it is. 

 

Scrolling is just a transform. If you scroll 100px down, the browser will translate the page -100px up. We can do that with GSAP.

TweenLite.set(contentToScroll, {
  y: -window.pageYOffset
});

 

So how do you prevent the browser from scrolling the content? Position your content in a fixed container, and set the height of the body equal to the height of your content. This will allow the page to scroll, but the fixed container won't move. Now animate the y position of your content based on the scroll position of the page.

 

 

  • Like 6

Share this post


Link to post
Share on other sites
1 minute ago, Sahil said:

@Noturnoo here is what you might be looking for.

 

Hehe. I just sent him message at the same time you posted that.

  • Like 1
  • Haha 1

Share this post


Link to post
Share on other sites

Pretty slick Blake. B)

 

I have seen that question pop up more and more lately so this will be a nice thread to add to the favorites and point to each time it's asked. 

  • Like 1

Share this post


Link to post
Share on other sites

Omg, that's right. Congratulations @OSUblake, you're a genius. :ugeek:
@Sahil, thank you for reminding me, and congratulations to the Specialist status, you are worthy.

I will implement in my project and see how it will behave, when it is ready I will come back to show. ;-)

Thank you again Guys!:wub:

  • Like 2

Share this post


Link to post
Share on other sites

I'll show how to do parallax later. I want to see if I can optimize it using the Intersection Observer API being discussed here.

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Blake, using his great example of smooth scroll,

got into a situation when using it along with ScrollMagic / GSAP,

I'm trying to create a parallax system in BG image,

but when it starts animating bgImage, the image gets "jumped" created an example using jQuery NiceScroll for you to see more or less the difference.

I need it to be animated along with scrolling to create the Parallax effect:

 

 

 

 

Share this post


Link to post
Share on other sites

Yep. That's to be expected. ScrollMagic doesn't know about the animation, and is getting the scroll position like it normally does, but that's not correct. The value ScrollMagic is using is the end value, not the current value, so it's out of sync.

 

I have some other things I need to do, but I will make a demo later on showing you how to get the smooth parallax working with that code.

 

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Huge thanks for posting this Blake! Very cool!

Share this post


Link to post
Share on other sites
On 25/10/2017 at 9:21 AM, OSUblake said:

Yep. That's to be expected. ScrollMagic doesn't know about the animation, and is getting the scroll position like it normally does, but that's not correct. The value ScrollMagic is using is the end value, not the current value, so it's out of sync.

 

I have some other things I need to do, but I will make a demo later on showing you how to get the smooth parallax working with that code.

 

 

 

@OSUblake

Perfect, anxious.

Share this post


Link to post
Share on other sites
On 10/27/2017 at 1:36 PM, Dipscom said:

Zero pressure from the crowd, @OSUblake...

 

:D

 

 

Yes. I know. I've been sick, and wasn't able to get around to doing anything last week. I'll work on it tonight. 

Share this post


Link to post
Share on other sites

Well, here's the start of something. Put a data-depth attribute on your element like so. 0 will be no offset, 10 will be max offset.

<div data-depth="10"></div>

 

And then create a smooth scroll instance.

var scroller = new SmoothScroll({
  target: document.querySelector("#scroll-container"), // element container to scroll
  scrollEase: 0.1, // scroll speed
  maxOffset: 500
});

 

With maxOffset set to 500, an element with a depth of 10 will move 500px.

10 / 10 * 500 = 500

 

A depth of 5 will move 250px

5 / 10 * 500 = 250

 

And so on...

4 / 10 * 500 = 200

 

 

  • Like 6

Share this post


Link to post
Share on other sites

Hello Blake,

sorry for the delay, I've been working a lot these days.

First of all I want to thank you for having made some of your time available to create this,

it is very useful for me. And I'm sure I'll use it on many projects.
Just a question, is there a way for Parallax to start as soon as the element enters the viewport? For here he is cheering when he comes in half.
A solution similar to ScrollMagic's TriggerHook.

 

Cheers

Share this post


Link to post
Share on other sites
On 11/11/2017 at 10:00 AM, Noturnoo said:

Just a question, is there a way for Parallax to start as soon as the element enters the viewport? For here he is cheering when he comes in half.
A solution similar to ScrollMagic's TriggerHook.

 

I'm not familiar with ScrollMagic. Does the hook start an animation, like one that plays without scrolling?

 

  • Like 1

Share this post


Link to post
Share on other sites

ScrollMagic's TriggerHook system is used to indicate from how many percent what element is in the Viewport it will start the animation.
Example
TriggerHook: 0.8
(The element will start animating when it is 20% of the bottom of the viewport)
Since TriggerHook: 1 is equal to 100% of Viewport.
Did you get it?

  • Haha 1

Share this post


Link to post
Share on other sites

I use scrollmagic and tweenmax in my angular projects and I recently swapped over to a newer ES6 version of scrollmagic called Scroll Wizardry  its a drop in replacement so you can replace your calls from scrollmagic to scroll wizardry.   I am not sure how much difference the performance is but it seems to work great for me.   

 

https://github.com/homerjam/scrollwizardry

 

and if you use vue.js here is a wrapper for it, but if you use something like angular or plain JS you can just call it the standard way.

https://gist.github.com/zurie/f816c1d6569d28b2eafa7fea71b7ed95

 

  • Like 2

Share this post


Link to post
Share on other sites
On 10/31/2017 at 2:37 AM, OSUblake said:

Blake, I don't mean to sound ignorant (it may be too late), but where is SmoothScroll defined?

 

 

And then create a smooth scroll instance.


var scroller = new SmoothScroll({
  target: document.querySelector("#scroll-container"), // element container to scroll
  scrollEase: 0.1, // scroll speed
  maxOffset: 500
});

 

-mark

***** NM Found It! ****

 

 

 
 

 

Edited by msymms
Anwered my own question

Share this post


Link to post
Share on other sites

Blake, so I have dug into the smoothScroll.js file.  I am trying to understand the logic and what exactly you are doing.  There are some behaviors I would like to modify and really just understand what is going on.  You have incorporated a parallax feel which I want to capitalize on as well.  Are you able to answer questions about the code?

 

I don't understand what is happening in this for-loop prior to setting the transform style.

 

for (let i = 0; i < _this.scrollItems.length; i++) {
                let item = _this.scrollItems[i];
                let distance = scrollOrigin - item.top;
                let offsetRatio = distance / _this.maxDistance;
                item.endOffset = Math.round(_this.maxOffset * item.depthRatio * offsetRatio);
                if (Math.abs(item.endOffset - item.currentOffset < _this.endThreshold)) {
                    item.currentOffset = item.endOffset;
                }
                else {
                    // item.currentOffset += (item.endOffset - item.currentOffset) * this.scrollEase;
                    item.currentOffset += (item.endOffset - item.currentOffset) * dt;
                }
                item.target.style.transform = "translate3d(0px,-" + item.currentOffset + "px,0px)";
            }

    

Can you help?

Edited by msymms
Added Code

Share this post


Link to post
Share on other sites

What are you trying to change?

 

That loop is based on the demos and videos in this threads. Instead of moving elements towards the mouse, I'm moving elements towards their original starting position.

 

 

 

Share this post


Link to post
Share on other sites

Let me check that post out.  I'll circle back

 

Share this post


Link to post
Share on other sites

So I have gone through the bulk of Keith's videos.  Quite enlightening.  Things look a little more familiar.  I have been able to start the parallax scrolling at the bottom of the screen.  But I am still trying to figure out the logic.  For instance, what does this value (dt) represent?

let dt = 1 - Math.pow(1 - _this.scrollEase, deltaTime);

 

and 

 

what is the need for an endThreshold?

 

 this.endThreshold = 0.03;

 

Sorry if this is basic stuff, I am just getting back into this after a number of years away.

Share this post


Link to post
Share on other sites

Everything is based on linear interpolation (lerp) being used like an exponential ease. Explaining dt and deltaTime can be hard to explain, so I'm just going to link to this.

https://gamedev.stackexchange.com/a/149106/109260

 

I had one line of code commented out. Use one or the other. Frame dependent animations can slow down during high CPU usage.

 

if (Math.abs(item.endOffset - item.currentOffset < this.endThreshold)) {
  item.currentOffset = item.endOffset;
} else {
  
  // FRAME DEPENDENT
  // item.currentOffset += (item.endOffset - item.currentOffset) * this.scrollEase;
  
  // FRAME INDEPENDENT
  // item.currentOffset += (item.endOffset - item.currentOffset) * dt;
}

 

 

That gamedev answer also mentioned Zeno, which is like a paradox. You can never arrive at a destination because the steps just get smaller and smaller. The threshold stops calculating stuff after a certain limit, i.e. changes you won't see because they are too small.

 

 

 

 

 

  • Like 2

Share this post


Link to post
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.