JSFiddle - React, Tailwind, and code Playground

by RadCor

HTML

<script src="https://s3.us-east-2.amazonaws.com/zachsaucier-com/html2canvas.min.js"></script>
<div class="btn">Тест</div>
<div class="btn">Тест</div>
<div class="btn">Тест</div>
<div class="btn">Тест</div>

CSS

.btn {
  display: inline-block;
  padding: 15px 30px;
  background: #ff0000;
  margin: 20px;
  border-radius: 10px;
  color: #fff;
}

JavaScript

var btn = document.querySelector(".btn");

html2canvas(btn).then(canvas => {
  ctx = canvas.getContext("2d");
  
  createParticleCanvas();
  
  let reductionFactor = 17;
  btn.addEventListener("click", e => {
    // Get the color data for our button
    let width = btn.offsetWidth;
    let height = btn.offsetHeight
    let colorData = ctx.getImageData(0, 0, width, height).data;

    // Keep track of how many times we've iterated (in order to reduce
    // the total number of particles create)
    let count = 0;

    // Go through every location of our button and create a particle
    for(let localX = 0; localX < width; localX++) {
      for(let localY = 0; localY < height; localY++) {
        if(count % reductionFactor === 0) {
          let index = (localY * width + localX) * 4;
          let rgbaColorArr = colorData.slice(index, index + 4);

          let bcr = btn.getBoundingClientRect();
          let globalX = bcr.left + localX;
          let globalY = bcr.top + localY;

          createParticleAtPoint(globalX, globalY, rgbaColorArr);
        }
        count++;
      }
    }
  });
});


/* An "exploding" particle effect that uses circles */
var ExplodingParticle = function() {
  // Set how long we want our particle to animate for
  this.animationDuration = 1000; // in ms

  // Set the speed for our particle
  this.speed = {
    x: -5 + Math.random() * 10,
    y: -5 + Math.random() * 10
  };
  
  // Size our particle
  this.radius = 5 + Math.random() * 5;
  
  // Set a max time to live for our particle
  this.life = 30 + Math.random() * 10;
  this.remainingLife = this.life;
  
  // This function will be called by our animation logic later on
  this.draw = ctx => {
    let p = this;

    if(this.remainingLife > 0
    && this.radius > 0) {
      // Draw a circle at the current location
      ctx.beginPath();
      ctx.arc(p.startX, p.startY, p.radius, 0, Math.PI * 2);
      ctx.fillStyle = "rgba(" + this.rgbArray[0] + ',' + this.rgbArray[1] + ',' +...