OSUblake

Smooth Page Scroll

Recommended Posts

Hey Blake, I know its been a year since you posted this scrolling parallax example, I really like it and I've been trying to figure somethings out. Mainly, how to update the 'scroll-container' height when I remove one of the image-items dynamically. I'm using your example as a menu - and so when an image is clicked, all other images are set to display:none - but the parent container height remains the same - just as when all the images were there. How can I trigger the scroll-container height to update to fit the one remaining image-item?

 

Hope you can help - Thanks

Share this post


Link to post
Share on other sites

In current implementation, Blake just loops through all the target elements that have data-depth attribute. And there is no logic in place to check if element is visible or hidden. You can add a property to 'item' that you can use to skip the element from the loop, but you will also have to adjust the the count of items to change the loop because you are skipping item and rest of calculation depends on the index. Kind of tricky situation as you will just have to rewrite most of the parts of it because Blake doesn't plan to provide support for it.

  • Like 3

Share this post


Link to post
Share on other sites

Hey Sahil, thanks for the reply.

 

The effect im looking for is already built-in Blakes code - its an event that fires whenever the browser window is resized or scrolled. Im basically trying to trigger that same event when I click on something. The scenario is, I have a 4 images - I click on one and the rest set to display:none. When only 1 image remains, the .scroll-container height does not update. However, when I manually resize the browser window, the scroll-container height updates and then so does the scroll position

 

below are the event functions Blake defines  

 

this._onResize = function (event) {
_this.resizeRequest++;
if (!_this.requestId) {
_this.lastTime = performance.now();
_this.requestId = requestAnimationFrame(_this._update);
}
};
this._onScroll = function (event) {
_this.scrollRequest++;
if (!_this.requestId) {
_this.lastTime = performance.now();
_this.requestId = requestAnimationFrame(_this._update);
}
};

Share this post


Link to post
Share on other sites

forgot to add this piece to...

 

