// js/ppt.js // Banquet PPT 入口:读取 config,加载模板,渲染幻灯片到 DOM // 依赖:loader.js 提供的 loadTemplateByName/render/loadOverrideCss import { loadTemplateByName, render, loadOverrideCss } from "./loader.js"; /** * 渲染整个宴会演示文稿 * @param {string} configPath - 配置文件路径 (例如 '/config/banquet.json') * @param {string} manifestPath - 模板 manifest 路径 (例如 '/templates/manifest.json') * @param {string} mountSelector - 容器选择器,渲染幻灯片的 DOM 节点 */ export async function renderBanquet( configPath = "config/banquet.json", manifestPath = "templates/manifest.json", mountSelector = "#app" ) { // 读取配置 const res = await fetch(configPath); if (!res.ok) throw new Error(`无法加载配置文件: ${configPath} (${res.status})`); const config = await res.json(); const container = document.querySelector(mountSelector); if (!container) throw new Error(`容器未找到: ${mountSelector}`); container.innerHTML = ""; // 存储每个 slide 对应的 CSS link const overrideLinks = []; // 遍历 config.slides 渲染 for (const [idx, slide] of config.slides.entries()) { const { template, data = {}, overrideCss } = slide; // 加载模板 const tpl = await loadTemplateByName(manifestPath, template); // 注入实例级 override CSS(如果配置了) let cssLink = null; if (overrideCss) { cssLink = loadOverrideCss(overrideCss); // 获取 link 元素 } // 渲染 HTML const html = render(tpl.html, data, { allowRaw: true }); // 创建 slide 容器 const slideEl = document.createElement("section"); slideEl.classList.add("banquet-slide"); slideEl.dataset.index = idx; slideEl.innerHTML = html; // 如果配置了背景,应用背景图 if (slide.background) { slideEl.style.backgroundImage = `url('${slide.background}')`; slideEl.style.backgroundSize = "cover"; slideEl.style.backgroundPosition = "center"; } container.appendChild(slideEl); overrideLinks[idx] = cssLink; // 保存起来 } // 简单导航(可扩展) initNavigation(container, overrideLinks); } /** * 初始化键盘翻页逻辑 */ function initNavigation(container, overrideLinks) { let current = 0; const slides = container.querySelectorAll(".banquet-slide"); function showSlide(i) { slides.forEach((s, idx) => { s.style.display = idx === i ? "block" : "none"; }); // 动态切换 CSS:只让当前 slide 的 override 生效 overrideLinks.forEach((link, idx) => { if (link) link.disabled = idx !== i; }); current = i; } showSlide(current); document.addEventListener("keydown", (e) => { if (e.key === "ArrowRight" || e.key === "PageDown") { if (current < slides.length - 1) showSlide(current + 1); } else if (e.key === "ArrowLeft" || e.key === "PageUp") { if (current > 0) showSlide(current - 1); } }); }