Fig. 2 | Material Design Ripple

In this example below you will see how to do a Fig. 2 | Material Design Ripple with some HTML / CSS and Javascript

For a blogpost: Material Design Ripple

Thumbnail
This awesome code was written by , you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright ⁣ ©
  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Fig. 2 | Material Design Ripple</title>
  
  
  <link rel='stylesheet prefetch' href='css/https___codepen_io_pixela.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <span class="wire" id="bound">Area</span>
  
  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/pixelass/fig-2-or-material-design-ripple-YXbNJd */
body {
  margin: 50px;
  font-family: sans-serif;
  background: #424242;
}

.wire {
  display: block;
  width: 10em;
  height: 10em;
  box-shadow: 0 0 0 2px;
  font-size: 20px;
  line-height: 10em;
  margin: -5em;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  text-align: center;
  border: 0;
  background: white;
  overflow: hidden;
}

.tracker {
  background: rgba(0, 0, 0, 0.3);
  height: 20px;
  width: 20px;
  border-radius: 100%;
  pointer-events: none;
  -webkit-animation: scale-in .4s ease-in-out;
          animation: scale-in .4s ease-in-out;
  transition: opacity .4s .2s ease-out;
}

@-webkit-keyframes scale-in {
  from {
    -webkit-transform: translate(-50%, -50%) scale(0);
            transform: translate(-50%, -50%) scale(0);
  }
  to {
    -webkit-transform: translate(-50%, -50%) scale(1);
            transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes scale-in {
  from {
    -webkit-transform: translate(-50%, -50%) scale(0);
            transform: translate(-50%, -50%) scale(0);
  }
  to {
    -webkit-transform: translate(-50%, -50%) scale(1);
            transform: translate(-50%, -50%) scale(1);
  }
}


/*Downloaded from https://www.codeseek.co/pixelass/fig-2-or-material-design-ripple-YXbNJd */
// the bounding box
var bound = document.getElementById('bound');
// listen to events
bound.addEventListener('mousedown', appendRipple);
bound.addEventListener('mouseup', removeRipple);

// flag to track animations
var animating;
var blocked;
// make tracker global
var tracker;

/**
 * handle the animation end of the growing ripple
 * @prop {Event} event  The event that triggered the action
 * @return              no return
 **/
function endIn(event) {
  // clear animation flag
  animating = false;
  event.target.removeEventListener('animationend', endIn);
}

/**
 * start the process of removing the ripple
 * @prop {Event} event  The event that triggered the action
 * @return              no return
 **/
function startOut(event) {
  // clear animation flag
  animating = true;
  // if the trigger was an event we need to clear the listener
  if (event) {
    event.target.removeEventListener('animationend', startOut);
  }
  tracker.style.opacity = 0;
  // add a new listener
  tracker.addEventListener('transitionend', removeFromDOM);
}

/**
 * removes the element from the DOM tree
 * @prop {Event} event  The event that triggered the action
 * @return              no return
 **/
function removeFromDOM(event) {
  // clear animation and blocked flag
  animating = false;
  blocked = false;
  event.target.removeEventListener('transitionend', removeFromDOM);
  event.target.remove();
}

/**
 * append a ripple to a clicked area
 * @prop {Event} event  The event that triggered the action
 * @return              no return
 **/
function appendRipple(event) {
  // don't proceed until the last ripple has been removed
  if (blocked) {
    return;
  }
  blocked = true;
  // get event coordinates
  var y = event.layerY;
  var x = event.layerX;
  // get event dimensions
  var w = event.target.offsetWidth;
  var h = event.target.offsetHeight;
  // get offset
  var offsetX = Math.abs(w / 2 - x);
  var offsetY = Math.abs(h / 2 - y);
  // get delta
  var deltaX = w / 2 + offsetX;
  var deltaY = h / 2 + offsetY;
  // calculate size
  var size = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2) - 2 * deltaX * deltaY * Math.cos(90 / 180 * Math.PI)) * 2;

  // create an element
  tracker = document.createElement('div');
  // position it
  tracker.classList.add('tracker');
  tracker.style.position = 'absolute';
  tracker.style.transform = 'translate(-50%,-50%)';
  tracker.style.left = x + 'px';
  tracker.style.top = y + 'px';
  tracker.style.height = size + 'px';
  tracker.style.width = size + 'px';

  // handle animation tracking
  animating = true;
  tracker.addEventListener('animationend', endIn);
  // append it to the event.target
  event.target.appendChild(tracker);
}

/**
 * remove a ripple from a clicked area
 * @prop {Event} event  The event that triggered the action
 * @return              no return
 **/
function removeRipple(event) {
  var ripple = event.target.querySelector('div');
  if (ripple) {
    if (animating) {
      // if the ripple is still animating we need to wait
      tracker.addEventListener('animationend', startOut);
    } else {
      // otherwise we can start removing the ripple
      startOut();
    }
  }
}

Comments