this._update = function (currentTime) {
if (currentTime === void 0) { currentTime = performance.now(); }
var elapsedMS = currentTime - _this.lastTime;
if (elapsedMS > _this.maxElapsedMS) {
elapsedMS = _this.maxElapsedMS;
}
var deltaTime = elapsedMS * _this.targetFPMS;
var dt = 1 - Math.pow(1 - _this.scrollEase, deltaTime);
var resized = _this.resizeRequest > 0;
var scrollY = window.pageYOffset;
if (resized) {
var height = _this.target.clientHeight;
document.body.style.height = height + "px";
_this.scrollHeight = height;
_this.viewHeight = window.innerHeight;
_this.halfViewHeight = _this.viewHeight / 2;
_this.maxDistance = _this.viewHeight * 2;
_this.resizeRequest = 0;
}

Share this post


Link to post
Share on other sites

You can force it to reset.

 

scroller.resizeRequest++;
scroller.scrollRequest++;
scroller.addItems();
scroller._update();

 

  • Like 1

Share this post


Link to post
Share on other sites

That's the code. 

function clickHandler() {
  // change stuff
  ...
  
  // force update
  scroller.resizeRequest++;
  scroller.scrollRequest++;
  scroller.addItems();
  scroller._update();
}

 

  • Like 4

Share this post


Link to post
Share on other sites

Click anywhere, and it will hide a couple images.

 

 

  • Like 5

Share this post


Link to post
Share on other sites

Thanks man, I was in the mud on that one. guess, I'm off to my next headache 😄

Share this post


Link to post
Share on other sites

Now I have to figure out how to get around the page jump when I remove all but one image - Any Ideas? I was thinking maybe wrap the image-item in a div on.click and that could some how cushion/prevent it from shooting up and out of the screen abruptly...

Share this post


Link to post
Share on other sites

I'm not really sure what you're trying to do, but trying to remove all the images but one without a jump doesn't seem possible without another container that is fixed. The image that you want to isolate, you could clone and append it the same screen location in the another fixed container.

  • Like 2

Share this post


Link to post
Share on other sites

Thanks for the suggestion, I haven't considered that idea. I think in that case tho, a jump would still take place to some extent.

What I had in mind is: the image-item after being clicked - could then tween to the center of the screen during the forced reset.  because the doc height reset happens so quickly - I could, as part of the click event, tell the window.scrollTo(0, 0) and possibly avoid the jump.

 

really im just trying to mimic (in a very hackish way) what this portfolio site does on its project menu page http://alexandrerochet.com/ check out the page right after the intro - then click on a project to see the effect. its pretty slick I think.

Share this post


Link to post
Share on other sites

Hello Everyone,

 

I've implemented Blake's smooth scrolling solution and am in love with it. With that in mind, I'm bashing my head the past 24 hrs on trying to get this to work in mobile. Blake's already addressed what the issue is, 

Quote

The address bar causes problems when it moves in and out of view.

 

Has anyone found a workaround or even better, come up with a working solution for mobile?

Any suggestions, direction, help on any level would be greatly appreciated.

Share this post


Link to post
Share on other sites

Although I don't use blakes implementation in this post (I use scrollmagic which is a scrolling system made for TweenMax and has parallax , pining, easing, and a ton of other advanced features) 

 

I have parallax / fading / scroll based animations on my personal site and it works great on mobile.  check it out at zadesigns.com

 

I use a combination of iNOBounce and ViewportUnitBuggyFill  to get it to work.

 

the only downside is that you are stuck with the address bar and the tab bar...  but blame Apple for that. 

 

good luck

  • Like 1

Share this post


Link to post
Share on other sites

Nice man, site looks impressive!

 

My site just requires two things -- smooth scroll + fading elements on scroll.

For this I'm using Blake's implementation + Intersection Observer API.

 

What I really like about Blake's implementation is it's purely JS, and JS that I can see/tinker with easily.

I haven't tested my app on iOS but see this on chrome + android.

To visually see what's happening, 

 

Found this video on a thread btw.

The only workaround (if you can call it that) I can think of to address all devices, is to remove the smooth scroll functionality for mobile. Having trouble with this too.

 

Tried going the JS + GSAP way,

     if (window.innerWidth <= 800 && window.innerHeight <= 730) {
		// remove and update classes
       TweenMax.set(this.el, { className: -=main});
       TweenMax.set(this.el, { className: +=main-mobile});
     };

 

Tried swapping css files dependent on viewport but having issues in a SSR Next.js environment.

 

But still no luck. 

 

Seems like ViewportUnitBuggyFill is meant for legacy browsers on android where vh,vw units are not recognized. This is a concern too, but not quite there yet. I'm still working on getting this to work on modern browsers lol.

 

As you can see, right now I'm leaning heavily on this forum lol.

Share this post


Link to post
Share on other sites

The mobile issue can be solved by using a fixed body size, and making another element scrollable. For an example, go to stackblitz and start an ionic app. The only downside to that approach is that the navigation bars will not shrink or move out of view. 

 

And here's one way to listen for media query changes instead of resize events.

 

 

 

  • Like 3

Share this post


Link to post
Share on other sites

Hey Blake,

 

Great to hear from you!

Could you elaborate using your smooth scroll implementation? Or if you could elaborate a little more on the fixed body size approach..

I just tried the following..

 

body {
  // BEFORE
  // overflow-x: hidden !important;
  // overflow-y: scroll !important;
  background: #148991;
  height: 310rem !important;
}

a { cursor: pointer; text-decoration: none !important; }

#main {
  // AFTER
  overflow-x: hidden !important;
  overflow-y: scroll !important;

  background: linear-gradient(to right top, #148991, #011219, #022531, #074757) !important;
  overflow: hidden !important;
  position: fixed;
  width: 100vw;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  justify-content: center;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

 

Am I going in the right direction here? At this point the address bar still causes teh issue

Share this post


Link to post
Share on other sites

Interestingly, keeping your original implementation and simply adjusting the scroll speed seemed to have done the trick. At least in Chrome / Android.

The resize event is still firing but given the new range of values maybe the jump is too small to notice.

 

    let scroller;

    if (window.innerWidth <= 800 && window.innerHeight <= 730) {
      scroller = {
        target: document.querySelector("#playground-subcontainer"),
        ease: .5, // <-- scroll speed on mobile
        endY: 0,
        y: 0,
        resizeRequest: 1,
        scrollRequest: 0,
      };
    }
    else {
      scroller = {
        target: document.querySelector("#playground-subcontainer"),
        ease: .05,  // <--scroll speed on !mobile
        endY: 0,
        y: 0,
        resizeRequest: 1,
        scrollRequest: 0,
      };
    }

 

Share this post


Link to post
Share on other sites

Here's a quickie version that should prevent the navigation bars from moving/resizing. It still has issues, like you can't interact with anything because pointer events are blocked. It could probably be done better using custom elements, but React doesn't play nice with custom elements.

 

 

 

  • Like 3

Share this post


Link to post
Share on other sites

Many many thanks for investing time into this, truly grateful and always great to see your examples.

I'll be sure to try and learn as much as i can from this. Thanks Blake!

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