Skip to content

Instantly share code, notes, and snippets.

@droduit
Last active August 21, 2023 08:44
Show Gist options
  • Save droduit/2df1e0ea6abc9fbe289977b853f44a50 to your computer and use it in GitHub Desktop.
Save droduit/2df1e0ea6abc9fbe289977b853f44a50 to your computer and use it in GitHub Desktop.
Material Ripple Effect (touch + mouse)
[ripple] {
position: relative;
.ripple-container {
top: 0; left:0; right: 0; bottom: 0;
position: absolute;
overflow: hidden;
border-radius: inherit;
}
span.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
animation: ripple 600ms linear;
background-color: rgba(0, 0, 0, .15);
}
}
@keyframes ripple {
to {
transform: scale(2);
opacity: 0;
}
}
function createRipple(event) {
const component = event.currentTarget;
const circle = document.createElement("span");
const diameter = Math.max(component.offsetWidth, component.offsetHeight);
const radius = diameter / 2;
const pos = component.getBoundingClientRect();
const { clientX, clientY } = (event.changedTouches && event.changedTouches.length > 0) ? event.changedTouches[0] : event;
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${clientX - (pos.left + radius)}px`;
circle.style.top = `${clientY - (pos.top + radius)}px`;
circle.classList.add("ripple");
component.querySelector(".ripple-container").appendChild(circle);
}
function cleanUp(component) {
const firstRipple = component.querySelector(".ripple-container").getElementsByClassName("ripple")[0];
if (firstRipple) {
firstRipple.remove();
}
}
export function attachRippleEffect(selector) {
const hasTouchEvents = ('ontouchstart' in window);
const rippleContainers = document.querySelectorAll(selector);
for (const rippleContainer of rippleContainers) {
const innerContainer = document.createElement('div');
innerContainer.className = 'ripple-container';
rippleContainer.addEventListener("touchstart", createRipple, false);
rippleContainer.addEventListener("mousedown", function(e) {
if (!hasTouchEvents) {
createRipple(e);
}
}, false);
rippleContainer.addEventListener("animationend", () => cleanUp(rippleContainer), false);
rippleContainer.appendChild(innerContainer);
}
}
<script>
document.addEventListener('DOMContentLoaded', function() {
attachRippleEffect('[ripple]');
});
</script>
<button ripple>Ripple effect Demo</button>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment