DP-Logopedicka-Platforma/js/worldsmenu-preloader.js
2026-04-23 15:41:11 +02:00

450 lines
13 KiB
JavaScript

/**
* WorldsMenu Preloader s Cache API
* Zabezpečuje rýchle načítanie obrázkov a ich uloženie do cache
* Autor: Adam Reňak
*/
// ==========================================
// GLOBÁLNE PREMENNÉ PRE PRELOADING
// ==========================================
// Verzia cache - zvýš túto hodnotu pri zmenách obrázkov
const CACHE_VERSION = 'worldsmenu-v1.4';
const CACHE_NAME = `banik-jozino-${CACHE_VERSION}`;
// Cache pre prednačítané obrázky (in-memory cache)
let preloadedImages = {};
// Progress tracking
let totalResources = 0;
let loadedResources = 0;
let isPreloadingComplete = false;
// ==========================================
// HLAVNÁ FUNKCIA PRELOADINGU
// ==========================================
/**
* Spustenie preloadingu všetkých potrebných zdrojov
*/
async function startWorldsMenuPreloading() {
try {
console.log('🚀 Spúšťam preloading pre worlds menu...');
// 1. Získaj všetky obrázky na načítanie
const imagesToLoad = collectAllWorldsMenuImages();
totalResources = imagesToLoad.length;
console.log(`📦 Celkovo ${totalResources} obrázkov na načítanie`);
updateLoadingMessage('Kontrolujem cache...');
// 2. Skontroluj a vyčisti staré cache
await cleanOldCaches();
// 3. Načítaj všetky obrázky (paralelne)
updateLoadingMessage('Načítavam obrázky...');
const promises = imagesToLoad.map(imagePath => preloadImageWithCache(imagePath));
await Promise.all(promises);
console.log('✅ Všetky obrázky načítané a uložené do cache!');
isPreloadingComplete = true;
// 4. Skry loading screen
setTimeout(() => {
hideLoadingScreen();
}, 500);
} catch (error) {
console.error('❌ Chyba pri preloadingu:', error);
// Aj pri chybe pokračuj - nech sa stránka zobrazí
setTimeout(() => {
hideLoadingScreen();
}, 1000);
}
}
// ==========================================
// ZBER OBRÁZKOV NA NAČÍTANIE
// ==========================================
/**
* Zbiera všetky obrázky potrebné pre worlds menu
*/
function collectAllWorldsMenuImages() {
const images = [];
// ==========================================
// 1. OBRÁZKY SVETOV
// ==========================================
console.log('📂 Zbierame obrázky svetov...');
// Získaj konfiguráciu svetov (ak existuje)
if (typeof WORLDS_CONFIG !== 'undefined') {
WORLDS_CONFIG.forEach(world => {
// Použij icon z konfigurácie - má už správnu cestu a príponu
if (world.icon) {
images.push(world.icon);
}
});
console.log(` ✅ Pridaných ${WORLDS_CONFIG.length} world obrázkov`);
}
// ==========================================
// 2. UI ELEMENTY
// ==========================================
console.log('📂 Zbierame UI elementy...');
const uiImages = [
// Hviezdy
'images/star_active.png',
'images/star_inactive.png',
// Level ikony
'images/banik-icon.png',
'images/pexeso-icon.png',
// Cursory
'images/cursor.png',
'images/active_cursor4.png',
// Pozadia
'images/pozadie.jpg',
'images/worlds/background.jpg',
// Menu buttony
'images/menubutton.png'
];
images.push(...uiImages);
console.log(` ✅ Pridaných ${uiImages.length} UI obrázkov`);
// ==========================================
// 3. LEVEL IKONY (ak existuje konfigurácia)
// ==========================================
if (typeof LEVELS_CONFIG !== 'undefined') {
console.log('📂 Zbierame level ikony...');
let levelIconsCount = 0;
// Pre každý svet
Object.keys(LEVELS_CONFIG).forEach(worldId => {
const worldLevels = LEVELS_CONFIG[worldId] || [];
// Pre každý level
worldLevels.forEach(level => {
// Pridaj ikonu levelu ak existuje
if (level.icon) {
images.push(level.icon);
levelIconsCount++;
}
});
});
console.log(` ✅ Pridaných ${levelIconsCount} level ikon`);
}
// ==========================================
// 4. ODSTRÁNENIE DUPLIKÁTOV
// ==========================================
const uniqueImages = [...new Set(images)];
console.log(`📦 Celkovo ${uniqueImages.length} unikátnych obrázkov (z ${images.length})`);
return uniqueImages;
}
// ==========================================
// NAČÍTANIE OBRÁZKA S CACHE
// ==========================================
/**
* Načíta obrázok s podporou Cache API
* Najprv kontroluje cache, potom sieť
*/
async function preloadImageWithCache(imagePath) {
try {
// 1. Skús načítať z cache
const cachedImage = await loadFromCache(imagePath);
if (cachedImage) {
console.log(`💾 Z cache: ${imagePath}`);
preloadedImages[imagePath] = cachedImage;
updateProgress();
return cachedImage;
}
// 2. Ak nie je v cache, načítaj zo siete
console.log(`🌐 Zo siete: ${imagePath}`);
const image = await loadImageFromNetwork(imagePath);
// 3. Ulož do cache
if (image) {
await saveToCache(imagePath, image);
preloadedImages[imagePath] = image;
}
updateProgress();
return image;
} catch (error) {
console.warn(`⚠️ Chyba pri načítaní ${imagePath}:`, error);
updateProgress();
return null;
}
}
/**
* Načítanie obrázka z cache
*/
async function loadFromCache(imagePath) {
try {
// Otvor cache
const cache = await caches.open(CACHE_NAME);
// Vytvor plnú URL
const fullUrl = new URL(imagePath, window.location.href).href;
// Pokús sa načítať z cache
const response = await cache.match(fullUrl);
if (response) {
// Vytvor Image objekt z cache response
const blob = await response.blob();
const imageUrl = URL.createObjectURL(blob);
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => resolve(null);
img.src = imageUrl;
});
}
return null;
} catch (error) {
console.warn(`Cache read error for ${imagePath}:`, error);
return null;
}
}
/**
* Načítanie obrázka zo siete
*/
function loadImageFromNetwork(imagePath) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => {
console.log(`✅ Načítaný: ${imagePath}`);
resolve(img);
};
img.onerror = () => {
console.warn(`⚠️ Chyba načítania: ${imagePath}`);
resolve(null);
};
img.src = imagePath;
});
}
/**
* Uloženie obrázka do cache
*/
async function saveToCache(imagePath, image) {
try {
// Otvor cache
const cache = await caches.open(CACHE_NAME);
// Vytvor plnú URL
const fullUrl = new URL(imagePath, window.location.href).href;
// Načítaj obrázok ako blob
const response = await fetch(imagePath);
if (response.ok) {
// Ulož do cache
await cache.put(fullUrl, response);
console.log(`💾 Uložené do cache: ${imagePath}`);
}
} catch (error) {
console.warn(`Cache save error for ${imagePath}:`, error);
}
}
// ==========================================
// SPRÁVA CACHE
// ==========================================
/**
* Vyčistenie starých verzií cache
*/
async function cleanOldCaches() {
try {
console.log('🧹 Čistím staré cache...');
// Získaj všetky cache names
const cacheNames = await caches.keys();
// Vymaž všetky okrem aktuálnej verzie
const deletionPromises = cacheNames
.filter(cacheName => cacheName.startsWith('banik-jozino-') && cacheName !== CACHE_NAME)
.map(cacheName => {
console.log(`🗑️ Mažem starú cache: ${cacheName}`);
return caches.delete(cacheName);
});
await Promise.all(deletionPromises);
console.log('✅ Staré cache vyčistené');
} catch (error) {
console.warn('Chyba pri čistení cache:', error);
}
}
/**
* Kontrola veľkosti cache
*/
async function getCacheSize() {
try {
const cache = await caches.open(CACHE_NAME);
const keys = await cache.keys();
let totalSize = 0;
for (const request of keys) {
const response = await cache.match(request);
if (response) {
const blob = await response.blob();
totalSize += blob.size;
}
}
// Konvertuj na MB
const sizeMB = (totalSize / (1024 * 1024)).toFixed(2);
console.log(`📊 Cache veľkosť: ${sizeMB} MB (${keys.length} súborov)`);
return { totalSize, itemCount: keys.length, sizeMB };
} catch (error) {
console.warn('Chyba pri získavaní veľkosti cache:', error);
return { totalSize: 0, itemCount: 0, sizeMB: 0 };
}
}
/**
* Vymazanie celej cache (pre debugging)
*/
async function clearAllCache() {
try {
const deleted = await caches.delete(CACHE_NAME);
console.log(deleted ? '✅ Cache vymazaná' : '❌ Cache sa nepodarilo vymazať');
return deleted;
} catch (error) {
console.error('Chyba pri mazaní cache:', error);
return false;
}
}
// ==========================================
// PROGRESS TRACKING
// ==========================================
/**
* Aktualizácia progress baru
*/
function updateProgress() {
loadedResources++;
// Vypočítaj percento
const percentage = Math.round((loadedResources / totalResources) * 100);
// Aktualizuj progress message
updateLoadingMessage(`Načítavam... ${percentage}%`);
// Detailný log každých 10%
if (loadedResources % Math.ceil(totalResources / 10) === 0 || loadedResources === totalResources) {
console.log(`📊 Progress: ${percentage}% (${loadedResources}/${totalResources})`);
}
}
/**
* Aktualizácia loading message
*/
function updateLoadingMessage(message) {
const loadingMessage = document.getElementById('loading-message');
if (loadingMessage) {
loadingMessage.textContent = message;
}
}
/**
* Skrytie loading screenu s animáciou
*/
function hideLoadingScreen() {
const loadingScreen = document.getElementById('loading-screen');
if (loadingScreen) {
console.log('👋 Skrývam loading screen...');
loadingScreen.style.opacity = '0';
setTimeout(() => {
loadingScreen.style.display = 'none';
console.log('✅ Loading screen skrytý, stránka pripravená!');
}, 500);
}
}
// ==========================================
// POMOCNÉ FUNKCIE
// ==========================================
/**
* Získanie prednačítaného obrázka
*/
function getPreloadedImage(imagePath) {
return preloadedImages[imagePath] || null;
}
/**
* Kontrola či je preloading dokončený
*/
function isPreloadingDone() {
return isPreloadingComplete;
}
// ==========================================
// DEBUG FUNKCIE
// ==========================================
/**
* Debug informácie o cache
*/
async function debugCacheInfo() {
console.log('=== CACHE DEBUG INFO ===');
console.log('Cache verzia:', CACHE_VERSION);
console.log('Cache name:', CACHE_NAME);
const size = await getCacheSize();
console.log('Cache veľkosť:', size.sizeMB, 'MB');
console.log('Počet súborov:', size.itemCount);
console.log('Načítané obrázky v pamäti:', Object.keys(preloadedImages).length);
console.log('Preloading dokončený:', isPreloadingComplete);
console.log('========================');
}
// ==========================================
// EXPORT PRE POUŽITIE V INÝCH SÚBOROCH
// ==========================================
if (typeof window !== 'undefined') {
window.startWorldsMenuPreloading = startWorldsMenuPreloading;
window.getPreloadedImage = getPreloadedImage;
window.isPreloadingDone = isPreloadingDone;
window.preloadedImages = preloadedImages;
// Debug funkcie
window.debugCacheInfo = debugCacheInfo;
window.clearAllCache = clearAllCache;
window.getCacheSize = getCacheSize;
}
console.log('✅ WorldsMenu Preloader načítaný a pripravený');