feat(05-02): wire forest navigation handlers and fade animation
- Add saveProgress import to scene.ts - Wire prevBtn/nextBtn onclick handlers in initForestScreen - Persist currentForestPage to IndexedDB on every navigation - Add fade-out/fade-in opacity transition on page changes
This commit is contained in:
+40
-2
@@ -1,6 +1,6 @@
|
||||
import type { Progress, LevelStatus } from "../types";
|
||||
import { levels } from "../game/levels";
|
||||
import { getProgress, getForestElements } from "../storage/db";
|
||||
import { getProgress, getForestElements, saveProgress } from "../storage/db";
|
||||
import { playForestElementSound } from "../audio/sounds";
|
||||
|
||||
let activeObjectUrls: string[] = [];
|
||||
@@ -21,6 +21,10 @@ export async function renderForestScene(
|
||||
}
|
||||
activeObjectUrls = [];
|
||||
|
||||
// Fade out before clearing
|
||||
grid.style.opacity = "0";
|
||||
grid.style.transition = "opacity 0.3s ease";
|
||||
|
||||
const elements = await getForestElements(db);
|
||||
grid.innerHTML = "";
|
||||
|
||||
@@ -56,6 +60,11 @@ export async function renderForestScene(
|
||||
grid.appendChild(slot);
|
||||
}
|
||||
|
||||
// Trigger fade-in after a frame
|
||||
requestAnimationFrame(() => {
|
||||
grid.style.opacity = "1";
|
||||
});
|
||||
|
||||
// Update navigation UI
|
||||
const totalPages = Math.max(1, Math.ceil(elements.length / SLOTS_PER_PAGE));
|
||||
const navContainer = document.getElementById("forest-nav");
|
||||
@@ -139,9 +148,38 @@ export async function initForestScreen(
|
||||
if (!progress) return;
|
||||
|
||||
renderLevelMap(mapContainer, progress, onStartLesson);
|
||||
const currentPage = progress.currentForestPage ?? 0;
|
||||
let currentPage = progress.currentForestPage ?? 0;
|
||||
await renderForestScene(db, currentPage);
|
||||
|
||||
// Wire navigation buttons
|
||||
const prevBtn = document.getElementById("forest-nav-prev") as HTMLButtonElement;
|
||||
const nextBtn = document.getElementById("forest-nav-next") as HTMLButtonElement;
|
||||
|
||||
const navigateToPage = async (newPage: number) => {
|
||||
currentPage = newPage;
|
||||
await renderForestScene(db, currentPage);
|
||||
// Persist page in progress
|
||||
const freshProgress = await getProgress(db);
|
||||
if (freshProgress) {
|
||||
freshProgress.currentForestPage = currentPage;
|
||||
await saveProgress(db, freshProgress);
|
||||
}
|
||||
};
|
||||
|
||||
if (prevBtn) {
|
||||
prevBtn.onclick = () => {
|
||||
if (currentPage > 0) navigateToPage(currentPage - 1);
|
||||
};
|
||||
}
|
||||
|
||||
if (nextBtn) {
|
||||
nextBtn.onclick = async () => {
|
||||
const elements = await getForestElements(db);
|
||||
const totalPages = Math.max(1, Math.ceil(elements.length / SLOTS_PER_PAGE));
|
||||
if (currentPage < totalPages - 1) navigateToPage(currentPage + 1);
|
||||
};
|
||||
}
|
||||
|
||||
const allComplete = levels.every((l) =>
|
||||
progress.completedLevels.includes(l.level),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user