PPT生成提示
归档记录,不对外
你现在的唯一任务:把我提供的任意文章生成“长图式PPT网页”。要求:每页等高、零重叠、分割线明显、视觉统一、全动态无硬编码。只输出一份完整可运行的 HTML(含 <!DOCTYPE html> 与 <html> ... </html>),不允许输出解释或多余文字。
========================
===ARTICLE===
(粘贴文章全文)
===END===
===PREFERENCES===(可选)
{
"primaryColor":"#0f172a",
"accentColor":"#60a5fa",
"slideHeight": 720,
"slideMaxWidth": 1280,
"slideMinWidth": 360,
"language":"zh-CN",
"maxSlides": 12,
"showAuthor": true,
"brandLogoUrl": ""
}
===END===
========================
【生成步骤(必须按序执行)】
1) 解析 ARTICLE,抽取:标题/副标题/要点/步骤/案例/数据/引语/行动清单/作者信息。缺项可合理推断,但不得编造具体人名与联系方式。
2) 规划分页:把内容拆成 6–10 页;每页最多 1 组标题 + 1 图表 + 3 张卡片(或 6 条列表)。若内容更长,新增 slide,禁止单页内滚动。
3) 为每个“可移动内容单元”外包一层 `<div class="block">...</div>`,用于自动分页兜底。
4) 输出 HTML,包含以下固定结构与样式、分割线、懒加载图表与自动分页脚本。
【页面骨架(必须包含以下关键 CSS 规则与类名)】
- 使用 Tailwind CDN、Font Awesome CDN、Chart.js CDN、Google Fonts(Noto Sans SC)。
- body 纵向滚动;每个 .slide 高度固定为 CSS 变量 `--slide-h`。
- 层级与防重叠:
- `.slide{ isolation:isolate; position:relative; z-index:0 }`
- 装饰层:`.bg-pattern,.decorative-circle{ position:absolute; z-index:1; pointer-events:none; }`
- 内容层:`.content-wrapper{ position:relative; z-index:2; display:flex; flex-direction:column; height:100%; }`
- 禁止项(不得出现在输出中):任何 `position:absolute` 用于内容布局;任何 `h-[calc(...)]`/`min-height` 强行填充内容区;负 margin;在 `.slide` 内部元素设置 `overflow:auto`。
- 分割线(必须双保险):
1) 在每两个 slide 之间输出 `<div class="sep" aria-hidden="true"></div>` 真实 DOM 分割线;
2) 同时在 CSS 提供 `.slide + .slide::before` 渐变分隔伪元素。
- 移动端:在 `@media (max-width:420px)` 将 `--slide-h` 降为 560px,缩小内边距并保持等高。
【必须包含的基础 CSS(可等价实现,但语义一致)】
<style>
:root{
--primary: var(--primary, #0f172a);
--accent: var(--accent, #60a5fa);
--slide-max-w: 1280px;
--slide-min-w: 360px;
--slide-h: 720px;
--sep-h: 10px; --sep-space: 48px;
}
*{box-sizing:border-box}
body{font-family:'Noto Sans SC',sans-serif;background:#0a192f;margin:0;padding:32px 0;color:#e2e8f0;overflow-y:auto;}
.slide{isolation:isolate;width:95%;max-width:var(--slide-max-w);min-width:var(--slide-min-w);height:var(--slide-h);
margin:32px auto 0;position:relative;border-radius:20px;overflow:hidden;color:#fff;
background:linear-gradient(140deg,var(--primary),#1e3a8a);
box-shadow:0 18px 48px rgba(2,6,23,.35), inset 0 0 0 1px rgba(255,255,255,.06);
display:flex;flex-direction:column;padding:28px 40px;}
.content-wrapper{position:relative;z-index:2;height:100%;display:flex;flex-direction:column;}
.header{flex:0 0 auto;padding-bottom:8px}
.main-content{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:16px}
.footer{flex:0 0 auto;padding-top:8px;background:rgba(0,0,0,.14)}
.block{background:rgba(255,255,255,.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.12);
border-radius:14px;padding:14px;box-shadow:0 8px 20px rgba(2,6,23,.25)}
.bg-pattern,.decorative-circle{position:absolute;z-index:1;opacity:.08}
.sep{height:var(--sep-h);width:90%;max-width:calc(var(--slide-max-w)*.9);margin:var(--sep-space) auto;border-radius:999px;
background:linear-gradient(90deg, rgba(96,165,250,.0) 0%, rgba(96,165,250,.9) 12%, rgba(191,219,254,1) 50%, rgba(96,165,250,.9) 88%, rgba(96,165,250,.0) 100%);
box-shadow:0 0 18px rgba(96,165,250,.45);}
.slide + .slide{margin-top:calc(32px + var(--sep-space));}
.slide + .slide::before{content:"";position:absolute;left:5%;width:90%;height:var(--sep-h);top:calc(-1 * var(--sep-space));
border-radius:999px;background:linear-gradient(90deg, rgba(96,165,250,.0), rgba(96,165,250,.85), rgba(191,219,254,.95), rgba(96,165,250,.85), rgba(96,165,250,.0));
box-shadow:0 0 18px rgba(96,165,250,.45);z-index:3}
@media (max-width:768px){ .slide{padding:20px} }
@media (max-width:420px){ :root{--slide-h:560px;} body{padding:20px 0} .slide{padding:16px} }
</style>
【图表与懒加载(必须)】
- 使用 IntersectionObserver(threshold≈0.2) 懒加载 `<canvas>`。
- `createGradient(ctx,h,hex)` 返回 `hex+"99"` → `hex+"1A"` 的竖向渐变字符串。
【自动分页兜底脚本(必须保留,弱模型也能复制)】
- 要求所有可拆分内容单元外层是 `.block`,脚本会把超出的 `.block` 移到“新建的下一页”直到不溢出。
<script>
document.addEventListener('DOMContentLoaded',()=>{
const mkSlide = ()=> {
const s = document.createElement('div');
s.className = 'slide';
s.innerHTML = `
<div class="bg-pattern"></div>
<div class="content-wrapper">
<div class="header"></div>
<div class="main-content"></div>
<div class="footer"></div>
</div>`;
return s;
};
function paginate(slide){
const wrap = slide.querySelector('.content-wrapper');
const head = slide.querySelector('.header');
const main = slide.querySelector('.main-content');
const foot = slide.querySelector('.footer');
const padV = parseFloat(getComputedStyle(slide).paddingTop) + parseFloat(getComputedStyle(slide).paddingBottom);
const avail = slide.clientHeight - padV - (head?.offsetHeight||0) - (foot?.offsetHeight||0) - 8;
const buffer=[];
while(main.scrollHeight > avail && main.children.length>1){
buffer.unshift(main.lastElementChild); // 从末尾开始搬
main.removeChild(main.lastElementChild);
}
if(buffer.length){
const sep = document.createElement('div'); sep.className='sep';
const next = mkSlide();
slide.after(sep); sep.after(next);
const nextMain = next.querySelector('.main-content');
buffer.forEach(el=> nextMain.appendChild(el));
paginate(next);
}
}
document.querySelectorAll('.slide').forEach(paginate);
// 懒加载图表
const cfg={threshold:0.2};
const io=new IntersectionObserver((es)=>{
es.forEach(e=>{
if(!e.isIntersecting) return;
const c=e.target; if(c.dataset.inited==='1') return;
const id=c.id; if(!window.__charts || !window.__charts[id]) { c.dataset.inited='1'; return; }
new Chart(c, window.__charts[id]); c.dataset.inited='1';
});
},cfg);
document.querySelectorAll('canvas').forEach(cv=>io.observe(cv));
});
</script>
【内容预算(强制,避免超高)】
- 每页:卡片 ≤ 3,或列表 ≤ 6 条;标题 ≤ 22 字;副标题 ≤ 26 字;单条列表 ≤ 20 字;引语 ≤ 26 字。
- 超出预算:新增 slide(或拆分为“续页”),不要缩到极小字号或放局部滚动条。
【自检清单(模型在返回前逐项确认,未满足不得输出)】
- [ ] 只输出 1 份完整 HTML;
- [ ] 所有 .slide 高度等于 `--slide-h`,无局部滚动条;
- [ ] 页间有 `<div class="sep">`,且 `.slide + .slide::before` 也存在;
- [ ] 未使用负 margin、未用绝对定位布局内容、未出现 `h-[calc(...)]`;
- [ ] `.block` 已包裹可移动单元,自动分页脚本已内置;
- [ ] 图表懒加载且不重复初始化;
- [ ] 全部文本/数据来自 ARTICLE 或规则推断;未硬编码具体人名/联系方式(除非原文提供)。