Mini curso · 10

Confeti al pulsar

Cada clic lanza decenas de partículas en direcciones aleatorias. Es la base de cualquier celebración en la web, y un primer contacto con los sistemas de partículas.

JavaScriptCSS keyframes Dificultad media⏱ 6 min

Pulsa el botón (y cambia la cantidad) 👇

haz clic varias veces

La idea

Por cada clic creamos N partículas. A cada una le damos un ángulo y una distancia al azar, y dejamos que el CSS la anime desde el centro hasta ese punto mientras se desvanece. Al terminar, la borramos del DOM.

const ang = Math.random() * Math.PI * 2;
const d = 40 + Math.random() * 90;
p.style.setProperty('--tx', Math.cos(ang) * d + 'px');
p.style.setProperty('--ty', Math.sin(ang) * d + 'px');

Paso 1 · El CSS de la partícula

La animación va de su punto de origen hasta el desplazamiento --tx/--ty, girando y desvaneciéndose.

.confeti{
  position:absolute; width:9px; height:9px; border-radius:2px;
  transform:translate(-50%,-50%);
  animation:vuela .8s ease-out forwards;
}
@keyframes vuela{
  to{
    transform:translate(calc(-50% + var(--tx)), calc(-50% + var(--ty))) rotate(320deg);
    opacity:0;
  }
}

Paso 2 · El JavaScript

boton.addEventListener('click', () => {
  for (let i = 0; i < 26; i++) {
    const p = document.createElement('span');
    p.className = 'confeti';
    p.style.background = colores[Math.random() * colores.length | 0];
    const ang = Math.random() * Math.PI * 2, d = 40 + Math.random() * 90;
    p.style.setProperty('--tx', Math.cos(ang) * d + 'px');
    p.style.setProperty('--ty', Math.sin(ang) * d + 'px');
    escena.appendChild(p);
    setTimeout(() => p.remove(), 800);
  }
});

Por qué limpiar el DOM

Cada partícula es un <span> real. Si no las borras, con cada clic se acumulan cientos de nodos invisibles y la página se vuelve lenta. El setTimeout que las elimina al acabar la animación es clave.

Fiesta lista 🎉

Ya tienes un sistema de partículas básico. La misma idea (crear, animar, destruir) sirve para chispas, humo, estrellas o corazones.