MediaWiki:Common.js: Unterschied zwischen den Versionen

Keine Bearbeitungszusammenfassung
Markierung: Zurückgesetzt
Keine Bearbeitungszusammenfassung
Markierung: Zurückgesetzt
Zeile 1.238: Zeile 1.238:


/* ============================================================
/* ============================================================
   ADOS – Feuerwerk mit Raketen (hochschießen + explodieren)
   ADOS – Feuerwerk mit Raketen + Explosion (sichtbar, ES5)
   ES5 | dauerhaft | kein Abdunkeln | pointer-events:none
   - dauerhaft
  - kein Abdunkeln (kein schwarzer Schleier)
  - Raketen mit Trail, Explosion deutlich
   ============================================================ */
   ============================================================ */
(function () {
(function () {
   'use strict';
   'use strict';


  // --- OPTIONAL: nur an Silvester/Neujahr ---
   // 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 = [];     // Raketenobjekte
   var rockets = [];
   var particles = [];   // Explosionspartikel
   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;


    // Start unten (leicht random)
     var x = rand(60, w - 60);
     var x = rand(60, w - 60);
     var y = h + rand(10, 80);
     var y = h + rand(20, 120);


     // Zielhöhe irgendwo oben/mittig
     // Explosionshöhe
     var targetY = rand(h * 0.15, h * 0.55);
     var targetY = rand(h * 0.12, h * 0.50);


     // Geschwindigkeit / Drift
     // Start-Geschwindigkeit nach oben (negativ)
     var vy = rand(-9.5, -12.5);
     var vy = rand(-14.0, -18.0);
     var vx = rand(-1.2, 1.2);
     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,
      life: rand(900, 1400), // Sicherheitslimit
       age: 0,
       age: 0,
       // Rocket-Farbe / Leuchtpunkt
       life: rand(2200, 3200),
      r: Math.floor(rand(220, 255)),
       r: r, g: g, b: b,
       g: Math.floor(rand(180, 240)),
       trail: [] // Liste von Punkten für Spur
       b: Math.floor(rand(80, 160))
     });
     });
   }
   }
Zeile 1.323: Zeile 1.344:
   // ---- Explosion ----
   // ---- Explosion ----
   function explode(x, y) {
   function explode(x, y) {
     var count = Math.floor(rand(45, 90));
     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, 6.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,
        life: rand(650, 1200),
         age: 0,
         age: 0,
         size: rand(1.4, 3.1),
        life: rand(900, 1600),
        // Explosionsfarbe: Gold/Rot/Blau gemischt
         size: rand(1.8, 3.8),
         r: Math.floor(rand(140, 255)),
         r: rr, g: gg, b: bb
        g: Math.floor(rand(80, 230)),
        b: Math.floor(rand(120, 255))
       });
       });
     }
     }
   }
   }


   // ---- Render: keine Abdunkelung → clearRect (kein Schleier) ----
   // ---- 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
     // 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 updaten/zeichnen ---
    // 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;


       // Bewegung
       // Trail-Punkt speichern
       r.vy += 0.0022 * dt; // Schwerkraft bremst (weniger negativ)
       r.trail.push({ x: r.x, y: r.y });
       r.vx *= Math.pow(0.999, dt);
       if (r.trail.length > 18) r.trail.shift();
       r.vy *= Math.pow(0.999, dt);
 
      // 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);


       // Rakete erreicht Zielhöhe → explodiert
       // 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:
       }
       }


       // Sicherheits-Limit
       // Sicherheit
       if (r.age >= r.life || r.y < -100 || r.x < -100 || r.x > w + 100) {
       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;
       }
       }


       // Rocket zeichnen: Punkt + kleiner Schweif
       // 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, 2.2, 0, Math.PI * 2, false);
       ctx.arc(r.x, r.y, 3.0, 0, Math.PI * 2, false);
       ctx.fill();
       ctx.fill();
      // Schweif (kurzer Strich nach unten)
      ctx.beginPath();
      ctx.strokeStyle = 'rgba(' + r.r + ',' + r.g + ',' + r.b + ',0.65)';
      ctx.lineWidth = 2;
      ctx.moveTo(r.x, r.y + 10);
      ctx.lineTo(r.x - r.vx * 3, r.y + 22);
      ctx.stroke();
     }
     }


     // --- Partikel updaten/zeichnen ---
     // --- 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:
       }
       }


       // Physik
       // Bewegung
       p.vy += 0.0030 * dt;
       p.vy += 0.020 * (dt / 16);
       p.vx *= Math.pow(0.998, dt);
       p.vx *= Math.pow(0.985, dt / 16);
       p.vy *= Math.pow(0.998, dt);
       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 t = 1 - (p.age / p.life);
       var alpha = clamp(1 - (p.age / p.life), 0, 1);
      var alpha = clamp(t, 0, 1);


       ctx.beginPath();
       ctx.beginPath();
Zeile 1.428: Zeile 1.474:
   }
   }


   // ---- Spawner: dauerhaft neue Raketen ----
   // ---- Spawner ----
   function scheduleRockets() {
   function scheduleRockets() {
     function loop() {
     function loop() {
       if (!running) return;
       if (!running) return;


       // 1–2 Raketen pro Spawn
       // 1–3 Raketen pro Tick
       spawnRocket();
       spawnRocket();
       if (Math.random() < 0.35) spawnRocket();
       if (Math.random() < 0.55) spawnRocket();
      if (Math.random() < 0.20) spawnRocket();


       // Frequenz (anpassen!)
       // Frequenz (kleiner = mehr Feuerwerk)
       setTimeout(loop, Math.floor(rand(800, 1500)));
       setTimeout(loop, Math.floor(rand(650, 1200)));
     }
     }
     loop();
     loop();
Zeile 1.452: Zeile 1.499:
     });
     });


    log('[Fireworks] init');
     scheduleRockets();
     scheduleRockets();
     requestAnimationFrame(tick);
     requestAnimationFrame(tick);