Search code examples
cssreactjsreact-spring

How To Transition React Elements That Already Have An Animation


I need some help merging an animation and a transition that occur at different times using react-spring.

When the component is mounted using useSpring I make the component appear, but I would like it so that when the button child is removed the container transitions smoothly upwards. Theres more details in the example.

https://codesandbox.io/s/naughty-dawn-r0e5x

PLEASE HELP :)


Solution

  • I created a solution. There is a new Spring animation mainly for the button, but we can use part of it for the original div. In this case the maxHeight property. So this way you can combine the animations.

    import ReactDOM from "react-dom";
    import React, { useState } from "react";
    import { useSpring, animated } from "react-spring";
    
    function WelcomeMessage() {
      const [isStarted, setIsStarted] = useState(false);
    
      const animation1 = useSpring({
        right: "1%",
        opacity: 1,
        from: { right: "-20%", opacity: 0 },
        delay: 300
      });
    
      const animation2 = useSpring({
        opacity: isStarted ? 0 : 1,
        maxHeight: isStarted ? 150 : 250,
        transform: `translateY(${isStarted ? "-50px" : "0px"})`
      });
    
      return (
        <animated.div
          style={{
            backgroundColor: "pink",
            position: "fixed",
            top: "2%",
            right: "1%",
            cursor: "default",
            borderRadius: 5,
            width: "90%",
            maxWidth: 400,
            ...animation1,
            maxHeight: animation2.maxHeight
          }}
        >
          <div style={{ padding: "15px 25px" }}>
            <span>
              This is a toaster notification component. When you click the following
              button it should disappear and the pink container's bottom section
              should transition upwards when it decreases in height.
            </span>
            <br />
            <br />
            {
              <animated.button
                style={{ width: "100%", fontSize: 48, ...animation2 }}
                onClick={() => {
                  setIsStarted(true);
                }}
              >
                Get Started
              </animated.button>
            }
          </div>
        </animated.div>
      );
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<WelcomeMessage />, rootElement);
    

    Here is the example: https://codesandbox.io/s/green-star-nzfj8 Is this answer your question?