jscottsmith / react-scroll-parallax

🔮 React hooks and components to create parallax scroll effects for banners, images or any other DOM elements.
https://react-scroll-parallax.damnthat.tv/
MIT License
2.9k stars 158 forks source link

Update props of parallax element #226

Closed mephistia closed 1 year ago

mephistia commented 1 year ago

Hi! I'm loving this lib, but I'm having trouble trying to update the props of a parallax element based on window width. I want the same element to have a different animation if it is rendered at a mobile screen size.

Here's the CodeSandbox with what I've tried already.

In the above example, I'm setting the initial parallax props as scale: [1, 2], and I want to update the props to be scale: [2, 1] if the window is less than 769px wide.

The docs mention a updateElementPropsById method in the ParallaxController object. But I'm not sure where that id comes from. I've tried using ref.current?.id but the hook doesn't seem to set an id for the referred element. I've also tried manually setting up an id for the element, but it didn't work. I'm confused since the id param expects a number, but the HTML id attribute type is string.

Looking forward for a solution!

mephistia commented 1 year ago

I believe I've figured it out:

const parallaxElements = parallaxController?.getElements();

const refId = parallaxElements?.find((entry) => entry.el.isEqualNode(ref.current))?.id || 0;

parallaxController?.updateElementPropsById(refId, newProps);

But it would be nice to update the docs informing where does this id come from

jscottsmith commented 1 year ago

@mephistia

There's no need to do all this extra work. Just use the tools React gives you to pass in new values to the useParallax hook. It will do all this updating for you automatically.

See the example below, which adds an isMobile state which is then updated by the resize event listener. If isMobile is true, we pass a different set of scale values to the parallax hook.


function Example() {
  const [isMobile, setIsMobile] = useState(false);

  const { ref } = useParallax<HTMLDivElement>({
    // change any values based on React state
    scale: isMobile ? [2, 1] : [1, 2]
  });

  function handleResize() {
    if (window.innerWidth < MOBILE_MAX_WIDTH) {
      setIsMobile(true);
    } else {
      setIsMobile(false);
    }
  }

  useEffect(() => {
    window.addEventListener("resize", handleResize);
    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);

  return (
    <div className="parallax-element" ref={ref}>
  );
}

Here's the working CodeSandbox using the code example above.

Hope that helps.