Jump to content
GreenSock

FrankRuiz

ScrollTrigger Messing up GatsbyJS Scroll Position

Moderator Tag

Recommended Posts

Hello, 

I've setup the following 'Reveal' component to use on my current project (GatsbyJS) and found that when navigating to a new page after scrolling to the next one, the next page does not start a the top. 

It basically sets up a ScrollTrigger on a given target element and can be passed an animation prop for different animations.
 

import React, { useRef, useLayoutEffect } from 'react';

import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

gsap.registerPlugin(ScrollTrigger);

const ns = `reveal`;

const Reveal = ({ children, animation }) => {
	// target
	const targetElement = useRef();

	useLayoutEffect(() => {
		const target = targetElement.current;
		animation(target);
	}, [animation]);

	return (
		<div ref={targetElement} className={`${ ns }`}>
			{children}
		</div>
	);
};

Reveal.defaultProps = {
	// Set the defalut reveal functionality here, custom reveals
	// can be passed to Reveal using the callback prop
	animation: target => {
		// setting 'from' / initial styles here
		gsap.set(target, {
			y: 50,
			opacity: 0,
			transition: 'all 150ms linear',
		});

		gsap.to(target, {
			// ScrollTrigger settings see link below for all options
			// https://greensock.com/docs/v3/Plugins/ScrollTrigger
			scrollTrigger: {
				start: 'top+=100 bottom',
				trigger: target,
				toggleActions: 'play none none reset',
			},
			// setting 'to' / revealed styles here
			y: 0,
			opacity: 1,
			duration: 0.15,
			transition: 'all 150ms linear',
		});
	},
};

export default Reveal;



Anyone have any ideas as to why this behavior is happening?  I am thinking I need to kill the ST instances when the component unmounts/page changes. Adding ScrollTrigger.refresh(true) on the page change (layout component) did not make a difference. 

Link to comment
Share on other sites

you'll definitely want to do garbage cleanup and kill the ST instance. You'll want to give your ScrollTriggers an unique ID then basically:

 

useEffect(() => () => {
  if (ScrollTrigger.getById('your-id') {
    ScrollTrigger.getById('your-id').kill();     
  }
}, [])

 

  • Like 2
Link to comment
Share on other sites

Yeah, it's tough to say without a minimal demo but if you need to kill all the ScrollTriggers, you wouldn't even need to use IDs or whatever - you can do this: 

ScrollTrigger.getAll().forEach(t => t.kill());

 

Link to comment
Share on other sites

I usually try to avoid the .getAll, in the case that they/I are using ST in the header file ( to control a nav collapse or similar) that doesn't get un/re-mounted on page change. But if that isn't the case, kill em all.

  • Like 2
Link to comment
Share on other sites

Thanks for your responses guys. I did add a cleanup/Scrolltrigger.kill() to my useEffect but it did not fix the issue.  What does seems to have worked is adding a Scrolltrigger.refresh() in that useEffect. Not sure how that will impact performance though.

 

	useEffect(() => {
		gsap.registerPlugin(ScrollTrigger);

		const target = targetElement.current;
		animation(target);

		ScrollTrigger.refresh();
	}, [animation]);

 

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