<div class="wrapper">
  <button data-type="square">Square particles</button>
  <button data-type="emoji">Emoji particles</button>
  <button data-type="mario">Mario particles</button>
  <button data-type="shadow">Shadow particles</button>
  <button data-type="line">Line particles</button>
</div>
<span class="preloader"></span>
particle {
  position: fixed;
  top: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: contain;
}

body {
  display: flex;
  min-height: 100vh;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  overflow: hidden;
  text-align: center;
}
button {
  padding: 20px;
  margin: 10px;
  align-self: center;
}
.preloader {
  position: absolute;
  background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/127738/mario-face.png);
}
View Compiled
function pop (e) {
  let amount = 30;
  switch (e.target.dataset.type) {
    case 'shadow':
    case 'line':
      amount = 60;
      break;
  }
  // Quick check if user clicked the button using a keyboard
  if (e.clientX === 0 && e.clientY === 0) {
    const bbox = e.target.getBoundingClientRect();
    const x = bbox.left + bbox.width / 2;
    const y = bbox.top + bbox.height / 2;
    for (let i = 0; i < 30; i++) {
      // We call the function createParticle 30 times
      // We pass the coordinates of the button for x & y values
      createParticle(x, y, e.target.dataset.type);
    }
  } else {
    for (let i = 0; i < amount; i++) {
      createParticle(e.clientX, e.clientY + window.scrollY, e.target.dataset.type);
    }
  }
}
function createParticle (x, y, type) {
  const particle = document.createElement('particle');
  document.body.appendChild(particle);
  let width = Math.floor(Math.random() * 30 + 8);
  let height = width;
  let destinationX = (Math.random() - 0.5) * 300;
  let destinationY = (Math.random() - 0.5) * 300;
  let rotation = Math.random() * 520;
  let delay = Math.random() * 200;
  
  switch (type) {
    case 'square':
      particle.style.background = `hsl(${Math.random() * 90 + 270}, 70%, 60%)`;
      particle.style.border = '1px solid white';
      break;
    case 'emoji':
      particle.innerHTML = ['โค','๐Ÿงก','๐Ÿ’›','๐Ÿ’š','๐Ÿ’™','๐Ÿ’œ','๐ŸคŽ'][Math.floor(Math.random() * 7)];
      particle.style.fontSize = `${Math.random() * 24 + 10}px`;
      width = height = 'auto';
      break;
    case 'mario':
      particle.style.backgroundImage = 'url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/127738/mario-face.png)';
      break;
    case 'shadow':
      var color = `hsl(${Math.random() * 90 + 90}, 70%, 50%)`;
      particle.style.boxShadow = `0 0 ${Math.floor(Math.random() * 10 + 10)}px ${color}`;
      particle.style.background = color;
      particle.style.borderRadius = '50%';
      width = height = Math.random() * 5 + 4;
      break;
    case 'line':
      var color = `hsl(${Math.random() * 90 + 90}, 70%, 50%)`;
      particle.style.background = 'black';
      height = 1;
      rotation += 1000;
      delay = Math.random() * 1000;
      break;
  }
  
  particle.style.width = `${width}px`;
  particle.style.height = `${height}px`;
  const animation = particle.animate([
    {
      transform: `translate(-50%, -50%) translate(${x}px, ${y}px) rotate(0deg)`,
      opacity: 1
    },
    {
      transform: `translate(-50%, -50%) translate(${x + destinationX}px, ${y + destinationY}px) rotate(${rotation}deg)`,
      opacity: 0
    }
  ], {
    duration: Math.random() * 1000 + 5000,
    easing: 'cubic-bezier(0, .9, .57, 1)',
    delay: delay
  });
  animation.onfinish = removeParticle;
}
function removeParticle (e) {
  e.srcElement.effect.target.remove();
}

if (document.body.animate) {
  document.querySelectorAll('button').forEach(button => button.addEventListener('click', pop));
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.