JSFiddle - React, Tailwind, and code Playground
by caub
HTML
<button id="butt">
Test butt
</button>
CSS
* {box-sizing: border-box;}
button > span {
border-radius: 50%;
position: absolute;
width: calc(2px*var(--ripple-radius));
height: calc(2px*var(--ripple-radius));
display: inline-block;
opacity: 0.66;
-webkit-user-select: none;
user-select: none;
pointer-events: none;
}
button {
height: 2em;
font-size: 1.5em;
margin: 1em;
border-radius: 2px;
border: none;
outline: none;
transition: all .2s ease-in-out;
overflow: hidden;
white-space: nowrap;
position:relative;
cursor: pointer;
-webkit-user-select: none;
user-select: none;
}
button {
box-shadow: 0 4px 6px rgba(7,7,7, 0.19),
0 3px 3px rgba(7,7,7, 0.23);
}
button:active {
box-shadow: 0 0px 1px rgba(7,7,7, 0.19),
0 1px 1px rgba(7,7,7, 0.23);
}
JavaScript
var duration = 1000, radius = 100;
document.body.style.setProperty('--ripple-radius', radius);
const ripple = e=>{
const {left, top} = e.currentTarget.getBoundingClientRect();
var d = e.currentTarget.appendChild(document.createElement('span'));
//console.log(e.clientX-left, e.clientY-top-50)
Object.assign(d.style, {
left:e.clientX-left-radius+'px',
top:e.clientY-top-radius+'px',
backgroundColor: `hsla(${10*Math.random()+200}, 30%, 70%, .7)`
});
d.animate([
{transform: 'scale(0)'},
{transform: 'scale(1)'},
], {
duration: duration,
easing: 'cubic-bezier(.22,.67,.52,.92)',
fill: 'forwards',
});
const up = e=>{
document.removeEventListener('mouseup', up);
const opacity = d.animate([
{opacity: 0.66},
{opacity: 0},
], {
duration,
fill: 'forwards',
});
opacity.onfinish = ()=> {
d.remove();
};
}
document.addEventListener('mouseup', up);
}
butt.onmousedown = e=>{
ripple(e);
}