📜 読み込み中...
"}]}; // IndexedDBに音声・画像をキャッシュ const DB_NAME='atelchemia_Story 1111'; const DB_VER=1; let db=null; function openDB(){ return new Promise((res,rej)=>{ const req=indexedDB.open(DB_NAME,DB_VER); req.onupgradeneeded=e=>e.target.result.createObjectStore('assets'); req.onsuccess=e=>{db=e.target.result;res(db);}; req.onerror=rej; }); } function saveAsset(key,blob){ return new Promise((res,rej)=>{ const tx=db.transaction('assets','readwrite'); tx.objectStore('assets').put(blob,key); tx.oncomplete=res; tx.onerror=rej; }); } function getAsset(key){ return new Promise((res,rej)=>{ const tx=db.transaction('assets','readonly'); const req=tx.objectStore('assets').get(key); req.onsuccess=e=>res(e.target.result); req.onerror=rej; }); } async function loadAsset(path){ try{ const cached=await getAsset(path); if(cached)return URL.createObjectURL(cached); const r=await fetch(path); if(!r.ok)return path; const blob=await r.blob(); await saveAsset(path,blob); return URL.createObjectURL(blob); }catch{return path;} } // レンダリング async function render(){ await openDB(); const main=document.getElementById('main'); const loading=document.getElementById('loading'); const cover=document.getElementById('cover'); const tabsEl=document.getElementById('tabs'); const pagesEl=document.getElementById('pages'); // カバー if(DATA.cover){ const url=await loadAsset(DATA.cover); cover.innerHTML=`cover

${DATA.title}

`; }else{ cover.innerHTML=`

${DATA.title}

`; } // ブロックをページ別に整理(kindがpage_breakで区切る) const pages=[[]]; for(const b of DATA.blocks){ if(b.kind==='page_break'){pages.push([]);} else{pages[pages.length-1].push(b);} } // タブ生成 pages.forEach((_,i)=>{ const btn=document.createElement('button'); btn.className='tab'+(i===0?' active':''); btn.textContent=`ページ ${i+1}`; btn.onclick=()=>switchPage(i); tabsEl.appendChild(btn); }); // ページ生成 for(let i=0;i`; }else if(b.kind==='audio'){ const url=await loadAsset(b.path); div.className='audio-block'; div.innerHTML=`
🎵 ${b.title||b.name||'音声'}
`; } sec.appendChild(div); } pagesEl.appendChild(sec); } loading.style.display='none'; main.style.display='block'; } function switchPage(idx){ document.querySelectorAll('.tab').forEach((t,i)=>t.classList.toggle('active',i===idx)); document.querySelectorAll('.page').forEach((p,i)=>p.classList.toggle('active',i===idx)); window.scrollTo(0,0); } render();