cssreactjs

How to prevent animation reset when div changes?


I have a parent div, which have button "show details". Here is how it works: when it pressed -> bool changes -> details showing up.

Code is something like this: (instead of blabla is huge div)

import React, { useState, useCallback } from 'react';

function Page() {
  const [showDetails, setShowDetails] = useState(true);

  const PurchaseComponent = () => {
    const toggleDetails = useCallback(() => {
      setShowDetails(prevShowDetails => !prevShowDetails);
    }, []);

    return (
        <div className="mydiv">
            <button onClick={toggleDetails}>
              Show Details
            </button>
            {showDetails && (
              <div>BlaBla</div>
            )}
        </div>
    );
  };

  return (
    <div>
        <PurchaseComponent />
    </div>
  );
}

export default Page;

CSS:

.mydiv {
    min-height: 250px;
    width: 800px;
    border-radius: 10px;
    padding: 50px;
    margin-bottom: 20px;
    background: linear-gradient(45deg, #4d474f, #282f32, #371211, #7d1416, #850b0f, #40080a, #850b0f, #7d1416, #371211, #282f32, #4d474f);
    background-size: 2200% 2200%;

    -webkit-animation: AnimationName 51s ease infinite;
    animation: AnimationName 51s ease infinite;
    transition: transform 2s ease;
  }
  

  @-webkit-keyframes AnimationName {
    0%{background-position:0% 96%}
    50%{background-position:100% 5%}
    100%{background-position:0% 96%}
  }
  @keyframes AnimationName {
    0%{background-position:0% 96%}
    50%{background-position:100% 5%}
    100%{background-position:0% 96%}
  }

Parent have an animated background made with gradient animator. All I want it to not restart when details button is pressed (childs updating). Size of parent div changes when button pressed.


Solution

  • The animation restarts if the animated div's parent rerenders. You can simply move the animated div to a wrapper component.

    Codesandbox

    function AnimatedCard({ children }) {
      return <div className="mydiv">{children}</div>;
    }
    
    function Page() {
      const [showDetails, setShowDetails] = useState(true);
    
      const PurchaseComponent = () => {
        const toggleDetails = useCallback(() => {
          setShowDetails((prevShowDetails) => !prevShowDetails);
        }, []);
    
        return (
          <>
            <button onClick={toggleDetails}>Show Details</button>
            {showDetails && <div>BlaBla</div>}
          </>
        );
      };
    
      return (
        <AnimatedCard>
          <PurchaseComponent />
        </AnimatedCard>
      );
    }
    
    export default Page;