MediaWiki:Common.js: Unterschied zwischen den Versionen
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
| Zeile 1.237: | Zeile 1.237: | ||
/* ============================================================ | /* ============================================================ | ||
ADOS – Feuerwerk ( | ADOS – Feuerwerk (Raketen hoch + Explosion + optional "2026") | ||
ES5 | dauerhaft | kein Abdunkeln | Canvas transparent | ES5 | dauerhaft | kein Abdunkeln/Overlay | Canvas transparent | ||
============================================================ */ | ============================================================ */ | ||
(function () { | (function () { | ||
| Zeile 1.245: | Zeile 1.245: | ||
// true = nur 31.12/01.01, false = immer | // true = nur 31.12/01.01, false = immer | ||
var onlyOnNewYears = false; | var onlyOnNewYears = false; | ||
// Wahrscheinlichkeit, dass statt normaler Explosion "2026" erscheint | |||
var YEAR_PROB = 0.15; // 0.10 = seltener, 0.25 = häufiger | |||
// Raketen-Geschwindigkeit (langsamer = kleinere Beträge) | |||
var ROCKET_VY_MIN = -6.5; | |||
var ROCKET_VY_MAX = -9.0; | |||
var ROCKET_VX_MIN = -0.6; | |||
var ROCKET_VX_MAX = 0.6; | |||
// Schwerkraft für Rakete (kleiner = ruhiger) | |||
var ROCKET_GRAVITY = 0.003; | |||
function isNewYears() { | function isNewYears() { | ||
| Zeile 1.278: | Zeile 1.290: | ||
var ctx = c.getContext('2d'); | var ctx = c.getContext('2d'); | ||
ctx.setTransform(dpr, 0, 0, dpr, 0, 0); | ctx.setTransform(dpr, 0, 0, dpr, 0, 0); | ||
// Glow | // Glow/Leuchteffekt | ||
ctx.globalCompositeOperation = 'lighter'; | ctx.globalCompositeOperation = 'lighter'; | ||
return ctx; | return ctx; | ||
| Zeile 1.292: | Zeile 1.304: | ||
var running = true; | var running = true; | ||
// ---- | // ------------------------------------------------------------ | ||
// "2026" Punkt-Matrix (5x7) | |||
// ------------------------------------------------------------ | |||
function getDigitPoints(digit) { | |||
var map = { | |||
'0': [ | |||
"01110", | |||
"10001", | |||
"10011", | |||
"10101", | |||
"11001", | |||
"10001", | |||
"01110" | |||
], | |||
'2': [ | |||
"01110", | |||
"10001", | |||
"00001", | |||
"00010", | |||
"00100", | |||
"01000", | |||
"11111" | |||
], | |||
'6': [ | |||
"00110", | |||
"01000", | |||
"10000", | |||
"11110", | |||
"10001", | |||
"10001", | |||
"01110" | |||
] | |||
}; | |||
return map[digit] || []; | |||
} | |||
// ------------------------------------------------------------ | |||
// Rakete erzeugen | |||
// ------------------------------------------------------------ | |||
function spawnRocket() { | function spawnRocket() { | ||
var w = window.innerWidth; | var w = window.innerWidth; | ||
| Zeile 1.300: | Zeile 1.350: | ||
var y = h + rand(20, 120); | var y = h + rand(20, 120); | ||
// Explosionshöhe | // Explosionshöhe | ||
var targetY = rand(h * 0.12, h * 0.48); | var targetY = rand(h * 0.12, h * 0.48); | ||
// | // LANGSAMERES Hochschießen (konfig oben) | ||
var vy = rand( | var vy = rand(ROCKET_VY_MIN, ROCKET_VY_MAX); | ||
var vx = rand( | var vx = rand(ROCKET_VX_MIN, ROCKET_VX_MAX); | ||
// | // warmes Leuchten | ||
var r = Math.floor(rand(220, 255)); | var r = Math.floor(rand(220, 255)); | ||
var g = Math.floor(rand(170, 240)); | var g = Math.floor(rand(170, 240)); | ||
| Zeile 1.319: | Zeile 1.369: | ||
life: rand(2400, 3400), | life: rand(2400, 3400), | ||
r: r, g: g, b: b, | r: r, g: g, b: b, | ||
trail: [] | trail: [], | ||
showYear: (Math.random() < YEAR_PROB) | |||
}); | }); | ||
} | } | ||
// ---- Explosion | // ------------------------------------------------------------ | ||
// Normale Explosion | |||
// ------------------------------------------------------------ | |||
function explode(x, y) { | function explode(x, y) { | ||
var count = Math.floor(rand(55, 95)); | var count = Math.floor(rand(55, 95)); | ||
var i; | var i; | ||
| Zeile 1.331: | Zeile 1.383: | ||
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.8, 6.8); | var speed = rand(2.8, 6.8); | ||
var rr = Math.floor(rand(120, 255)); | var rr = Math.floor(rand(120, 255)); | ||
var gg = Math.floor(rand(80, 240)); | var gg = Math.floor(rand(80, 240)); | ||
var bb = Math.floor(rand(120, 255)); | var bb = Math.floor(rand(120, 255)); | ||
// Gold/Amber | // Gold/Amber Bias | ||
if (Math.random() < 0.35) { | if (Math.random() < 0.35) { | ||
rr = Math.floor(rand(220, 255)); | rr = Math.floor(rand(220, 255)); | ||
| Zeile 1.353: | Zeile 1.403: | ||
life: rand(900, 1500), | life: rand(900, 1500), | ||
size: rand(1.8, 3.4), | size: rand(1.8, 3.4), | ||
r: rr, g: gg, b: bb | r: rr, g: gg, b: bb, | ||
type: 'normal' | |||
}); | }); | ||
} | } | ||
} | } | ||
// ------------------------------------------------------------ | |||
// "2026" Explosion (Punkte ziehen sich kurz zur Zahl) | |||
// ------------------------------------------------------------ | |||
function explode2026(cx, cy) { | |||
var digits = ['2', '0', '2', '6']; | |||
// Optik-Parameter | |||
var spacing = 34; // Abstand zwischen Ziffern | |||
var pixel = 6; // Punktabstand innerhalb Ziffer | |||
var rowsH = 7 * pixel; | |||
// Gesamtbreite grob berechnen: 4 Ziffern * (5*pixel) + 3*spacing | |||
var totalW = (4 * (5 * pixel)) + (3 * spacing); | |||
var startX = cx - (totalW / 2); | |||
var baseY = cy - (rowsH / 2); | |||
var dx = startX; | |||
var d, y, x, mat; | |||
for (d = 0; d < digits.length; d++) { | |||
mat = getDigitPoints(digits[d]); | |||
for (y = 0; y < mat.length; y++) { | |||
for (x = 0; x < mat[y].length; x++) { | |||
if (mat[y].charAt(x) === '1') { | |||
// Partikel startet am Explosionspunkt und „zieht“ zur Zielposition | |||
particles.push({ | |||
x: cx, | |||
y: cy, | |||
vx: rand(-1.2, 1.2), | |||
vy: rand(-1.2, 1.2), | |||
tx: dx + x * pixel, | |||
ty: baseY + y * pixel, | |||
age: 0, | |||
life: 1800, | |||
size: 2.6, | |||
r: 255, | |||
g: 200, | |||
b: 80, | |||
type: 'digit' | |||
}); | |||
} | |||
} | |||
} | |||
dx += (5 * pixel) + spacing; | |||
} | |||
} | |||
// ------------------------------------------------------------ | |||
// Frame | |||
// ------------------------------------------------------------ | |||
function tick(ts) { | function tick(ts) { | ||
if (!running) return; | if (!running) return; | ||
| Zeile 1.372: | Zeile 1.474: | ||
ctx.globalCompositeOperation = 'lighter'; | ctx.globalCompositeOperation = 'lighter'; | ||
// Rockets | // ---------------- 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.382: | Zeile 1.484: | ||
if (r.trail.length > 16) r.trail.shift(); | if (r.trail.length > 16) r.trail.shift(); | ||
// Physik | // Physik (langsamer & ruhiger) | ||
r.vy += | r.vy += ROCKET_GRAVITY * (dt / 16); | ||
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 | ||
if (r.y <= r.targetY) { | if (r.y <= r.targetY) { | ||
explode(r.x, r.y); | if (r.showYear) explode2026(r.x, r.y); | ||
else explode(r.x, r.y); | |||
rockets.splice(i, 1); | rockets.splice(i, 1); | ||
continue; | continue; | ||
| Zeile 1.400: | Zeile 1.503: | ||
} | } | ||
// Trail zeichnen | // Trail zeichnen | ||
ctx.beginPath(); | ctx.beginPath(); | ||
ctx.lineWidth = 2.6; | ctx.lineWidth = 2.6; | ||
| Zeile 1.419: | Zeile 1.522: | ||
} | } | ||
// Particles | // ---------------- Particles ---------------- | ||
var p; | var p; | ||
for (i = particles.length - 1; i >= 0; i--) { | for (i = particles.length - 1; i >= 0; i--) { | ||
| Zeile 1.430: | Zeile 1.533: | ||
} | } | ||
// | // "2026"-Partikel: zuerst zur Zielposition ziehen, dann zerfallen lassen | ||
p.vy += 0.018 * (dt / 16); | if (p.type === 'digit' && p.age < 900) { | ||
// sanftes „Anziehen“ zur Zahl | |||
p.x += (p.tx - p.x) * 0.085; | |||
p.y += (p.ty - p.y) * 0.085; | |||
} else { | |||
// normales Partikel-Verhalten | |||
p.vy += 0.018 * (dt / 16); | |||
p.vx *= Math.pow(0.986, dt / 16); | |||
p.vy *= Math.pow(0.986, dt / 16); | |||
p.x += p.vx * (dt / 16); | |||
p.y += p.vy * (dt / 16); | |||
} | |||
var alpha = clamp(1 - (p.age / p.life), 0, 1); | var alpha = clamp(1 - (p.age / p.life), 0, 1); | ||
| Zeile 1.448: | Zeile 1.558: | ||
} | } | ||
// ---- Spawn-Frequenz (klassisch | // ------------------------------------------------------------ | ||
// Spawn-Frequenz (klassisch, aber nicht Dauerfeuer) | |||
// ------------------------------------------------------------ | |||
function scheduleRockets() { | function scheduleRockets() { | ||
function loop() { | function loop() { | ||
if (!running) return; | if (!running) return; | ||
// meist 1 Rakete, manchmal 2 | // meist 1 Rakete, manchmal 2 | ||
spawnRocket(); | spawnRocket(); | ||
if (Math.random() < 0.28) spawnRocket(); | if (Math.random() < 0.28) spawnRocket(); | ||