Toggle menu
Toggle preferences menu
Toggle personal menu
Nejste přihlášen(a)
Your IP address will be publicly visible if you make any edits.

MediaWiki:Citizen.js

MediaWiki interface page

Poznámka: Po zveřejnění musíte vyprázdnit cache vašeho prohlížeče, jinak změny neuvidíte.

  • Firefox / Safari: Při kliknutí na Aktualizovat držte Shift nebo stiskněte Ctrl-F5 nebo Ctrl-R (na Macu ⌘-R)
  • Google Chrome: Stiskněte Ctrl-Shift-R (na Macu ⌘-Shift-R)
  • Edge: Při kliknutí na Aktualizovat držte Ctrl nebo stiskněte Ctrl-F5.
/* Zde uvedený JavaScript bude použit pro všechny uživatele při načtení každé stránky */
/* eslint-disable no-var */
(function () {
  'use strict';

  // Nepouštět, když je preferováno omezení pohybu
  var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (reduceMotion) return;

  // Vytvoř kořenový overlay
  var root = document.createElement('div');
  root.id = 'spark-root';
  document.addEventListener('DOMContentLoaded', function () {
    document.body.appendChild(root);
  });

  // Paleta „magických“ barev (modrá, zlato, fialová, tyrkys)
  var COLORS = ['#7fb3ff', '#bb7e0e', '#c58cff', '#66e0ff', '#9ad1ff'];
  function pickColor(i) { return COLORS[i % COLORS.length]; }

  // Tvorba jedné jiskry
  function spawnSpark(x, y, opts) {
    var el = document.createElement('div');
    el.className = 'spark' + (opts && opts.burst ? ' burst' : '');
    el.style.left = x + 'px';
    el.style.top  = y + 'px';
    el.style.setProperty('--spark-color', (opts && opts.color) || pickColor(Math.floor(Math.random() * COLORS.length)));

    if (opts && opts.burst) {
      el.style.setProperty('--dx', (opts.dx || 0) + 'px');
      el.style.setProperty('--dy', (opts.dy || 0) + 'px');
    }

    root.appendChild(el);

    var ttl = opts && opts.ttl ? opts.ttl : 1000;
    setTimeout(function () {
      if (el && el.parentNode) el.parentNode.removeChild(el);
    }, ttl);
  }

  // Throttle pro mousemove, aby to bylo lehké
  var lastMove = 0;
  function onMove(ev) {
    var now = performance.now();
    if (now - lastMove < 40) return; // cca 25/s
    lastMove = now;

    var x = ev.clientX, y = ev.clientY;
    spawnSpark(x, y, { ttl: 900 });
  }

  // Burst při click/touch
  function burstAt(x, y) {
    var n = 12;                          // počet jisker
    var speed = 60;                      // px
    for (var i = 0; i < n; i++) {
      var ang = (Math.PI * 2 * i) / n + (Math.random() * 0.6 - 0.3);
      var r   = speed * (0.7 + Math.random() * 0.6);
      var dx  = Math.cos(ang) * r;
      var dy  = Math.sin(ang) * r;
      spawnSpark(x, y, { burst: true, dx: dx, dy: dy, ttl: 1000 });
    }
  }

  // Handlery
  function pointerWithinViewport(ev) {
    // ignorovat v iframu/VE—CSS to už skrývá, ale pro jistotu
    if (!root.parentNode) return;
    onMove(ev);
  }

  // Připojit po načtení DOMu (kvůli rootu)
  document.addEventListener('DOMContentLoaded', function () {
    document.addEventListener('mousemove', pointerWithinViewport, { passive: true });
    document.addEventListener('pointerdown', function (ev) {
      burstAt(ev.clientX, ev.clientY);
    }, { passive: true });

    // Dotyk – lehká podpora
    document.addEventListener('touchstart', function (ev) {
      var t = ev.changedTouches && ev.changedTouches[0];
      if (t) burstAt(t.clientX, t.clientY);
    }, { passive: true });

    // Úklid při navigaci (SPA přechody apod.)
    window.addEventListener('beforeunload', function () {
      document.removeEventListener('mousemove', pointerWithinViewport);
    });
  });
})();