Klick-Feuerwerk-Generator

Erzeuge Klick-Feuerwerk, Konfetti und Partikelbursts für deine Site und kopiere dann das JavaScript

100 % kostenlos. Läuft vollständig in deinem Browser: deine Dateien und Daten verlassen dein Gerät nie, und es wird nichts auf einen Server hochgeladen.

local_fire_department Click canvas

Click anywhere to spawn the effect.

code Export

/* Click fireworks - generated by 500 Toolbox
 * Attach to the whole page (window):
 *   document.addEventListener('click', handler)
 * Attach to one element:
 *   document.querySelector('.ugfw-btn').addEventListener('click', handler)
 *
 * Rendering notes: glow uses cached radial-gradient sprites and additive
 * blending instead of ctx.shadowBlur, which is what keeps a 900-particle
 * sky at 60fps.
 */
(function () {
  var CFG = {"kind":"fireworks","count":90,"size":2.6,"speed":6.2,"gravity":0.11,"spread":360,"colors":["#fbbf24","#ef4444","#ffffff"],"glow":true,"duration":1500,"direction":"out","randomness":0.7,"emoji":"✨","attach":"window","launch":true,"trails":true,"autoShow":true,"max":900};
  var canvas = document.getElementById('ugfw-canvas');
  if (!canvas) {
    canvas = document.createElement('canvas');
    canvas.id = 'ugfw-canvas';
    document.body.appendChild(canvas);
  }
  var ctx = canvas.getContext('2d');
  if (!ctx) return;
  var ps = [];
  var last = 0;
  var W = window.innerWidth, H = window.innerHeight;
  var sprites = {};

  function fit() {
    var dpr = Math.min(2, window.devicePixelRatio || 1);
    W = window.innerWidth;
    H = window.innerHeight;
    canvas.width = W * dpr;
    canvas.height = H * dpr;
    canvas.style.width = '100%';
    canvas.style.height = '100%';
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
  }
  fit();
  window.addEventListener('resize', fit);

  function pick() { return CFG.colors[Math.floor(Math.random() * CFG.colors.length)]; }

  function sprite(color) {
    if (sprites[color]) return sprites[color];
    var c = document.createElement('canvas');
    c.width = 64; c.height = 64;
    var g = c.getContext('2d');
    var grd = g.createRadialGradient(32, 32, 0, 32, 32, 32);
    grd.addColorStop(0, '#ffffff');
    grd.addColorStop(0.22, color);
    grd.addColorStop(0.55, color);
    grd.addColorStop(1, 'rgba(0,0,0,0)');
    g.fillStyle = grd;
    g.beginPath(); g.arc(32, 32, 32, 0, Math.PI * 2); g.fill();
    sprites[color] = c;
    return c;
  }

  function star(r) {
    ctx.beginPath();
    for (var i = 0; i < 10; i++) {
      var a = (i * Math.PI) / 5 - Math.PI / 2;
      var rad = i % 2 ? r * 0.38 : r;
      var x = Math.cos(a) * rad, y = Math.sin(a) * rad;
      if (i) ctx.lineTo(x, y); else ctx.moveTo(x, y);
    }
    ctx.closePath();
  }
  function heart(sz) {
    ctx.beginPath();
    ctx.moveTo(0, sz * 0.35);
    ctx.bezierCurveTo(0, -sz * 0.3, -sz, -sz * 0.3, -sz, sz * 0.12);
    ctx.bezierCurveTo(-sz, sz * 0.62, 0, sz, 0, sz);
    ctx.bezierCurveTo(0, sz, sz, sz * 0.62, sz, sz * 0.12);
    ctx.bezierCurveTo(sz, -sz * 0.3, 0, -sz * 0.3, 0, sz * 0.35);
  }
  function trailKind(k) {
    return k === 'fireworks' || k === 'spark' || k === 'neon' || k === 'glow' || k === 'magic' || k === 'stars';
  }

  function lightning(x, y) {
    var dir = (Math.random() - 0.5) * (CFG.spread * Math.PI / 180);
    var len = 80 + Math.random() * 140;
    var pts = [{ x: x, y: y }];
    var cx = x, cy = y, segs = 8 + Math.floor(Math.random() * 6);
    for (var i = 0; i < segs; i++) {
      cx += Math.sin(dir) * (len / segs) + (Math.random() - 0.5) * 28;
      cy += Math.cos(dir) * (len / segs) + Math.random() * 10;
      pts.push({ x: cx, y: cy });
    }
    return { role: 'spark', kind: 'lightning', x: x, y: y, vx: 0, vy: 0, life: CFG.duration * 0.5, maxLife: CFG.duration * 0.6, size: CFG.size, color: pick(), rot: 0, vr: 0, points: pts, emoji: '' };
  }

  function shell(x, targetY) {
    var startY = H + 8;
    var rise = Math.max(60, startY - targetY);
    var frames = Math.max(22, Math.min(90, rise / 7));
    var g = Math.max(0.02, CFG.gravity) * 0.55;
    var v0 = ((targetY - startY) - 0.5 * g * frames * frames) / frames;
    var lifeMs = frames * 16 + 400;
    return { role: 'shell', kind: CFG.kind, x: x, y: startY, vx: (Math.random() - 0.5) * 1.1, vy: v0,
      life: lifeMs, maxLife: lifeMs, size: Math.max(1.6, CFG.size * 0.8), color: pick(),
      rot: 0, vr: 0, emoji: CFG.emoji, targetY: targetY, trail: [x, startY], seed: Math.random() * 6.28 };
  }

  function one(x, y, i, n, shellColor) {
    var spreadRad = CFG.spread * Math.PI / 180;
    var round = CFG.direction === 'out' && CFG.spread >= 340;
    var angle;
    if (round) angle = Math.random() * Math.PI * 2;
    else if (CFG.direction === 'out') angle = (i / n) * Math.PI * 2 + (Math.random() - 0.5) * spreadRad * CFG.randomness;
    else if (CFG.direction === 'up') angle = -Math.PI / 2 + (Math.random() - 0.5) * spreadRad;
    else if (CFG.direction === 'down') angle = Math.PI / 2 + (Math.random() - 0.5) * spreadRad;
    else angle = Math.random() * Math.PI * 2;
    var bias = round ? 0.45 + 0.55 * Math.sqrt(Math.random()) : 0.55 + Math.random() * 0.7;
    var sp = CFG.speed * bias * (1 - 0.35 * CFG.randomness + 0.35 * CFG.randomness * (0.6 + Math.random() * 0.8));
    var vx = Math.cos(angle) * sp, vy = Math.sin(angle) * sp;
    if (CFG.kind === 'bubbles' || CFG.kind === 'smoke') { vy = -Math.abs(vy) * (CFG.kind === 'smoke' ? 0.45 : 0.7); vx *= 0.45; }
    if (CFG.kind === 'snow' || CFG.kind === 'leaves') { vy = Math.abs(vy) * 0.35 + 0.4; vx *= 0.5; }
    var life = CFG.duration * (0.65 + Math.random() * 0.5);
    return { role: 'spark', kind: CFG.kind, x: x, y: y, vx: vx, vy: vy, life: life, maxLife: life,
      size: CFG.size * (0.6 + Math.random() * 0.9),
      color: Math.random() < 0.16 ? '#fff6de' : shellColor,
      rot: Math.random() * Math.PI * 2, vr: (Math.random() - 0.5) * 0.28, emoji: CFG.emoji,
      seed: Math.random() * 6.28,
      trail: CFG.trails && trailKind(CFG.kind) ? [x, y] : null };
  }

  function explode(x, y) {
    var room = Math.max(0, CFG.max - ps.length);
    if (room < 12) { ps.splice(0, Math.min(ps.length, CFG.count)); room = Math.max(0, CFG.max - ps.length); }
    var n = Math.min(room, CFG.count);
    var shellColor = pick();
    if (CFG.glow) ps.push({ role: 'flash', kind: CFG.kind, x: x, y: y, vx: 0, vy: 0, life: 190, maxLife: 190, size: CFG.size * 9, color: '#ffffff', rot: 0, vr: 0, emoji: '' });
    for (var i = 0; i < n; i++) ps.push(one(x, y, i, n, shellColor));
  }

  function burst(x, y) {
    if (CFG.kind === 'lightning') {
      for (var b = 0; b < 4; b++) ps.push(lightning(x, y));
      return;
    }
    if (CFG.launch) { ps.push(shell(x, y)); return; }
    explode(x, y);
  }

  function pushTrail(p) {
    if (!p.trail) return;
    p.trail.push(p.x, p.y);
    if (p.trail.length > 12) p.trail.splice(0, p.trail.length - 12);
  }

  function tick(now) {
    var dt = last ? Math.min(48, now - last) : 16;
    last = now;
    var f = dt / 16;
    ctx.clearRect(0, 0, W, H);

    var next = [];
    for (var i = 0; i < ps.length; i++) {
      var p = ps[i];
      p.life -= dt;
      if (p.role === 'shell') {
        p.vy += CFG.gravity * 0.55 * f;
        p.x += p.vx * f; p.y += p.vy * f;
        pushTrail(p);
        if (p.vy >= 0 || p.y <= p.targetY || p.life <= 0) { explode(p.x, p.y); continue; }
        next.push(p);
        continue;
      }
      if (p.life <= 0) continue;
      if (p.kind === 'lightning' || p.role === 'flash') { next.push(p); continue; }
      p.vy += CFG.gravity * f;
      if (p.kind === 'snow' || p.kind === 'leaves') p.x += Math.sin(p.life / 90 + p.rot) * 0.6;
      if (p.kind === 'bubbles') p.x += Math.sin(p.life / 70) * 0.35;
      p.x += p.vx * f; p.y += p.vy * f; p.rot += p.vr * f;
      var drag = p.trail ? 0.976 : 0.992;
      p.vx *= drag;
      if (p.trail) p.vy *= drag;
      pushTrail(p);
      next.push(p);
    }
    ps = next;

    ctx.globalCompositeOperation = CFG.glow ? 'lighter' : 'source-over';
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';
    for (var j = 0; j < ps.length; j++) {
      var q = ps[j];
      var t = Math.max(0, Math.min(1, q.life / q.maxLife));

      if (q.role === 'flash') {
        var fr = q.size * (1 + (1 - t) * 1.6);
        ctx.globalAlpha = t * t * 0.75;
        ctx.drawImage(sprite(q.color), q.x - fr, q.y - fr, fr * 2, fr * 2);
        continue;
      }
      if (q.kind === 'lightning') {
        ctx.globalAlpha = t;
        ctx.strokeStyle = q.color;
        ctx.lineWidth = Math.max(1.2, q.size * 0.8);
        ctx.beginPath();
        ctx.moveTo(q.points[0].x, q.points[0].y);
        for (var k = 1; k < q.points.length; k++) ctx.lineTo(q.points[k].x, q.points[k].y);
        ctx.stroke();
        continue;
      }

      var flicker = q.seed === undefined ? 1 : 0.72 + 0.28 * Math.sin(q.life * 0.045 + q.seed);
      var alpha = Math.min(1, t * 1.25) * (t < 0.55 ? flicker : 1);

      if (q.trail && q.trail.length >= 4) {
        ctx.globalAlpha = alpha * 0.42;
        ctx.strokeStyle = q.color;
        ctx.lineWidth = Math.max(0.8, q.size * 0.85);
        ctx.beginPath();
        ctx.moveTo(q.trail[0], q.trail[1]);
        for (var m = 2; m < q.trail.length; m += 2) ctx.lineTo(q.trail[m], q.trail[m + 1]);
        ctx.stroke();
      }

      if (q.role === 'shell') {
        var sr = q.size * 2.2;
        ctx.globalAlpha = 0.9;
        ctx.drawImage(sprite(q.color), q.x - sr, q.y - sr, sr * 2, sr * 2);
        continue;
      }

      if (q.kind === 'confetti' || q.kind === 'pixel' || q.kind === 'stars' || q.kind === 'magic'
          || q.kind === 'hearts' || q.kind === 'emoji' || q.kind === 'leaves') {
        ctx.save();
        ctx.globalAlpha = alpha;
        ctx.fillStyle = q.color;
        ctx.translate(q.x, q.y);
        ctx.rotate(q.rot);
        if (q.kind === 'confetti') ctx.fillRect(-q.size, -q.size * 0.4, q.size * 2, q.size * 1.2);
        else if (q.kind === 'pixel') ctx.fillRect(-q.size, -q.size, q.size * 2, q.size * 2);
        else if (q.kind === 'stars' || q.kind === 'magic') { star(q.size * 1.6); ctx.fill(); }
        else if (q.kind === 'hearts') { heart(q.size * 1.3); ctx.fill(); }
        else if (q.kind === 'emoji') { ctx.font = (q.size * 3.2) + 'px serif'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(q.emoji, 0, 0); }
        else { ctx.beginPath(); ctx.ellipse(0, 0, q.size * 1.6, q.size * 0.7, 0.4, 0, Math.PI * 2); ctx.fill(); }
        ctx.restore();
      } else if (q.kind === 'smoke') {
        ctx.globalAlpha = t * 0.26; ctx.fillStyle = q.color;
        ctx.beginPath(); ctx.arc(q.x, q.y, q.size * (2.2 - t), 0, Math.PI * 2); ctx.fill();
      } else if (q.kind === 'bubbles') {
        ctx.globalAlpha = alpha; ctx.strokeStyle = q.color; ctx.lineWidth = 1.2;
        ctx.beginPath(); ctx.arc(q.x, q.y, q.size * 1.4, 0, Math.PI * 2); ctx.stroke();
      } else if (q.kind === 'snow') {
        ctx.globalAlpha = alpha; ctx.fillStyle = q.color;
        ctx.beginPath(); ctx.arc(q.x, q.y, q.size, 0, Math.PI * 2); ctx.fill();
      } else {
        var rr = q.size * (q.kind === 'glow' ? 2.6 : q.kind === 'neon' ? 2.2 : 1.9);
        ctx.globalAlpha = alpha;
        if (CFG.glow) ctx.drawImage(sprite(q.color), q.x - rr, q.y - rr, rr * 2, rr * 2);
        else { ctx.fillStyle = q.color; ctx.beginPath(); ctx.arc(q.x, q.y, q.size * 1.1, 0, Math.PI * 2); ctx.fill(); }
      }
    }
    ctx.globalCompositeOperation = 'source-over';
    ctx.globalAlpha = 1;
    requestAnimationFrame(tick);
  }
  requestAnimationFrame(tick);

  if (CFG.autoShow) {
    setInterval(function () {
      if (document.hidden) return;
      burst(W * (0.15 + Math.random() * 0.7), H * (0.18 + Math.random() * 0.3));
    }, 1100);
  }

  function handler(e) { burst(e.clientX, e.clientY); }

  if (CFG.attach === 'button') {
    var btn = document.querySelector('.ugfw-btn');
    if (btn) {
      btn.addEventListener('click', function (e) {
        e.preventDefault();
        e.stopPropagation();
        var r = e.currentTarget.getBoundingClientRect();
        burst(r.left + r.width / 2, r.top + r.height / 2);
      });
    }
  } else {
    document.addEventListener('click', handler);
  }
})();

