2

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.

Jananath Banuka
  • 493
  • 3
  • 11
  • 22

1 Answers1

4

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>
  );
};
Józef Podlecki
  • 10,453
  • 5
  • 24
  • 50
  • Thank you for this, how can I use this same mechanism to for y axis? – Jananath Banuka Jun 23 '20 at 12:55
  • 1
    nvm found it. thank you :) But do you have any examples you did with `spring-react` that I could have a look? – Jananath Banuka Jun 23 '20 at 12:57
  • [There are codepen examples at the bottom of the page](https://www.react-spring.io/docs/hooks/use-spring) Most of the time they are using second overload for `useSpring` function and using `param.interpolate` function to reflect change as css value. Unfortunately documentation is scarce as you said. – Józef Podlecki Jun 23 '20 at 13:02
  • Thank you. Is there a way that can activate this effect only when I scroll some pixels? Let's say I want to activate this effect when I have already scrolled 200px or when I scroll down to some element. it is good if you can tell me a way to activate this if I scroll down to a particular element – Jananath Banuka Jun 23 '20 at 13:54
  • You have to manipulate that expression. `let ratio = window.scrollY / window.innerHeight;` a bit. For example it can be `let ratio = window.scrollY === 200 ? 1 : 0` – Józef Podlecki Jun 23 '20 at 14:36
  • When I do that, my react component is hidden. Can you update the answer with this implementation as well? – Jananath Banuka Jun 23 '20 at 14:46
  • Ah wait that was stupid. It should be `window.scrollY >= 200` . If you do `window.scrollY === 200` you have to extremely lucky to scroll at the exact height so it triggers it – Józef Podlecki Jun 23 '20 at 14:48
  • Sorry I don't understand. Can you update the code with the full `let ration = ......` part? – Jananath Banuka Jun 23 '20 at 15:02
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/216508/discussion-between-jozef-podlecki-and-jananath-banuka). – Józef Podlecki Jun 23 '20 at 15:40