Files
dinner.tootaio.com/20250916/ppt/js/ppt.js
2025-09-15 00:28:27 +08:00

97 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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);
}
});
}