Jump to content
Search Community

Scrolling within a container when the body has overflow hidden

jackkemm test
Moderator Tag

Recommended Posts

Hi there,

 

I am wondering if someone can point me in the right direction for my scenario below.

 

The idea I have is basically the ability to click a column which expands full width, revealing what's within that column. That part is fine, however I would like to then be able to scroll horizontally within that column to show the other items.

 

The sticking point I have - I am using Lenis (I know this is a third party 😬) to pause the scrolling/add overflow hidden to the body, and was wondering if there's a tool of sorts which will allow me to scroll that active container?

 

The reason I want to pause scrolling is to make this act as a takeover, so you have to scroll within this column or close it to be able to carry on scrolling up/down the page.

 

I have tried to create the closest demo possible of what I have so far which I hope helps show better of what i'm trying to achieve and if there's anything in the GSAP world which can help me achieve this!

 

Thanks,

Jack :)

See the Pen GRYoNRJ by jackkemm (@jackkemm) on CodePen

Link to comment
Share on other sites

Hi @Rodrigo,

 

This got me in the right direction thank you!

 

I am doing similar, but updating the timeline progress using the onUp and onDown callbacks.

 

I was wondering if there was a way to smooth the scroll a bit more and make it feel a bit more natural?

 

I have an updated Codepen implementing what i've managed so far below:

See the Pen RwearyE by jackkemm (@jackkemm) on CodePen

 

Thanks for the guidance so far 👍

 

Thanks,

Jack

Link to comment
Share on other sites

Hey,

 

Thanks again for the above!

 

I am trying to add some stagger to the cards on scroll using the velocityX property and have 3 values in a lerp variable to try stagger the velocity a bit.

 

I am using the

See the Pen eYpGLYL by GreenSock (@GreenSock) on CodePen

example you guys have built to try get the desired effect but the velocity using the Observer plugin doesn't seem as smooth as the example linked above?

 

Is there anything I'm missing here?

 

See the Pen RwearyE by jackkemm (@jackkemm) on CodePen

 

Thanks,
Jack

Link to comment
Share on other sites

Hi,

 

I think you're overcomplicating this a bit. Just a few changes in Jack's last example is enough to get something similar to that.

 

First set the easing of the timeline to none in order to have it move in a constant ratio:

const scrollTl = gsap.timeline({ paused: true });

scrollTl.to(cardWrapper, {
  x: () => -1 * (cardWrapper.scrollWidth - window.innerWidth),
  ease: "none", // no easing, constant ratio
  duration: 5,
});

Then in the quickTo instance, make it longer and give it a strong ease out function:

const progressTo = gsap.quickTo(scrollTl, "progress", {duration: 1, ease: "power3.out"});

Finally in the Observer instance make the amount the progress increases/decreases larger:

onUp: (self) => {
  let lapsedProgress;
  if (lapsedProgress === 1) return;
  lapsedProgress = scrollTl.progress() - 0.075; // more progress
  progressTo(lapsedProgress);
},
onDown: (self) => {
  let lapsedProgress;
  if (lapsedProgress === 0) return;
  lapsedProgress = scrollTl.progress() + 0.075; // more progress
  progressTo(lapsedProgress);
},

Here is a fork of Jack's example with those changes:

See the Pen dygOeyo by GreenSock (@GreenSock) on CodePen

 

Hopefully this helps.

Happy Tweening!

  • Like 1
Link to comment
Share on other sites

Hey @Rodrigo,

 

Thanks for the recommendations here! I have implemented them and everything is much smoother.

 

My message above was about creating a lerp type of effect fpr the cards using the velocityY property - that's what that this chunk is trying to do using onUp or onDown:

const posSetter = gsap.quickSetter(cards, "x", "%");
const clamp = gsap.utils.clamp(-20, 20);
const lerp = [8, 16, 24];
const proxy = {
  x: 0
};
Observer.create({
  target: cardItems,
  type: "wheel,touch,pointer",
  onUp: (self) => {
    let lapsedProgress;
    if (lapsedProgress === 1) return;
    lapsedProgress = scrollTl.progress() - 0.075;
    progressTo(lapsedProgress);

    const x = clamp((self.velocityY / -300) * lerp[Math.floor(Math.random() * lerp.length)]);
    if (Math.abs(x) > Math.abs(proxy.x)) {
      proxy.x = x;
      gsap.to(proxy, {
        x: 0,
        duration: 0.8,
        ease: "none",
        overwrite: true,
        onUpdate: () => posSetter(proxy.x)
      });
    }
  },
})

I guess this is a better example of what i'm trying to do, but wanted to use the velocityY property:

See the Pen wvMeNee?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Do you think this is doable or should I go down the route of the above example?

 

Here is the updated Codepen for reference:

See the Pen RwearyE?editors=0011 by jackkemm (@jackkemm) on CodePen

 

EDIT: One thing I noticed too, on mobile/touch devices, the scroll is in the opposite direction. I have tried adding -1 to wheelSpeed and scrollSpeedfor touch devices but the scroll is still in the opposite direction. Is there a way to change this?

 

Thanks,

Jack

Edited by jackkemm
Noticed the scroll direction is the wrong way round on mobile/touch devices.
Link to comment
Share on other sites

Hi,

 

The difference between the example you're linking and your code is that in your code you're moving the entire container with the cards while the other example is moving each card independently. You could create a single tween for each card and update the progress of every tween and change the easing based on the speed of the scroll.

 

Also keep in mind that the example you're linking has a different approach. In that particular code the difference is the duration of each quickTo instance for the progress:

let progressTo = gsap.quickTo(imageAnim, "progress", {
  ease: "power3",
  duration: parseFloat(section.dataset.scrub) || 0.1
});

Unfortunately we don't have the time resources to go through all your setup and create a solution for this. If you want you can hire us on a consulting basis or post in the Jobs & Freelance forums to get help there.

 

Good luck with the project!

Happy Tweening!

  • Thanks 1
Link to comment
Share on other sites

Hey @Rodrigo,

 

Thanks for getting back to me.

 

Fully understand that!

 

I have however cracked it in the meantime thank you.

 

I have tapped into ScrollTrigger.isTouch to work out if the device is a touch device and I am reversing the calcs for touch devices.

 

I also gave a go at implementing the above example for the lerping and it works nicely. I think I was trying to overcomplicate things 😬

 

Here is the Codepen with the updates 👍

See the Pen RwearyE?editors=1011 by jackkemm (@jackkemm) on CodePen

 

Thanks again!

 

Jack

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