DEV Community

Cover image for Ripple Effect using JS animation api
Frank Wisniewski
Frank Wisniewski

Posted on

3 1

Ripple Effect using JS animation api

see comments in Source Code

<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <title>Ripple sample</title>
  <!-- 
    Pico.css • Minimal CSS Framework for semantic HTML
  -->
  <link rel="stylesheet"
    href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
  <style>
    h1{
      font-weight:400;
      text-align:center;
    }
    h2{
      text-align:center;
      font-weight:500;
    }
    button{
      /*
        it is important to use position: relative
      */
      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;
    }
  </style>

</head>
<body class=container>

  <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>

<script>
  "use strict";

  function rippleEffect ( evt ) {
    // get Coordinates from current Button
    let offset = this.getBoundingClientRect(), 
        // create the ripple div
        ripple = document.createElement( 'div' ),
        // save the overflow style from current Button
        aktOverflow = getComputedStyle( this ).overflow,
        // set colors for ripple
        light = `rgba(255,255,255,0)`,
        dark =  `rgba(255,255,255,.3)`,
        // calc the diagonal width from element
        scale = Math.sqrt( 
          ( offset.width*offset.width ) + 
          ( offset.height*offset.height ) )/10;
    // set overflow Button 
    this.style.overflow = 'hidden';
    // style the ripple Element
    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;`
    // inject ripple in button
    this.prepend( ripple );
    // create the animate object
    let rippleAni = ripple.animate( [
        { transform: 'scale(0)', opacity:1 },
        { transform: `scale(${scale})`, opacity: .1 }
      ],
      { duration: 600}
    );
    // kill the ripple when animation finished
    Promise.resolve( rippleAni.finished )
      .then( () => { 
        ripple.remove();
        this.style.overflow=aktOverflow;
        }
      );
  }

  document.querySelectorAll( 'button' ).forEach( 
      el => el.addEventListener( 'click', rippleEffect )
  )

</script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

TRY IT

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay