function getModFolder() { return window.location.pathname .split('/') .pop() .replace('.html', ''); } function loadDescription(lang){ const file = `${getModFolder()}/description.txt`; fetch(file) .then(res => res.text()) .then(text => { document.getElementById('aboutText').innerHTML = parseText(text, lang); }) .catch(() => { document.getElementById('aboutText').innerText = '[ERROR]Failed to load description'; }); } function parseText(text, lang) { text = text.replace(/\r\n/g, '\n'); const lines = text.split('\n'); let currentColor = null; let inList = false; const colorMap = { red: 'red', orange: 'orange', yellow: 'yellow', lightgreen: 'lightgreen', green: 'green', blue: 'lightblue', purple: 'purple', pink: 'pink', normal: 'yellow', gray: 'gray', black: 'black' }; // Список тегов, строки с которыми нужно пропускать целиком const skipTags = ['green']; // можно добавить другие, например: 'red', 'blue' и т.д. let html = ''; lines.forEach((line, index) => { if (index === 0 || index === 1 || index === 2 || index === 3) return; if ((index === 4 || index === 5) && lang !== 'ru') return; if ((index === 6 || index === 7) && lang !== 'en') return; if (line.trim() === '') { html += '
'; return; } line = line.trim(); const tags = line.match(/^(\[[^\]]+\])+/); // ПРОВЕРКА НА ПРОПУСК СТРОКИ let shouldSkip = false; if (tags) { const tagList = tags[0].match(/\[([^\]]+)\]/g) || []; tagList.forEach(tag => { const clean = tag.replace(/[\[\]]/g, ''); if (skipTags.includes(clean)) { shouldSkip = true; } }); } // Если строка начинается с пропускаемого тега - пропускаем её if (shouldSkip) { return; } if (tags) { const tagList = tags[0].match(/\[([^\]]+)\]/g) || []; tagList.forEach(tag => { const clean = tag.replace(/[\[\]]/g, ''); if (colorMap[clean]) { currentColor = colorMap[clean]; line = line.replace(tag, ''); } }); } if (line.toLowerCase().includes('load order')) { const title = lang === 'ru' ? 'Порядок Загрузки:' : line; html += `
${title}
`; html += `'; return html; } // animations.js // Анимации плавного появления элементов при загрузке страницы (function() { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initAnimations); } else { initAnimations(); } function initAnimations() { const style = document.createElement('style'); style.textContent = ` .fade-animate-init { opacity: 0 !important; transform: translateY(20px) !important; } .fade-left-init { opacity: 0 !important; transform: translateX(-15px) !important; } .fade-scale-init { opacity: 0 !important; transform: scale(0.95) !important; } `; document.head.appendChild(style); // Функция для временной анимации (transition удаляется после показа) function animateWithCleanup(element, className, delay, duration = 0.3) { if (!element) return; element.classList.add(className); element.style.transition = `opacity ${duration}s ease, transform ${duration}s ease`; setTimeout(() => { element.classList.remove(className); element.style.opacity = '1'; element.style.transform = ''; // Удаляем transition через небольшую задержку setTimeout(() => { element.style.transition = ''; }, duration * 1000 + 50); }, delay); } // Навигация и шапка (быстро) animateWithCleanup(document.querySelector('#backBtn'), 'fade-animate-init', 30, 0.2); animateWithCleanup(document.querySelector('.nav'), 'fade-animate-init', 50, 0.25); animateWithCleanup(document.querySelector('.dwlbtn'), 'fade-animate-init', 70, 0.25); animateWithCleanup(document.querySelector('.lang'), 'fade-animate-init', 90, 0.25); // Заголовки и описание animateWithCleanup(document.querySelector('.title'), 'fade-animate-init', 120, 0.3); animateWithCleanup(document.querySelector('.desc'), 'fade-animate-init', 150, 0.3); animateWithCleanup(document.querySelector('.banner'), 'fade-scale-init', 180, 0.35); // Изображения const images = document.querySelectorAll('.banner img'); images.forEach((img, idx) => { img.style.opacity = '0'; img.style.transition = 'opacity 1s ease'; setTimeout(() => { img.style.opacity = '1'; setTimeout(() => img.style.transition = '', 1000); }, 200 + idx * 60); }); // Секции и info-box const sections = document.querySelectorAll('.section'); sections.forEach((el, i) => animateWithCleanup(el, 'fade-animate-init', 220 + i * 80, 0.3)); const infoBoxes = document.querySelectorAll('.info-box'); infoBoxes.forEach((box, i) => { animateWithCleanup(box, 'fade-animate-init', 280 + i * 100, 0.3); const headers = box.querySelectorAll('h2'); headers.forEach((h, hi) => animateWithCleanup(h, 'fade-left-init', 300 + i * 100 + hi * 40, 0.25)); const texts = box.querySelectorAll('p, .info-text'); texts.forEach((t, ti) => animateWithCleanup(t, 'fade-left-init', 320 + i * 100 + ti * 50, 0.25)); }); // Блок загрузки const downloadBlock = document.querySelector('.download-block'); animateWithCleanup(downloadBlock, 'fade-animate-init', 520, 0.3); const dlBtns = document.querySelectorAll('.download-block .btn'); dlBtns.forEach((btn, i) => animateWithCleanup(btn, 'fade-scale-init', 560 + i * 60, 0.25)); // Нижние кнопки const bottomDiv = document.querySelector('.bottom-buttons'); animateWithCleanup(bottomDiv, 'fade-animate-init', 620, 0.3); const bottomBtns = document.querySelectorAll('.bottom-buttons .btn'); bottomBtns.forEach((btn, i) => animateWithCleanup(btn, 'fade-scale-init', 650 + i * 60, 0.25)); // Версия const versionDiv = document.querySelector('.version'); animateWithCleanup(versionDiv, 'fade-animate-init', 700, 0.3); animateWithCleanup(document.querySelector('.version-title'), 'fade-left-init', 730, 0.25); animateWithCleanup(document.querySelector('.changelog'), 'fade-left-init', 760, 0.3); animateWithCleanup(document.querySelector('.version .btn'), 'fade-scale-init', 800, 0.25); // Кнопка аддонов animateWithCleanup(document.querySelector('#addonBtn'), 'fade-scale-init', 680, 0.25); // Остальные тексты и заголовки (без накопления transition) const extraTexts = document.querySelectorAll('p:not(.info-box p), .changelog, #creditsText, #infoText, #aboutText'); extraTexts.forEach((txt, i) => { if (txt && !txt.closest('.info-box') && !txt.closest('.version')) { txt.style.opacity = '0'; txt.style.transform = 'translateY(8px)'; txt.style.transition = 'opacity 1s ease, transform 1s ease'; setTimeout(() => { txt.style.opacity = '1'; txt.style.transform = 'translateY(0)'; setTimeout(() => txt.style.transition = '', 400); }, 340 + i * 30); } }); // Удаляем временные стили через 2 секунды setTimeout(() => style.remove(), 2000); } })(); // Синхронизация всех select с выбором языка function syncLangSelects() { const selects = document.querySelectorAll('#langSelect'); const currentLang = localStorage.getItem('lang') || 'ru'; selects.forEach(select => { if (select.value !== currentLang) { select.value = currentLang; } }); } // Вызываем синхронизацию при загрузке страницы document.addEventListener('DOMContentLoaded', function() { syncLangSelects(); }); // Также синхронизируем при изменении языка любым из select'ов function setupLangSync() { const selects = document.querySelectorAll('#langSelect'); selects.forEach(select => { select.addEventListener('change', function(e) { const newLang = e.target.value; localStorage.setItem('lang', newLang); // Обновляем все остальные select'ы selects.forEach(otherSelect => { if (otherSelect !== select) { otherSelect.value = newLang; } }); // Вызываем функцию смены языка if (typeof setLang === 'function') { setLang(newLang); } }); }); } // Запускаем синхронизацию после загрузки DOM if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { syncLangSelects(); setupLangSync(); }); } else { syncLangSelects(); setupLangSync(); } (function() { const SCROLL_HIDE_POINT = 60; const SCROLL_SHOW_POINT = 60; const header = document.querySelector("header"); const leftPanel = document.querySelector(".left-panel"); const rightPanel = document.querySelector(".right-panel"); window.addEventListener("scroll", () => { const scrollY = window.pageYOffset; // При скролле вниз if (scrollY > SCROLL_HIDE_POINT) { if (header) header.classList.add("hide"); if (leftPanel) leftPanel.classList.add("show"); if (rightPanel) rightPanel.classList.add("show"); } // При скролле вверх (в начало страницы) if (scrollY < SCROLL_SHOW_POINT) { if (header) header.classList.remove("hide"); if (leftPanel) leftPanel.classList.remove("show"); if (rightPanel) rightPanel.classList.remove("show"); } }); })(); // Анимация при смене языка (минимальная, без сохранения transition) function animateLanguageChange() { const els = document.querySelectorAll('.info-box, .version, .download-block, .title, .desc, .section'); els.forEach(el => { if (!el) return; const oldTrans = el.style.transition; el.style.transition = 'opacity 1s ease'; el.style.opacity = '0.7'; setTimeout(() => { el.style.opacity = ''; setTimeout(() => { if (el.style.transition === 'opacity 1s ease') el.style.transition = oldTrans; }, 200); }, 100); }); } // Плавное обновление текста function smoothTextUpdate(el, newText) { if (!el) return; const oldTrans = el.style.transition; el.style.transition = 'opacity 1s ease'; el.style.opacity = '0'; setTimeout(() => { if (typeof newText === 'string') el.innerHTML = newText; el.style.opacity = '1'; setTimeout(() => el.style.transition = oldTrans, 150); }, 100); } // Перехват setLang const originalSetLang = window.setLang; if (originalSetLang) { window.setLang = function(lang) { animateLanguageChange(); setTimeout(() => originalSetLang(lang), 50); }; } function goBack(){ const last = localStorage.getItem('lastPage'); if(last){ window.location.href = "../mods.html"; window.close(); } else { window.location.href = "../mods.html"; } }