Über dieses Tool

Klick-Feuerwerk macht aus einem Tippen einen Partikelburst: Funken, Konfetti, Herzen, Emoji, Schnee, Neon. Dieser Generator lässt dich in die Vorschau klicken, Anzahl, Schwerkraft, Streuung und Farbe justieren und JavaScript kopieren, das an die ganze Seite oder an einen Button andockt. Ein Partikel-Cap und ein Performance-Modus halten schwache Handys vom Schmelzen ab. Effekte spielen nie automatisch Audio, und nichts wird hochgeladen.

So verwendest du dieses Tool

  1. Einen Effekt wählenFeuerwerk, Konfetti, Sterne, Herzen, Emoji, Rauch, Blasen, Schnee und mehr.
  2. In die Vorschau klickenJeder Klick burste Partikel. Justiere Anzahl, Größe, Tempo, Schwerkraft und Farben.
  3. Wählen, wo es andocktJeder Klick auf der Seite oder nur ein bestimmter Button. Dann kopiere das Skript.

Warum es nutzen

  • Fünfzehn Partikelstile mit Live-Klick-Test.
  • Presets für Celebration, Gaming, Magic, Love, Neon, Minimal und Party.
  • Partikel-Cap plus ein Performance-Modus für langsamere Geräte.
  • Export dockt an das Fenster oder an ein Element an.

