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.