Jananath Banuka
Jananath Banuka

Reputation: 633

How to properly move a React component from left to right using react-spring on scroll?

I have a div which contains an image and some text on it aligned to center

I need to make a transition with react-spring that when I scroll it should look like the text is coming from -x value to 0 and it has to be very smooth and real looking.

So I looked in to the react-spring documentation and they don't have a rich documentation on these kind of things. Only few examples.

For an example, how can I find other props for a scenario like this?

import {useTransition, animated} from 'react-spring'

const component = () => {

  const props = useSpring({opacity: 1, from: {opacity: 0}}) // how can I know other parameters like opcacity, from, to etc...

  return (
    <animated.div>
      {div contents here}
    </animated.div>
  )
}

And anyone to help me with the left-right transition where text come from left and lands at the center of the above mentioned image WHEN SCROLLING THROUGH?

Thank you.

Upvotes: 2

Views: 7877

Answers (1)

J&#243;zef Podlecki
J&#243;zef Podlecki

Reputation: 11283

I think you might be interested in translateX

from left and lands at the center of the above mentioned image

Combine the above with display: flex and align-items: center

Example

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { useSpring, animated } from "react-spring";

const style = {
  background: 'url("https://picsum.photos/200/300") center center / cover no-repeat',
  padding: '10px',
  width: '300px',
  height: '200px',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
}

const textStyle = {
  color: 'white',
  fontSize: '50px',
  background: 'black'
}

const App = props => {
  const [isLoaded, setLoaded] = useState(false);
  const springProps = useSpring({ 
    opacity: 1, 
    delay: 700,
    reset: isLoaded,
    transform: 'translateX(0px)',
    from: { 
      opacity: 0,
      transform: 'translateX(-250px)'
    } });

  useEffect(() => {
    fetch("https://picsum.photos/200/300")
      .then(pr => {
        setLoaded(true);
      })
  }, [])

  return <>{isLoaded ? <div style={style}>
        <animated.div style={{...textStyle, ...springProps}}>Some text</animated.div>
      </div> : <span></span>}</>
};

WHEN SCROLLING THROUGH?

In this case you would have to use second overload for useSpring, and use destructed set method to update values in onscroll callback

Example

const App = props => {
  const [isLoaded, setLoaded] = useState(false);
  const [{ param }, set] = useSpring(() => ({ param: 0 }));

  const onScroll = () => {
    let ratio = window.scrollY / window.innerHeight;
    ratio = ratio > 1 ? 1 : ratio;

    set({
      param: ratio
    });
  };

  useEffect(() => {
    window.addEventListener("scroll", onScroll);

    fetch("https://picsum.photos/200/300").then(pr => {
      setLoaded(true);
    });

    return () => {
      window.removeEventListener("scroll", onScroll);
    };
  }, []);

  return (
    <div style={containerStyle}>
      {isLoaded ? (
        <div style={style}>
          <animated.div
            style={{
              ...textStyle,
              opacity: param.interpolate({
                range: [0, 0.5, 0.75, 1],
                output: [0, 0.5, 0.75, 1]
              }),
              transform: param
                .interpolate({ range: [0, 0.5, 1], output: [-50, -25, 0] })
                .interpolate(x => `translateX(${x}px)`)
            }}
          >
            Some text
          </animated.div>
        </div>
      ) : (
        <span />
      )}
    </div>
  );
};

Upvotes: 4

Related Questions