<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title></title>
</head>
<body>
<div id="admin">
<div id="btn"></div>
</div>
<script type="text/javascript">
document.querySelector("#btn").onmousedown = function (event) {
const container = this;
const { x, y, centerX, centerY, size } = computeRippleStyles(
container,
event
);
console.log(x, y, centerX, centerY, size);
const ripple = document.createElement("div");
ripple.classList.add("my-ripple");
ripple.style.opacity = `0`;
ripple.style.transform = `translate(${x}px, ${y}px) scale3d(.3, .3, .3)`;
ripple.style.width = `${size}px`;
ripple.style.height = `${size}px`;
ripple.dataset.createdAt = String(performance.now());
const { position } = window.getComputedStyle(container);
container.style.overflow = "hidden";
position === "static" && (this.style.position = "relative");
console.log(ripple);
container.appendChild(ripple);
window.setTimeout(() => {
ripple.style.transform = `translate(${centerX}px, ${centerY}px) scale3d(1, 1, 1)`;
ripple.style.opacity = `.25`;
});
};
document.querySelector("#btn").onmouseup = function (event) {
const container = this;
const ripples = container.querySelectorAll(".my-ripple");
if (!ripples.length) {
return;
}
const lastRipple = ripples[ripples.length - 1];
const delay =
300 - performance.now() + Number(lastRipple.dataset.createdAt);
setTimeout(() => {
lastRipple.style.opacity = `0`;
setTimeout(() => lastRipple.parentNode?.removeChild(lastRipple), 300);
}, delay);
}
function computeRippleStyles(element, event) {
const { top, left } = element.getBoundingClientRect();
const { clientWidth, clientHeight } = element;
const radius = Math.sqrt(clientWidth ** 2 + clientHeight ** 2) / 2;
const size = radius * 2;
console.log(top, left, clientWidth, clientHeight, size);
const localX = event.clientX - left;
const localY = event.clientY - top;
const centerX = (clientWidth - radius * 2) / 2;
const centerY = (clientHeight - radius * 2) / 2;
const x = localX - radius;
const y = localY - radius;
return { x, y, centerX, centerY, size };
}
</script>
</body>
<style>
#btn {
margin: 30px 40px;
width: 80px;
height: 60px;
border: 1px solid black;
}
.my-ripple {
position: absolute;
top: 0;
left: 0;
z-index: 100;
border-radius: 50%;
background-color: currentColor;
opacity: 0;
transition: transform 0.2s cubic-bezier(0.68, 0.01, 0.62, 0.6),
opacity 0.08s linear;
will-change: transform, opacity;
pointer-events: none;
}
</style>
</html>