35 lines
1.7 KiB
JavaScript
35 lines
1.7 KiB
JavaScript
(() => {
|
|
const preference = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
const weather = document.createElement('div');
|
|
weather.className = 'ny-weather';
|
|
weather.setAttribute('aria-hidden', 'true');
|
|
const fragment = document.createDocumentFragment();
|
|
for (let i = 0; i < 32; i++) {
|
|
const flake = document.createElement('span');
|
|
flake.className = 'ny-flake' + (i % 6 === 0 ? ' ny-spark' : '');
|
|
flake.textContent = i % 6 === 0 ? '✦' : (i % 4 === 0 ? '❄' : '•');
|
|
flake.style.cssText = `--x:${(i * 37.7) % 100}%;--size:${i % 4 === 0 ? 14 : 7}px;--duration:${14 + (i % 9)}s;--delay:-${i * 1.9}s`;
|
|
fragment.append(flake);
|
|
}
|
|
weather.append(fragment);
|
|
const button = document.createElement('button');
|
|
button.type = 'button'; button.className = 'ny-motion';
|
|
let paused = preference.matches;
|
|
try { paused = preference.matches || localStorage.getItem('olapka_winter_paused') === 'true'; } catch (_) {}
|
|
function render() {
|
|
document.body.classList.toggle('ny-paused', paused);
|
|
button.textContent = paused ? '✦ Включить анимацию' : '❄ Остановить анимацию';
|
|
button.setAttribute('aria-pressed', String(!paused));
|
|
button.hidden = preference.matches;
|
|
}
|
|
button.addEventListener('click', () => {
|
|
paused = !paused; render();
|
|
try { localStorage.setItem('olapka_winter_paused', String(paused)); } catch (_) {}
|
|
});
|
|
preference.addEventListener('change', () => { paused = preference.matches; render(); });
|
|
document.addEventListener('visibilitychange', () => {
|
|
weather.style.display = document.hidden ? 'none' : '';
|
|
});
|
|
document.body.append(weather, button); render();
|
|
})();
|