JSFiddle - React, Tailwind, and code Playground

by atesgoral

HTML

<button>A button</button>
<button>Another button</button>
<button>Last button</button>
<hr>
<table class="fancy-table">
  <colgroup span="4"></colgroup>
  <tr>
    <th>Countries</th>
    <th>Capitals</th>
    <th>Population</th>
    <th>Language</th>
  </tr>
  <tr>
    <td>USA</td>
    <td>Washington D.C.</td>
    <td>309 million</td>
    <td>English</td>
  </tr>
  <tr>
    <td>Sweden</td>
    <td>Stockholm</td>
    <td>9 million</td>
    <td>Swedish</td>
  </tr>
</table>

CSS

button:hover {
  -pow-color: orange;
  -pow-size: 2;
  -pow-style: random;
}
button:active {
  -pow-color: red;
  -pow-size: 3;
}
.fancy-table td:hover {
  background: blue;
  -pow-color: cyan;
  -pow-size: 2;
  -pow-style: linear;
  -pow-speed: 3;
}
body {
  background: black;
  margin: 0;
  padding: 20px;
}
button {
  border: none;
  background: brown;
  padding: 20px;
  color: white;
  font-size: 20px;
  cursor: pointer;
}
button:focus {
  outline: none;
}
.fancy-table td, .fancy-table th {
  color: white;
  background: navy;
  padding: 5px;
  font-family: sans-serif;
}

JavaScript

function Pow(el, props) {
  var powColor = props['-pow-color'] || '#fff';
  var powSize = parseFloat(props['-pow-size']) || 1;
  var powStyle = props['-pow-style'] || 'random';
  var powSpeed = parseFloat(props['-pow-speed']) || 1;
  
  var elBounds = el.getBoundingClientRect();
  var powBounds = {
    left: elBounds.left - powSize,
    top: elBounds.top - powSize,
    width: elBounds.width + powSize * 2,
    height: elBounds.height + powSize * 2
  };

  var canvas = document.createElement('canvas');
  var style = {
    position: 'absolute',
    zIndex: -1
  };

	for (var prop in powBounds) {
  	style[prop] = powBounds[prop] + 'px';
  }

  Object.assign(canvas.style, style);
    
  document.body.appendChild(canvas);
  
  var buffer = document.createElement('canvas');
  
  buffer.width = canvas.width = powBounds.width;
  buffer.height = canvas.height = powBounds.height;
  
  var ctx = canvas.getContext('2d');
  var bufferCtx = buffer.getContext('2d');
  
  var circ = (elBounds.width + elBounds.height) * 2;

  var render = function (t) {
  	callRender();
    
    bufferCtx.clearRect(0, 0, buffer.width, buffer.height);
    bufferCtx.globalAlpha = 0.95;
    bufferCtx.drawImage(canvas, 0, 0);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(buffer, 0, 0);
    
    var d = powStyle === 'linear'
    	? Math.floor(t / 10 * powSpeed) % circ
      : Math.random() * circ;
    var x = powSize;
    var y = powSize;
    
    if (d < elBounds.width) {
    	x += d;
    } else if (d < elBounds.width + elBounds.height) {
    	x += elBounds.width;
      y += d - elBounds.width;
    } else if (d < elBounds.width * 2 + elBounds.height) {
    	x += elBounds.width * 2 + elBounds.height - d;
      y += elBounds.height;
    } else {
    	y += elBounds.width * 2 + elBounds.height * 2 - d;
    }
    
    ctx.fillStyle = powColor;
    ctx.beginPath();
    ctx.arc(x, y, powSize, 0, 2 * Math.PI);
    ctx.fill();
  };
  
  function callRender() {
    if (render) {
 ...