MediaWiki:Common.js: Unterschied zwischen den Versionen

Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 1.237: Zeile 1.237:


/* ============================================================
/* ============================================================
   ADOS – Feuerwerk (klassisch Silvester) – Raketen steigen hoch + explodieren
   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-/Leuchteffekt (klassischer Feuerwerkslook)
     // Glow/Leuchteffekt
     ctx.globalCompositeOperation = 'lighter';
     ctx.globalCompositeOperation = 'lighter';
     return ctx;
     return ctx;
Zeile 1.292: Zeile 1.304:
   var running = true;
   var running = true;


   // ---- Rocket Spawn (klassisch: moderat schnell) ----
   // ------------------------------------------------------------
  // "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 (klassisch: eher im oberen Mittelfeld)
     // Explosionshöhe
     var targetY = rand(h * 0.12, h * 0.48);
     var targetY = rand(h * 0.12, h * 0.48);


     // Geschwindigkeit (klassisch: sichtbar, aber nicht hektisch)
     // LANGSAMERES Hochschießen (konfig oben)
     var vy = rand(-6.0, -8.5);
     var vy = rand(ROCKET_VY_MIN, ROCKET_VY_MAX);
     var vx = rand(-0.6, 0.6);
     var vx = rand(ROCKET_VX_MIN, ROCKET_VX_MAX);


     // Raketenleuchten (warm/gold)
     // 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 (klassisch: kräftig, aber nicht extrem) ----
   // ------------------------------------------------------------
  // Normale Explosion
  // ------------------------------------------------------------
   function explode(x, y) {
   function explode(x, y) {
    // Partikelanzahl: klassisch mittel
     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);
      // Geschwindigkeit: klassisch „Knall“
       var speed = rand(2.8, 6.8);
       var speed = rand(2.8, 6.8);


      // Farben: Mix aus bunt + gold (klassisch)
       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-Bias für „klassisch“
       // 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: sanfte Schwerkraft (klassisch)
       // Physik (langsamer & ruhiger)
       r.vy += 0.003 * (dt / 16);
       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);


       // Explosions-Trigger
       // 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 (klassisch: sichtbar, aber nicht zu dick)
       // 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:
       }
       }


       // Physik
       // "2026"-Partikel: zuerst zur Zielposition ziehen, dann zerfallen lassen
       p.vy += 0.018 * (dt / 16);
       if (p.type === 'digit' && p.age < 900) {
      p.vx *= Math.pow(0.986, dt / 16);
        // sanftes „Anziehen“ zur Zahl
      p.vy *= Math.pow(0.986, dt / 16);
        p.x += (p.tx - p.x) * 0.085;
      p.x += p.vx * (dt / 16);
        p.y += (p.ty - p.y) * 0.085;
      p.y += p.vy * (dt / 16);
      } 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: alle ~1.2–2.2s) ----
   // ------------------------------------------------------------
  // 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 (klassisch)
       // meist 1 Rakete, manchmal 2
       spawnRocket();
       spawnRocket();
       if (Math.random() < 0.28) spawnRocket();
       if (Math.random() < 0.28) spawnRocket();