Jump to content
Search Community

Problem with the onWheel animation

LucieB test
Moderator Tag

Recommended Posts

Hey, I'm Lucie and I'm new on GSAP forums. So glad to be part of the GSAP community ! 😃

 

I met a tiny problem about my onWheel animation, made with React.

I don't know how to resolve this, so I decided to create a new topic on the forum.

 

I made a Codesandbox (sorry, I don't know how to use CodePen with React).

My problem : When I use my wheel, i just want to create an animation.

But actually, the animation starts over and over, even if I used the isActive method.

Here's the preview of my problem.

 

Thanks guys and take care! 😃

 

 

Link to comment
Share on other sites

 

1 hour ago, elegantseagulls said:

Hi @LucieB

 

I just had a quick glance, but it looks to me that part of the issue is that you are re-creating the timeline every time you onWheel. You may want to create a ref for your timeline, then set the timeline using useCallback, then use the onWheel to tl.current.play(); the animation.  

 

Hi ! I'm sorry, I didn't understand what you mean. Can you explain ? Thanks

Link to comment
Share on other sites

3 hours ago, LucieB said:

Can you explain ?

import React, { useRef, useCallback } from "react";
import { gsap } from "gsap";
import "./styles.css";

export default function App() {

  const tl = useRef();
  const tlr = useRef();

  const el = useCallback((node) => {
    if (!node) return;

      const squareBlue = node.children[0];
      const squareRed = node.children[1];
      const squareYellow = node.children[2];
      const squareGreen = node.children[3];

      tl.current = new gsap.timeline({ paused: true });
      tlr.current = new gsap.timeline({ paused: true });


      tl.current.to(
        [squareBlue, squareRed, squareYellow, squareGreen],
        { y: '50%', duration: 1, stagger: { amount: 0.2 } }
      );

      tlr.current.to(
          [squareBlue, squareRed, squareYellow, squareGreen],
          { y: '-50%', duration: 1, stagger: { amount: 0.2 } }
        );
    
  },[]) 

  // let squaresRef = useRef(null);

  const animate = e => {
    

    if (e.deltaY < 0) {

      if (!tl.current.isActive()) {
        console.log('up')
        tlr.current.invalidate();
        tl.current.invalidate();
        tl.current.play(0);
      
      }
    } 
    else if (e.deltaY > 0) {

      if (!tlr.current.isActive()) {
        console.log('down')
        tl.current.invalidate();
        tlr.current.invalidate();
        tlr.current.play(0);
        
      }
    }
  };

  return (
    <div className="App" onWheel={animate}>
      <h1>Just scroll in the window.</h1>
      <div className="squares" ref={el}>
        <div className="sq blue" />
        <div className="sq red" />
        <div className="sq yellow" />
        <div className="sq green" />
      </div>
    </div>
  );
}

 

With the setup above you're just defining each timeline once, in your useCallback function, rather than on each mousewheel event.

For this, I had to invalidate, or it'd get a jumpy on direction change. Hope this is helpful. If I have more time later, I'll try to provide more of an explaination.

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