Häufige Anwendungen

  • Ein Celebrate-Burst, wenn jemand ein Formular abschließt.
  • Konfetti beim Upgrade-Klick auf einer Preisseite.
  • Ein ruhiger Funke in einer Game-UI.

Fehler, die du vermeiden solltest

  • ctx.shadowBlur für den Glow zu nutzen. Es rendert einen Blur pro Partikel pro Frame neu und ist der übliche Grund, warum ein Burst Frames verliert; gecachte Gradient-Sprites kosten einen Bruchteil davon.
  • Den Effekt an jeden Klick auf der Seite zu hängen, inklusive Klicks auf Links und Formularfelder, wo er mit der eigentlichen Interaktion kämpft.
  • Partikelanzahl hoch und Dauer lang gleichzeitig zu setzen. Live-Partikel sind Anzahl mal Lebenszeit, nicht Anzahl allein.
  • Celebration-Effekte zu feuern, ohne prefers-reduced-motion zu prüfen, was Menschen mit vestibulären Störungen wirklich belasten kann.
  • Das Canvas ohne pointer-events: none zu lassen, sodass es still Klicks schluckt, die für die Seite darunter gedacht sind.

Häufig gestellte Fragen

Die Engine cappt Live-Partikel (etwa 400), und der Performance-Modus halbiert den Burst. Alte Partikel werden entfernt, wenn sie verblassen.

Ja. Für Emoji und Herzen kannst du ein eigenes Symbol tippen, das der Burst verwendet.

Wechsle zur Element-Option, kopiere das Skript und behalte den Beispiel-Selektor oder zeige auf deine eigene Button-id.

Nein. Der Export ist ein kleines Vanilla-Skript. Kein Extra-Paket zum Installieren.

Andere suchen auch nach

  • klick feuerwerk javascript
  • konfetti effekt beim klick
  • canvas partikel effekt generator
  • celebration animation für website
  • js confetti library alternative
  • maus klick effekt javascript
  • feuerwerk animation code

Related guides