MediaWiki:Common.js: Unterschied zwischen den Versionen
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung Markierung: Zurückgesetzt |
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung Markierung: Zurückgesetzt |
||
| Zeile 1.238: | Zeile 1.238: | ||
/* ============================================================ | /* ============================================================ | ||
ADOS – Feuerwerk mit Raketen ( | ADOS – Feuerwerk mit Raketen + Explosion (sichtbar, ES5) | ||
- dauerhaft | |||
- kein Abdunkeln (kein schwarzer Schleier) | |||
- Raketen mit Trail, Explosion deutlich | |||
============================================================ */ | ============================================================ */ | ||
(function () { | (function () { | ||
'use strict'; | 'use strict'; | ||
// true = nur 31.12/01.01, false = immer | // true = nur 31.12/01.01, false = immer | ||
var onlyOnNewYears = false; | var onlyOnNewYears = false; | ||
// Debug in Konsole | |||
var DEBUG = false; | |||
function isNewYears() { | function isNewYears() { | ||
| Zeile 1.255: | Zeile 1.259: | ||
} | } | ||
if (onlyOnNewYears && !isNewYears()) return; | if (onlyOnNewYears && !isNewYears()) return; | ||
function log() { | |||
if (!DEBUG || !window.console) return; | |||
try { console.log.apply(console, arguments); } catch (e) {} | |||
} | |||
// Canvas anlegen | // Canvas anlegen | ||
function createCanvas() { | function createCanvas() { | ||
// falls schon existiert (z.B. nach Reload), entfernen | |||
var old = document.getElementById('ados-fireworks-canvas'); | |||
if (old && old.parentNode) old.parentNode.removeChild(old); | |||
var c = document.createElement('canvas'); | var c = document.createElement('canvas'); | ||
c.id = 'ados-fireworks-canvas'; | c.id = 'ados-fireworks-canvas'; | ||
| Zeile 1.277: | Zeile 1.290: | ||
c.height = Math.floor(window.innerHeight * dpr); | c.height = Math.floor(window.innerHeight * dpr); | ||
var ctx = c.getContext('2d'); | var ctx = c.getContext('2d'); | ||
// Koordinaten in CSS-Pixeln nutzen | |||
ctx.setTransform(dpr, 0, 0, dpr, 0, 0); | ctx.setTransform(dpr, 0, 0, dpr, 0, 0); | ||
// Optional: additiver Look für „Glow“ | |||
ctx.globalCompositeOperation = 'lighter'; | |||
return ctx; | return ctx; | ||
} | } | ||
| Zeile 1.285: | Zeile 1.304: | ||
var canvas, ctx; | var canvas, ctx; | ||
var rockets = []; | var rockets = []; | ||
var particles = []; | var particles = []; | ||
var last = 0; | var last = 0; | ||
var running = true; | var running = true; | ||
| Zeile 1.295: | Zeile 1.314: | ||
var h = window.innerHeight; | var h = window.innerHeight; | ||
var x = rand(60, w - 60); | var x = rand(60, w - 60); | ||
var y = h + rand( | var y = h + rand(20, 120); | ||
// | // Explosionshöhe | ||
var targetY = rand(h * 0. | var targetY = rand(h * 0.12, h * 0.50); | ||
// Geschwindigkeit | // Start-Geschwindigkeit nach oben (negativ) | ||
var vy = rand(- | var vy = rand(-14.0, -18.0); | ||
var vx = rand(-1. | var vx = rand(-1.8, 1.8); | ||
// „Glow“-Farbe (gold/weiß) | |||
var r = Math.floor(rand(220, 255)); | |||
var g = Math.floor(rand(170, 240)); | |||
var b = Math.floor(rand(80, 170)); | |||
rockets.push({ | rockets.push({ | ||
| Zeile 1.312: | Zeile 1.335: | ||
vy: vy, | vy: vy, | ||
targetY: targetY, | targetY: targetY, | ||
age: 0, | age: 0, | ||
life: rand(2200, 3200), | |||
r: r, g: g, b: b, | |||
g: | trail: [] // Liste von Punkten für Spur | ||
}); | }); | ||
} | } | ||
| Zeile 1.323: | Zeile 1.344: | ||
// ---- Explosion ---- | // ---- Explosion ---- | ||
function explode(x, y) { | function explode(x, y) { | ||
var count = Math.floor(rand( | var count = Math.floor(rand(70, 140)); | ||
var i; | var i; | ||
log('[Fireworks] explode @', x, y, 'count', count); | |||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||
var angle = rand(0, Math.PI * 2); | var angle = rand(0, Math.PI * 2); | ||
var speed = rand(2.0, | var speed = rand(2.5, 7.5); | ||
// knalligere Farben | |||
var rr = Math.floor(rand(120, 255)); | |||
var gg = Math.floor(rand(80, 240)); | |||
var bb = Math.floor(rand(120, 255)); | |||
// etwas „Gold“-Bias | |||
if (Math.random() < 0.40) { | |||
rr = Math.floor(rand(220, 255)); | |||
gg = Math.floor(rand(150, 230)); | |||
bb = Math.floor(rand(30, 120)); | |||
} | |||
particles.push({ | particles.push({ | ||
x: x, | x: x, | ||
| Zeile 1.333: | Zeile 1.370: | ||
vx: Math.cos(angle) * speed, | vx: Math.cos(angle) * speed, | ||
vy: Math.sin(angle) * speed, | vy: Math.sin(angle) * speed, | ||
age: 0, | age: 0, | ||
size: rand(1. | life: rand(900, 1600), | ||
size: rand(1.8, 3.8), | |||
r: | r: rr, g: gg, b: bb | ||
}); | }); | ||
} | } | ||
} | } | ||
// ---- | // ---- Frame ---- | ||
function tick(ts) { | function tick(ts) { | ||
if (!running) return; | if (!running) return; | ||
| Zeile 1.354: | Zeile 1.388: | ||
var h = window.innerHeight; | var h = window.innerHeight; | ||
// | // KEIN Abdunkeln: wir „faden“ mit transparenter WEISS-Schicht minimal. | ||
ctx.clearRect(0, 0, w, h); | // Dadurch gibt es einen soften Trail-Effekt, aber keinen dunklen Schleier. | ||
// (Wenn du absolut gar keinen Trail willst: ctx.clearRect(...) statt fillRect) | |||
ctx.globalCompositeOperation = 'source-over'; | |||
ctx.fillStyle = 'rgba(255,255,255,0.10)'; // kleiner Wert = weniger „Aufhellen“ | |||
ctx.fillRect(0, 0, w, h); | |||
// --- Rockets | // Glow wieder aktivieren | ||
ctx.globalCompositeOperation = 'lighter'; | |||
// --- Rockets --- | |||
var i, r; | var i, r; | ||
for (i = rockets.length - 1; i >= 0; i--) { | for (i = rockets.length - 1; i >= 0; i--) { | ||
| Zeile 1.363: | Zeile 1.404: | ||
r.age += dt; | r.age += dt; | ||
// | // Trail-Punkt speichern | ||
r. | r.trail.push({ x: r.x, y: r.y }); | ||
r. | if (r.trail.length > 18) r.trail.shift(); | ||
r.vy | |||
// Physik: Gravity zieht runter (vy wird weniger negativ) | |||
r.vy += 0.010 * (dt / 16); // stärker, damit es natürlicher wirkt | |||
r.x += r.vx * (dt / 16); | r.x += r.vx * (dt / 16); | ||
r.y += r.vy * (dt / 16); | r.y += r.vy * (dt / 16); | ||
// | // Explodieren, wenn Zielhöhe erreicht | ||
if (r.y <= r.targetY) { | if (r.y <= r.targetY) { | ||
explode(r.x, r.y); | explode(r.x, r.y); | ||
| Zeile 1.377: | Zeile 1.420: | ||
} | } | ||
// | // Sicherheit | ||
if (r.age >= r.life || r.y < - | if (r.age >= r.life || r.y < -200 || r.x < -200 || r.x > w + 200) { | ||
rockets.splice(i, 1); | rockets.splice(i, 1); | ||
continue; | continue; | ||
} | } | ||
// | // Trail zeichnen | ||
ctx.beginPath(); | |||
ctx.lineWidth = 3.2; | |||
ctx.strokeStyle = 'rgba(' + r.r + ',' + r.g + ',' + r.b + ',0.35)'; | |||
var t; | |||
for (t = 0; t < r.trail.length; t++) { | |||
var pt = r.trail[t]; | |||
if (t === 0) ctx.moveTo(pt.x, pt.y); | |||
else ctx.lineTo(pt.x, pt.y); | |||
} | |||
ctx.stroke(); | |||
// Rocket-Kopf (hell) | |||
ctx.beginPath(); | ctx.beginPath(); | ||
ctx.fillStyle = 'rgba(' + r.r + ',' + r.g + ',' + r.b + ',1)'; | ctx.fillStyle = 'rgba(' + r.r + ',' + r.g + ',' + r.b + ',1)'; | ||
ctx.arc(r.x, r.y, | ctx.arc(r.x, r.y, 3.0, 0, Math.PI * 2, false); | ||
ctx.fill(); | ctx.fill(); | ||
} | } | ||
// --- | // --- Particles --- | ||
var p; | var p; | ||
for (i = particles.length - 1; i >= 0; i--) { | for (i = particles.length - 1; i >= 0; i--) { | ||
| Zeile 1.409: | Zeile 1.456: | ||
} | } | ||
// | // Bewegung | ||
p.vy += 0. | p.vy += 0.020 * (dt / 16); | ||
p.vx *= Math.pow(0. | p.vx *= Math.pow(0.985, dt / 16); | ||
p.vy *= Math.pow(0. | p.vy *= Math.pow(0.985, dt / 16); | ||
p.x += p.vx * (dt / 16); | p.x += p.vx * (dt / 16); | ||
p.y += p.vy * (dt / 16); | p.y += p.vy * (dt / 16); | ||
var | var alpha = clamp(1 - (p.age / p.life), 0, 1); | ||
ctx.beginPath(); | ctx.beginPath(); | ||
| Zeile 1.428: | Zeile 1.474: | ||
} | } | ||
// ---- Spawner | // ---- Spawner ---- | ||
function scheduleRockets() { | function scheduleRockets() { | ||
function loop() { | function loop() { | ||
if (!running) return; | if (!running) return; | ||
// | // 1–3 Raketen pro Tick | ||
spawnRocket(); | spawnRocket(); | ||
if (Math.random() < 0. | if (Math.random() < 0.55) spawnRocket(); | ||
if (Math.random() < 0.20) spawnRocket(); | |||
// Frequenz ( | // Frequenz (kleiner = mehr Feuerwerk) | ||
setTimeout(loop, Math.floor(rand( | setTimeout(loop, Math.floor(rand(650, 1200))); | ||
} | } | ||
loop(); | loop(); | ||
| Zeile 1.452: | Zeile 1.499: | ||
}); | }); | ||
log('[Fireworks] init'); | |||
scheduleRockets(); | scheduleRockets(); | ||
requestAnimationFrame(tick); | requestAnimationFrame(tick); | ||