JSFiddle - React, Tailwind, and code Playground

by riyadh

HTML

<header>
  <h1>ripple</h1>
</header>
<div class="content">
  <button ripple="ripple">Fail</button>
  <button ripple="ripple">Info</button>
  <button ripple="ripple">Save</button>
</div>

CSS

button {
  background-color:#000;
  color:#fff;
}
body {
  color: #777;
  text-align: center;
  padding: 0 0 0 0;
  margin: 0 0 0 0;
}

[ripple] {
  position: relative;
  overflow: hidden;
}
[ripple] .ripple--container {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
[ripple] .ripple--container span {
  transform: scale(0);
  border-radius: 100%;
  position: absolute;
  opacity: 0.75;
  background-color: #fff;
  animation: ripple 1000ms;
}
@-moz-keyframes ripple {
  to {
    opacity: 0;
    transform: scale(2);
  }
}
@-webkit-keyframes ripple {
  to {
    opacity: 0;
    transform: scale(2);
  }
}
@-o-keyframes ripple {
  to {
    opacity: 0;
    transform: scale(2);
  }
}
@keyframes ripple {
  to {
    opacity: 0;
    transform: scale(2);
  }
}

JavaScript

(function() { var cleanUp, debounce, i, len, ripple, rippleContainer, ripples, showRipple;

debounce = function(func, delay) {
  var inDebounce;
  inDebounce = undefined;
  return function() {
    var args, context;
    context = this;
    args = arguments;
    clearTimeout(inDebounce);
    return inDebounce = setTimeout(function() {
      return func.apply(context, args);
    }, delay);
  };
};

showRipple = function(e) {
  var pos, ripple, rippler, size, style, x, y;
  ripple = this;
  rippler = document.createElement('span');
  size = ripple.offsetWidth;
  pos = ripple.getBoundingClientRect();
  x = e.pageX - pos.left - (size / 2);
  y = e.pageY - pos.top - (size / 2);
  style = 'top:' + y + 'px; left: ' + x + 'px; height: ' + size + 'px; width: ' + size + 'px;';
  ripple.rippleContainer.appendChild(rippler);
  return rippler.setAttribute('style', style);
};

cleanUp = function() {
  while (this.rippleContainer.firstChild) {
    this.rippleContainer.removeChild(this.rippleContainer.firstChild);
  }
};

ripples = document.querySelectorAll('[ripple]');

for (i = 0, len = ripples.length; i < len; i++) {
  ripple = ripples[i];
  rippleContainer = document.createElement('div');
  rippleContainer.className = 'ripple--container';
  ripple.addEventListener('mousedown', showRipple);
  ripple.addEventListener('mouseup', debounce(cleanUp, 2000));
  ripple.rippleContainer = rippleContainer;
  ripple.appendChild(rippleContainer);
}
 }());