<hgroup>
<h1>Ripple</h1>
<h2>using animation.api</h2>
</hgroup>
<button>click me</button>
<p></p>
<button class=secondary>click me</button>
<p></p>
<button class=contrast>click me</button>
body{
width:300px;
margin: 0 auto;
text-align: center;
}
h1{
font-weight:400;
text-align:center;
}
h2{
text-align:center;
font-weight:500;
}
button{
position:relative;
width:200px;
font-weight:400;
text-transform: uppercase;
margin:0 auto;
box-shadow: 2px 3px 4px rgba(0,0,0,0.4);
transition: all 200ms ease;
}
button:active{
box-shadow:none;
}
"use strict";
function rippleEffect ( evt ) {
let offset = this.getBoundingClientRect(),
ripple = document.createElement( 'div' ),
aktOverflow = getComputedStyle( this ).overflow,
light = `rgba(255,255,255,0)`,
dark = `rgba(255,255,255,.3)`,
scale = Math.sqrt(
( offset.width*offset.width ) +
( offset.height*offset.height ) )/10;
this.style.overflow = 'hidden';
ripple.style = `
width:20px;
height:20px;
border-radius: 50%;
background: radial-gradient(circle,
${dark} 0%, ${light} 5%, ${light} 7%,
${dark} 13%, ${dark} 17%, ${light} 30%,
${light} 35%, ${dark} 51%,${dark} 58%,
${light} 68%, ${light} 75%, ${dark} 100%);
position: absolute;
opacity: 0;
transform-origin: 'center center';
left: ${evt.clientX - offset.left -10}px;
top: ${evt.clientY - offset.top -10}px;`
this.prepend( ripple );
let rippleAni = ripple.animate( [
{ transform: 'scale(0)', opacity:1 },
{ transform: `scale(${scale})`, opacity: .1 }
],
{ duration: 600}
);
Promise.resolve( rippleAni.finished )
.then( () => {
ripple.remove();
this.style.overflow=aktOverflow;
}
);
}
document.querySelectorAll( 'button' ).forEach(
el => el.addEventListener( 'mousedown', rippleEffect )
)
document.querySelectorAll( 'button' ).forEach(
el => el.addEventListener( 'click', ()=>console.log('click') )
)
This Pen doesn't use any external JavaScript resources.