Jump to content
Search Community

Scrollsmoother speeding up on each load (SWUP)

RDC test
Moderator Tag

Go to solution Solved by RDC,

Recommended Posts

I've got a bit of an odd issue, but I'm fully aware it's not a GSAP issue, so aren't looking for help with another library, hopefully just a push in the right direction?

 

I've got a site setup using Scrollsmoother and SWUP for page transitions, and am killing SS and reinitializing it on each page transition.

The odd issue I have is after visting other pages, the scroll speed seems to get quicker and quicker.

Any idea what might be causing this?
I had wondered if it was down to assets not loading in prior to SS init, but the height of a page is the same on a window refresh, as it is on a transition.


Initially, I just captured this on video to help show the issue firsthand, as I'm hoping that might be enough to point me in the right direction.

https://streamable.com/b5h22y

For a direct comparison, the first page scroll on the video is normal, and the same page a few page transitions later at 00:43. (same mouse scrolling)

Thanks in advance, and apologies for not having a minimal demo at this stage

Link to comment
Share on other sites

Hi @RDC and welcome to the GreenSock forums!

 

First, thanks for being a Club GreenSock member and supporting GreenSock! 💚

 

The only thing I can think of is that somehow the ScrollSmoother instances are not really being removed, that somehow you have two, three and so forth. I don't have time to dig into SWUP's API and look for some lifecycle methods and create an example of my own and test. Have you ran some console calls in your files that create the ScrollSmoother instances for each page? Are you 100% sure that the entire HTML is being removed? Or is just being replaced by SWUP?

 

The only advice I can give you now is that on every page, wrap everything that is GSAP related in a GSAP Context instance:

https://greensock.com/docs/v3/GSAP/gsap.context()

 

If that's not possible at least wrap the ScrollSmoother instance and before the page gets removed run the revert() method on that GSAP Context instance:

const ctx = gsap.context(() => {
  const smoother = ScrollSmoother.create({
    // config here
  });
});

// Later when the page gets removed
ctx.revert();

But as far as I know nothing should trigger this behaviour unless you're updating the speed parameter in the ScrollSmoother configuration. I just ran some tests running ScrollSmoother create up to five times on the same page in a span of 5 seconds while killing the previously created ScrollSmoother instance and I can't replicate the problem.

 

let smoother = ScrollSmoother.create({
  smooth: 1,
  effects: true,
});
let iterations = 0;
const timer = setInterval(() => {
  smoother.kill();
  smoother = ScrollSmoother.create({
    smooth: 1,
    effects: true,
  });
  iterations++;
  if (iterations > 4) {
    clearInterval(timer);
  }
}, 1000);

Have you tested withou SWUP? Are you using the latest version of ScrollSmoother?

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Thanks Rodrigo, really appreciate your time and energy.

My initial assumption was that it wasn't being killed, but I ran a console command within a function containing kill(), so I could see when it was working.

 

One thing I've though of though... I've be ceeating a new scrollsmoother instance on each page transition, as the <div id="smooth-wrapper"> + <div id="smooth-content"> are replaced as part of the SWUP process. Should I be approaching it like this, or should I be refreshing it somehow (assuming it detects the new html in the DOM?).

I'm also using ScrollTrigger.refresh() once the content is replaced, but that's to make sure other GSAP animations are triggering correctly.


I'm next on this project tomorrow so will check out context and revert then (thank you!).
If that does the trick i'll report back with a bit more info in case it helps others.

Link to comment
Share on other sites

  • Solution

So after a bit of investigation, I've found the source of the issue, although don't fully understand why...

 

To answer your other Qs though:

  • Yes latest version of GSAP & ScrollSmoother (3.11.5)
  • I've not tested without SWUP, as initial page loads are always fine, so the issue lays as a combo between the two.
  • I tried out .context, but it gave me a few scoping issues, so I tried out another approach below.

I stripped all the code way back to the basics to just allow page transitions with GSAP and SWUP, and the issue disseapeared.
As I added the various functions in one by one I found that the issue returned as soon as I started using: smoother.paused(true/false).

I had the following; I used .get() to find the SS instance and pause scrolling, so an intro vid/anim would play, and then unpause. No issues with that.
The SWUP code after then also paused and un-paused the instance when transitioning between pages (to stop people scrolling the page as it loaded in the background, leaving them halfway down a page and being confused).
 

if (ScrollTrigger.isTouch !== 1) {
	const smoother = ScrollSmoother.get();
	smoother.paused(true);
}

// later on down the file


// SWUP handling of transition out (simplified)
const outPage = (next)  => {
	smoother.paused(true);
	var tl = gsap.timeline({
		onComplete: next
	})
}
// and then in (simplified)
const inPage = (next)  => {
	smoother.paused(false);
}

// SWUP stuff just for ref
const pageAnimation = [{
	from: '(.*)',
	to: '(.*)',

	in: function(next) {
		inPage(next);
	},
	out: (next) => {
		outPage(next);		
	}
}];


const swup = new Swup({
	plugins: [
		new SwupJsPlugin(pageAnimation),
	]
});

 

Essentially, I needed to define a new smoother variable using get() for the outPage and inPage variables like below.

The browser didn't flag it as an issue previously, because I guess it could always reference the original 'smoother' variable, even though it was being killed and then re-created on every page load.... so pretty basic JS error on my side!

 

// transition out
const outPage = (next)  => {
	const smoother = ScrollSmoother.get();
	smoother.paused(true);
	var tl = gsap.timeline({
		onComplete: next
	})
}

// transition in
const inPage = (next)  => {
	const smoother = ScrollSmoother.get();
	var tl = gsap.timeline({
		onComplete: next
	})
	smoother.paused(false);
}


As to why it made the page scroll faster... I'm really not sure.

One odd thing I found though, is that after using .kill(), if I ran a console.log of smoother, it would still log something, as opposed to undefined, which somewhat suggests it wasn't being killed.

Anyways, thanks so much again for your time in responding :)
 

 

  • Like 1
  • Thanks 1
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...