Button with Ripple Effect

ReactReactBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we will learn how to create a button with a ripple effect animation using React. The purpose of this lab is to help you understand how to use React hooks, such as useState() and useEffect(), to manage the state of the button and trigger the animation. By the end of this lab, you will be able to create interactive and visually appealing buttons for your React applications.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL react(("`React`")) -.-> react/FundamentalsGroup(["`Fundamentals`"]) react(("`React`")) -.-> react/AdvancedConceptsGroup(["`Advanced Concepts`"]) react(("`React`")) -.-> react/StateManagementGroup(["`State Management`"]) react(("`React`")) -.-> react/StylingGroup(["`Styling`"]) react/FundamentalsGroup -.-> react/jsx("`JSX`") react/FundamentalsGroup -.-> react/event_handling("`Handling Events`") react/AdvancedConceptsGroup -.-> react/hooks("`React Hooks`") react/StateManagementGroup -.-> react/use_state_reducer("`Using useState and useReducer`") react/StylingGroup -.-> react/css_in_react("`CSS in React`") subgraph Lab Skills react/jsx -.-> lab-38359{{"`Button with Ripple Effect`"}} react/event_handling -.-> lab-38359{{"`Button with Ripple Effect`"}} react/hooks -.-> lab-38359{{"`Button with Ripple Effect`"}} react/use_state_reducer -.-> lab-38359{{"`Button with Ripple Effect`"}} react/css_in_react -.-> lab-38359{{"`Button with Ripple Effect`"}} end

Button With Ripple Effect

index.html and script.js have already been provided in the VM. In general, you only need to add code to script.js and style.css.

This code renders a button component that creates a rippling effect when clicked. Here's how it works:

  • The useState() hook is used to create two state variables: coords and isRippling. The coords variable stores the pointer's coordinates, while isRippling stores the animation state of the button.
  • A useEffect() hook is used to change the value of isRippling every time the coords state variable changes. This starts the animation of the rippling effect.
  • setTimeout() is used in the previous hook to clear the animation after it's done playing.
  • Another useEffect() hook is used to reset coords whenever the isRippling state variable is false.
  • The onClick event is handled by updating the coords state variable and calling the passed callback function.

Here's the code for the RippleButton component:

const RippleButton = ({ children, onClick }) => {
  const [coords, setCoords] = React.useState({ x: -1, y: -1 });
  const [isRippling, setIsRippling] = React.useState(false);

  React.useEffect(() => {
    if (coords.x !== -1 && coords.y !== -1) {
      setIsRippling(true);
      setTimeout(() => setIsRippling(false), 300);
    } else setIsRippling(false);
  }, [coords]);

  React.useEffect(() => {
    if (!isRippling) setCoords({ x: -1, y: -1 });
  }, [isRippling]);

  return (
    <button
      className="ripple-button"
      onClick={(e) => {
        const rect = e.target.getBoundingClientRect();
        setCoords({ x: e.clientX - rect.left, y: e.clientY - rect.top });
        onClick && onClick(e);
      }}
    >
      {isRippling && (
        <span
          className="ripple"
          style={{
            left: coords.x,
            top: coords.y
          }}
        />
      )}
      <span className="content">{children}</span>
    </button>
  );
};

You can use this component like this:

ReactDOM.createRoot(document.getElementById("root")).render(
  <RippleButton onClick={(e) => console.log(e)}>Click me</RippleButton>
);

And here's the CSS for the RippleButton component:

.ripple-button {
  border-radius: 4px;
  border: none;
  margin: 8px;
  padding: 14px 24px;
  background: #1976d2;
  color: #fff;
  overflow: hidden;
  position: relative;
  cursor: pointer;
}

.ripple-button > .ripple {
  width: 20px;
  height: 20px;
  position: absolute;
  background: #63a4ff;
  display: block;
  content: "";
  border-radius: 9999px;
  opacity: 1;
  animation: 0.9s ease 1 forwards ripple-effect;
}

@keyframes ripple-effect {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(10);
    opacity: 0.375;
  }
  100% {
    transform: scale(35);
    opacity: 0;
  }
}

.ripple-button > .content {
  position: relative;
  z-index: 2;
}

Please click on 'Go Live' in the bottom right corner to run the web service on port 8080. Then, you can refresh the Web 8080 Tab to preview the web page.

Summary

Congratulations! You have completed the Button With Ripple Effect lab. You can practice more labs in LabEx to improve your skills.

Other React Tutorials you may like