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
- Einen Effekt wählenFeuerwerk, Konfetti, Sterne, Herzen, Emoji, Rauch, Blasen, Schnee und mehr.
- In die Vorschau klickenJeder Klick burste Partikel. Justiere Anzahl, Größe, Tempo, Schwerkraft und Farben.
- 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