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.
Button With Ripple Effect
index.htmlandscript.jshave already been provided in the VM. In general, you only need to add code toscript.jsandstyle.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:coordsandisRippling. Thecoordsvariable stores the pointer's coordinates, whileisRipplingstores the animation state of the button. - A
useEffect()hook is used to change the value ofisRipplingevery time thecoordsstate 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 resetcoordswhenever theisRipplingstate variable isfalse. - The
onClickevent is handled by updating thecoordsstate 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.