Skip to content

Instantly share code, notes, and snippets.

@clqu
Created November 6, 2022 18:55
Show Gist options
  • Save clqu/0130cd9246cbf41e893210df11cf177f to your computer and use it in GitHub Desktop.
Save clqu/0130cd9246cbf41e893210df11cf177f to your computer and use it in GitHub Desktop.
React Ripple
.ripple {
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.1), transparent);
opacity: 0;
margin-top: -50px;
margin-left: -50px;
}
@keyframes ripple {
0% {
opacity: 1;
transform: scale(0, 0);
}
100% {
opacity: 0;
transform: scale(10);
}
}
import Ripple from "./Ripple";
export default function Index() {
return <Ripple as="div" className="w-72 h-72 bg-zinc-500">
Text
</Ripple>
}
import { useRef, useEffect } from "react";
import classNames from "classnames";
export default function Ripple({ as, children, className, ...props }) {
const rippleRef = useRef(null);
useEffect(() => {
const ripple = (e) => {
const ripple = document.createElement("span");
ripple.classList.add("ripple");
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
let scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
ripple.style.left = `${e.clientX - rippleRef.current.offsetLeft + scrollLeft}px`;
ripple.style.top = `${e.clientY - rippleRef.current.offsetTop + scrollTop}px`;
ripple.style.transition = "all 0.5s ease-in-out";
ripple.style.animation = "ripple 0.6s ease-in-out";
if (e.target.tagName !== "BUTTON") {
rippleRef.current.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 1000);
}
};
rippleRef.current?.addEventListener("click", ripple);
return () => {
rippleRef.current?.removeEventListener("click", ripple);
};
}, [rippleRef]);
const Element = as || "div";
return (
<Element ref={rippleRef} className={classNames("w-full relative h-full overflow-hidden", className)} {...props}>
{children}
</Element>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment