MediaWiki:Common.js: Unterschied zwischen den Versionen

Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 397: Zeile 397:




/* Fireworks Popup (v1) – once per day, canvas fireworks, motion-safe */
/* Fireworks Popup (v2) – mit großem "ADOS" im Feuerwerk */
mw.loader.using(['mediawiki.util','jquery']).then(function(){
mw.loader.using(['mediawiki.util','jquery']).then(function(){
   (function($, mw){
   (function($, mw){
Zeile 404: Zeile 404:
     var CONFIG = {
     var CONFIG = {
       enabled: true,
       enabled: true,
       id: 'fireworks_popup_v1',                 // bei Änderungen erhöhen
       id: 'fireworks_popup_v2',
       title: 'Neu: Abfüllungen bewerten 🎉',
       title: 'Neu: Abfüllungen bewerten 🎉',
       messageHTML:
       messageHTML:
         '<p>Ab sofort kannst du im Wiki <strong>jede Abfüllung bewerten</strong> – ' +
         '<p>Ab sofort kannst du im Wiki <strong>jede Abfüllung bewerten</strong> – ' +
         'teile deine Meinung und hilf anderen bei der Auswahl!</p>',
         'teile deine Meinung und hilf anderen bei der Auswahl!</p>',
       cta: { text: 'Jetzt bewerten', url: 'https://ados-wiki.de/index.php?title=Spezial:Zuf%C3%A4llige_Seite' }, // URL anpassen
       cta: { text: 'Jetzt bewerten', url: 'https://ados-wiki.de/index.php?title=Spezial:Zuf%C3%A4llige_Seite' },
       showOnNamespaces: 'all',                 // oder z. B. [0,4]
       showOnNamespaces: 'all',
       dailyLimit: 1,
       dailyLimit: 1,
       escToClose: true,
       escToClose: true,
Zeile 418: Zeile 418:
     if (!CONFIG.enabled) return;
     if (!CONFIG.enabled) return;


    // Namespace-Filter
     var ns = mw.config.get('wgNamespaceNumber');
     var ns = mw.config.get('wgNamespaceNumber');
     if (CONFIG.showOnNamespaces !== 'all' &&
     if (CONFIG.showOnNamespaces !== 'all' &&
Zeile 424: Zeile 423:
         $.inArray(ns, CONFIG.showOnNamespaces) === -1) return;
         $.inArray(ns, CONFIG.showOnNamespaces) === -1) return;


    // Einmal pro Tag
     var isAnon = (mw.config.get('wgUserName') === null);
     var isAnon = (mw.config.get('wgUserName') === null);
     function g(k){ try{return localStorage.getItem(k);}catch(e){return null;} }
     function g(k){ try{return localStorage.getItem(k);}catch(e){return null;} }
Zeile 434: Zeile 432:


     $(function(){
     $(function(){
      // Grundgerüst
       var $overlay = $('<div>', {'class':'mw-popup-overlay'});
       var $overlay = $('<div>', {'class':'mw-popup-overlay'});
       var $modal = $('<div>', {'class':'mw-popup-modal','role':'dialog','aria-modal':'true','aria-labelledby':'mw-fw-title'});
       var $modal = $('<div>', {'class':'mw-popup-modal','role':'dialog','aria-modal':'true','aria-labelledby':'mw-fw-title'});


      // Feuerwerk-Canvas (liegt oben im Modal, hinter Text reservierter Bereich)
       var $fwWrap = $('<div>', {'class':'mw-fw-canvas-wrap'});
       var $fwWrap = $('<div>', {'class':'mw-fw-canvas-wrap'});
       var $canvas = $('<canvas>', {'class':'mw-fw-canvas', 'aria-hidden':'true'});
       var $canvas = $('<canvas>', {'class':'mw-fw-canvas', 'aria-hidden':'true'});
Zeile 449: Zeile 445:
       var $ok = $('<button>', {'class':'mw-popup-close', type:'button'}).text('OK');
       var $ok = $('<button>', {'class':'mw-popup-close', type:'button'}).text('OK');
       $buttons.append($ok);
       $buttons.append($ok);
       if (CONFIG.cta && CONFIG.cta.url) {
       if (CONFIG.cta && CONFIG.cta.url) {
         $buttons.append($('<a>', {
         $buttons.append($('<a>', {
           'class':'mw-popup-wiki-button',
           'class':'mw-popup-wiki-button',
           'href': CONFIG.cta.url,
           'href': CONFIG.cta.url,
           'target':'_blank',
           'target': '_blank',
           'rel':'noopener'
           'rel': 'noopener'
         }).text(CONFIG.cta.text || 'Mehr'));
         }).text(CONFIG.cta.text || 'Mehr'));
       }
       }
Zeile 461: Zeile 456:
       $modal.append($fwWrap, $title, $content, $buttons);
       $modal.append($fwWrap, $title, $content, $buttons);
       $('body').append($overlay, $modal);
       $('body').append($overlay, $modal);
      // Fokus
      setTimeout(function(){ try{$modal.attr('tabindex','-1').focus();}catch(e){} }, 0);


       function close(){
       function close(){
Zeile 480: Zeile 472:
       }
       }


       // ==== Fireworks (Canvas) ====
       // ==== Fireworks mit "ADOS" Text ====
       var canvas = $canvas[0], ctx = canvas.getContext('2d');
       var canvas = $canvas[0], ctx = canvas.getContext('2d');
       var dpr = Math.max(1, window.devicePixelRatio || 1);
       var dpr = Math.max(1, window.devicePixelRatio || 1);
       var w=0,h=0, raf=null, particles=[], bursts=[];
       var w=0,h=0, raf=null, particles=[], startTime=0;
       var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
       var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;


Zeile 494: Zeile 486:
         canvas.style.height = rect.height+'px';
         canvas.style.height = rect.height+'px';
       }
       }
       function rand(min,max){ return Math.random()*(max-min)+min; }
       function rand(min,max){ return Math.random()*(max-min)+min; }
       function hsla(h,s,l,a){ return 'hsla('+h+','+s+'%,'+l+'%,'+a+')'; }
       function hsla(h,s,l,a){ return 'hsla('+h+','+s+'%,'+l+'%,'+a+')'; }
Zeile 512: Zeile 505:
         }
         }
       }
       }
       function tick(){
 
         ctx.clearRect(0,0,w,h);
       function drawADOS(t){
         // leichte Verdunkelung für Nachleuchten
         ctx.save();
        ctx.globalCompositeOperation = 'lighter';
        ctx.font = 'bold 64px "Segoe UI", Arial, sans-serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        var alpha = Math.max(0, 1 - t/3500); // blendet nach 3,5s aus
        ctx.fillStyle = 'rgba(255,255,255,'+alpha.toFixed(2)+')';
        ctx.shadowColor = 'hsl(' + ((t/20)%360) + ',100%,60%)';
        ctx.shadowBlur = 20;
        ctx.fillText('ADOS', w/2, h/2);
        ctx.restore();
      }
 
      function tick(t){
         ctx.fillStyle = 'rgba(0,0,0,0.08)';
         ctx.globalCompositeOperation = 'source-over';
         ctx.globalCompositeOperation = 'source-over';
        ctx.fillStyle = 'rgba(0,0,0,0.08)';
         ctx.fillRect(0,0,w,h);
         ctx.fillRect(0,0,w,h);


Zeile 524: Zeile 530:
           var p = particles[i];
           var p = particles[i];
           p.age++;
           p.age++;
          // Schwerkraft + Dämpfung
           p.vy += 0.02;
           p.vy += 0.02;
           p.vx *= 0.99; p.vy *= 0.99;
           p.vx *= 0.99; p.vy *= 0.99;
           p.x += p.vx*dpr; p.y += p.vy*dpr;
           p.x += p.vx*dpr; p.y += p.vy*dpr;
           var alpha = Math.max(0, 1 - p.age/p.life);
           var alpha = Math.max(0, 1 - p.age/p.life);
           if (alpha > 0){
           if (alpha>0){
             ctx.beginPath();
             ctx.beginPath();
             ctx.fillStyle = hsla(p.hue, 100, 60, alpha);
             ctx.fillStyle = hsla(p.hue,100,60,alpha);
             ctx.arc(p.x, p.y, Math.max(0.5, 2*alpha), 0, Math.PI*2);
             ctx.arc(p.x,p.y,Math.max(0.5,2*alpha),0,Math.PI*2);
             ctx.fill();
             ctx.fill();
             next.push(p);
             next.push(p);
Zeile 538: Zeile 543:
         }
         }
         particles = next;
         particles = next;
        // ADOS in den ersten 3,5 Sekunden anzeigen
        var elapsed = t - startTime;
        if (elapsed < 3500) drawADOS(elapsed);


         // regelmäßig neue Bursts
         // regelmäßig neue Bursts
         if (Math.random() < 0.08) {
         if (elapsed > 500 && Math.random() < 0.08) {
           var bx = rand(w*0.15, w*0.85);
           var bx = rand(w*0.15, w*0.85);
           var by = rand(h*0.2,  h*0.6);
           var by = rand(h*0.2,  h*0.6);
           spawnBurst(bx, by);
           spawnBurst(bx, by);
         }
         }
         raf = requestAnimationFrame(tick);
         raf = requestAnimationFrame(tick);
       }
       }
       function startFireworks(){
       function startFireworks(){
         if (reduceMotion) return; // respektiert Nutzerpräferenz
         if (reduceMotion) return;
         resize();
         resize();
         // Initial 2 Bursts
         startTime = performance.now();
         spawnBurst(w*0.3, h*0.45);
         spawnBurst(w*0.3, h*0.45);
         spawnBurst(w*0.7, h*0.35);
         spawnBurst(w*0.7, h*0.35);
Zeile 562: Zeile 573:


       startFireworks();
       startFireworks();
      // Direkt als gesehen markieren, damit reload am selben Tag nicht neu zeigt
       markSeen();
       markSeen();
     });
     });
   })(jQuery, mw);
   })(jQuery, mw);
});
});