Jump to content
Search Community

Failed to execute 'scrollTo' on 'Window': The provided value is not of type 'ScrollToOptions'.

honchoman test
Moderator Tag

Recommended Posts

  • 11 months later...

Hi @Cassie I'm following this article to implement smooth scroll on a eventlistener

 

 

but I'm getting following error in react even I'm using gsap within `useEffect` and I've initialised scrolltrigger. Any suggestion on what should I do?

 

Uncaught TypeError: Failed to execute 'scrollTo' on 'Window': The provided value is not of type 'ScrollToOptions'.
    at PropTween2._setterFunc2 [as set] (gsap-core.js:3679:17)
    at PropTween2._renderComplexString2 [as r] (gsap-core.js:3716:8)
    at Tween2.render3 [as render] (gsap-core.js:3443:12)
    at _lazyRender2 (gsap-core.js:187:36)
    at _lazySafeRender2 (gsap-core.js:193:25)
    at Array.updateRoot (gsap-core.js:2686:7)
    at _tick2 (gsap-core.js:1309:20)

 

Here's what my code roughly looks like

```

import gsap from "gsap";
import { ScrollTrigger } from 'gsap/dist/ScrollTrigger';
 
useEffect(() => {
 gsap.registerPlugin(ScrollTrigger);
gsap.to(
        ".scroll_footer_section",
        {
          duration: 0.2,
          bottom: 50,
          ease: "Power4.out",
        },
        "<0.5"
      );
      gsap.to(window, {duration: 2, scrollTo: 400}, "<0.5");
})
Link to comment
Share on other sites

Hi @Rahul Ahire and welcome to the GreenSock forums!

 

Is a bit hard for us to know exactly what the problem is with the code snippet you provided. Is always better to include a minimal demo so we can see your set up and have a better idea of what you're trying to do. We have this collection of starter templates for using GSAP in a React App:

https://stackblitz.com/@GreenSockLearning/collections/gsap-react-starters

 

From the code you posted there are a few things that stand out though. First, you don't need to register your plugins inside the useEffect or useLayoutEffect hooks, just do that once in the lifecycle of the app (at the top level file in your react app, normally the index.js file that is at the root of the src folder is enough). Second you mention smooth scrolling but I don't see anything related to the ScrollSmoother plugin in there. Are you sure that you installed the gsap-trial package to test the bonus stuff? Take a better look at the installation instructions in the docs. Third, you have the scrollTo wrapper in a tween, but again there is no indication in your code that you are importing and registering the ScrollTo Plugin in your app, so refer to the installation instructions again.

 

Hopefully this helps. If you keep having issues let us know and remember to include a minimal demo.

 

Happy Tweening!

Link to comment
Share on other sites

Yep, as Rodrigo pointed out, there are several problems:

  1. You forgot to load/register the ScrollToPlugin (you only did ScrollTrigger). 
  2. You didn't pass an empty dependency array to your useEffect(), so React will call that again and again on every render. 
  3. You aren't doing proper cleanup. I'd strongly recommend using gsap.context() to make it very easy. Read this article:
  4. You were passing a position parameter ("<0.5") to a normal tween which is invalid. That's only for when you're placing something into a timeline. I'm not exactly sure what you were trying to accomplish there, but if you want to make the animations delay their start time for 0.5 seconds, just set delay: 0.5 in your tween(s). 
  5. You used a capital "P" in "Power4.out" which is incorrect. It should be "power4.out" or just "power4" because "out" is the default type.

So your code could look like:

 

import gsap from "gsap";
import { ScrollTrigger } from 'gsap/dist/ScrollTrigger';
import { ScrollToPlugin } from 'gsap/dist/ScrollToPlugin';

gsap.registerPlugin(ScrollTrigger, ScrollToPlugin); // (or in the top-level file in your React app)

useEffect(() => {
  let ctx = gsap.context(() => {
    gsap.to(".scroll_footer_section", {
          duration: 0.2,
          bottom: 50,
          delay: 0.5
          ease: "power4.out",
        });
    gsap.to(window, {duration: 2, scrollTo: 400, delay: 0.5});
  });
  return () => ctx.revert(); // <-- cleanup!
}, []); // <- empty dependency Array

 

I hope that helps. 

  • Like 3
Link to comment
Share on other sites

First of all I really want to thanks @Rodrigo and Jack for answering, greensock's forum does seem more vibrant than most other places I've seen online. I was indeed using gsap context in my `useEffect` but didn't included it here as my code is bit convoluted. So thought about showing specific bits of it. One request though, it'd be better if the scrollTo plugin mentioned to register it kinda like scrollTrigger. Now I'm able to make it work

One more question, I understand why should I use gsap.ctx but is it always necessary? I'm also using gsap to animate my gltf animation in threejs  inside of eventlistner in react and there seems not to have any weird behavior?

https://github.com/experientia-in/experientia.in/blob/react/src/nasa-black-marble/comp/earth.jsx#L112-L117

Link to comment
Share on other sites

Hi,

 

GSAP Context is a way to easily cleanup when a component gets unmounted for example. If your component gets unmounted and GSAP is still running a Tween/Timeline that could lead to an error or a memory leak. It simplifies the process if you create a bunch of GSAP instances in your component, so you don't have to store them in an array, or a ref, or something like that in order to properly kill and revert them.

 

If your component NEVER gets unmounted during the lifecycle of your app, then yeah, you can rescind GSAP Context but we always suggest using it because of it's benefits and since it's footprint, like everything else in GSAP, is minimal and borderline unnoticeable.

 

Also keep in mind that you can add event listeners to GSAP Context and store said Context instance in a React ref:

const ctx = useRef();

useEffect(() => {
  ctx.current = gsap.context((self) => {
    // use any arbitrary string as a name; it'll be added to the Context object, so in this case you can call ctx.onClick() later...
    self.add("cameraTime", (t, d) => {
      gsap.to(actions["CameraAction.001"], {
        time: t,
        duration: d,
      }); // <-- gets added to the Context!
    });
  });
  return () => ctx.current.revert();
}, []);

Then you can use it like this:

scroll.addEventListener("end", () => {
  ctx.current.cameraTime(2, 2);
});

That being said, we only provide guidance and suggest best practices for our users, nothing more. If the way you're using GSAP now proves to be solid and works without any issues in your app, then go ahead, like I said, we aim that our users are capable and well versed in the tech stack they use in order to know how those different parts work and to get the best of them in every case.

 

Finally I'm curious about the fact that you have three different useEffect hooks with empty dependencies arrays. Any particular reason to not use a single one and run everything there?

 

Let us know if you have more questions.

 

Happy Tweening!

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