97 lines
2.9 KiB
JavaScript
97 lines
2.9 KiB
JavaScript
// 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);
|
||
}
|
||
});
|
||
}
|