|
značky: nahrazeno ruční vrácení zpět |
| Řádek 1: |
Řádek 1: |
| /* Zde uvedený JavaScript bude použit pro všechny uživatele při načtení každé stránky */ | | /* 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);
| |
| });
| |
| });
| |
| })();
| |