Skip to content

Instantly share code, notes, and snippets.

@DavideGalilei
Created December 16, 2023 17:48
Show Gist options
  • Save DavideGalilei/52c9d65ef39a851b27a0d67ac4a2dba2 to your computer and use it in GitHub Desktop.
Save DavideGalilei/52c9d65ef39a851b27a0d67ac4a2dba2 to your computer and use it in GitHub Desktop.
Lite Ripple.js Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ripple</title>
</head>
<body>
<style>
button {
--ripple-color: rgba(0, 0, 120, .2);
background-color: lightblue;
box-shadow: 0 0 1rem rgba(0, 0, 0, .2);
border: none;
padding: .7rem;
font-size: 1rem;
border-radius: .4rem;
transition: box-shadow .3s ease-out;
}
button:hover {
box-shadow: 0 0 1rem rgba(0, 0, 0, .5);
}
[data-ripple] {
position: relative;
cursor: pointer;
overflow: hidden;
}
.ripple-circle {
position: absolute;
background-color: var(--ripple-color, rgba(0, 0, 0, .2));
z-index: 9999;
border-radius: 50%;
width: var(--ripple-radius);
height: var(--ripple-radius);
pointer-events: none;
transform-origin: center;
}
</style>
<button data-ripple>Click AAAAAAAAAAAAAAAAAAA</button>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<div data-ripple>a</div>
<script>
/**
* @type {HTMLElement[]}
*/
const buttons = document.querySelectorAll('[data-ripple]');
function handler(e) {
const button = e.currentTarget;
const circle = document.createElement("span");
circle.classList.add("ripple-circle");
circle.style.top = `${e.offsetY}px`;
circle.style.left = `${e.offsetX}px`;
button.appendChild(circle);
// Get the distance to the furthest corner
const endRadius = Math.hypot(
Math.max(e.offsetX, button.offsetWidth - e.offsetX),
Math.max(e.offsetY, button.offsetHeight - e.offsetY),
);
circle.style.setProperty("--ripple-radius", `${endRadius}px`);
const animation = circle.animate([
{
transform: `translate(-50%, -50%) scale(0)`,
opacity: 1,
},
{
transform: `translate(-50%, -50%) scale(2)`,
opacity: 0,
},
], {
duration: 500,
easing: "ease-out",
fill: "forwards",
});
animation.addEventListener("finish", () => {
circle.remove();
});
animation.addEventListener("cancel", () => {
circle.remove();
});
}
buttons.forEach(button => {
button.addEventListener("pointerenter", handler);
button.addEventListener("click", handler);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment