Files
ClassFeedback/.claude/lesson/AI03/第5节课AI大作家下.html
chengzi 7487e8451a Initial commit: 穹狼科创课评反馈生成器
- 添加 CLAUDE.md 项目说明
- 添加评语规则、课程模板、技能库
- 添加 .gitignore 忽略 .env
2026-04-14 21:27:19 +08:00

1178 lines
42 KiB
HTML
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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI大作家- 从大纲到完整故事</title>
<link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=boska@900,500&f[]=satoshi@400,500,700&display=swap">
<style>
/* ===========================================
CSS CUSTOM PROPERTIES (THEME)
Notebook Tabs Style - 教学风格
=========================================== */
:root {
/* Colors */
--bg-outer: #2d2d2d;
--bg-page: #f8f6f1;
--text-primary: #1a1a1a;
--text-secondary: #555;
--text-muted: #888;
/* Tab Colors */
--tab-1: #98d4bb;
--tab-2: #c7b8ea;
--tab-3: #f4b8c5;
--tab-4: #a8d8ea;
--tab-5: #ffe6a7;
--tab-6: #ffb3ba;
/* Accent */
--accent-warm: #e8d4c0;
--accent-highlight: #ff6b6b;
/* Typography */
--font-display: 'Boska', serif;
--font-body: 'Satoshi', sans-serif;
/* Font Sizes - MUST use clamp() */
--title-size: clamp(1.75rem, 4vw, 3rem);
--h2-size: clamp(1.25rem, 3vw, 2rem);
--h3-size: clamp(1rem, 2vw, 1.5rem);
--body-size: clamp(0.8rem, 1.5vw, 1.1rem);
--small-size: clamp(0.7rem, 1.2vw, 0.9rem);
/* Spacing */
--slide-padding: clamp(1.5rem, 4vw, 3rem);
--content-gap: clamp(1rem, 2vw, 2rem);
--element-gap: clamp(0.5rem, 1vw, 1rem);
/* Animation */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--duration-normal: 0.6s;
}
/* ===========================================
VIEWPORT FITTING: MANDATORY BASE STYLES
=========================================== */
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
height: 100%;
overflow-x: hidden;
font-family: var(--font-body);
}
html {
scroll-snap-type: y mandatory;
scroll-behavior: smooth;
}
body {
background: var(--bg-outer);
color: var(--text-primary);
}
/* Each slide = exact viewport height */
.slide {
width: 100vw;
height: 100vh;
height: 100dvh;
overflow: hidden;
scroll-snap-align: start;
display: flex;
flex-direction: column;
position: relative;
background: var(--bg-outer);
}
/* Paper container - the notebook page */
.paper-container {
flex: 1;
margin: clamp(0.5rem, 2vw, 1.5rem);
margin-right: clamp(3rem, 8vw, 6rem);
background: var(--bg-page);
border-radius: 8px;
box-shadow:
0 4px 6px rgba(0,0,0,0.1),
0 10px 20px rgba(0,0,0,0.1),
inset 0 1px 0 rgba(255,255,255,0.8);
position: relative;
overflow: hidden;
}
/* Binder holes decoration */
.binder-holes {
position: absolute;
left: clamp(0.75rem, 2vw, 1.5rem);
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: clamp(2rem, 5vh, 4rem);
}
.binder-hole {
width: clamp(6px, 1vw, 10px);
height: clamp(6px, 1vw, 10px);
background: var(--bg-outer);
border-radius: 50%;
opacity: 0.3;
}
/* Content container */
.slide-content {
height: 100%;
padding: var(--slide-padding);
padding-left: clamp(2.5rem, 6vw, 4rem);
display: flex;
flex-direction: column;
justify-content: center;
max-height: 100%;
overflow: hidden;
}
/* Vertical tabs on right */
.tab-container {
position: absolute;
right: calc(-1 * clamp(1.5rem, 3vw, 2.5rem));
top: 0;
bottom: 0;
width: clamp(2rem, 4vw, 3rem);
display: flex;
flex-direction: column;
justify-content: center;
gap: clamp(0.25rem, 0.5vh, 0.5rem);
z-index: 10;
}
.tab {
width: 100%;
border-radius: 0 6px 6px 0;
display: flex;
align-items: center;
justify-content: center;
writing-mode: vertical-rl;
text-orientation: mixed;
font-size: clamp(0.5rem, 1vh, 0.7rem);
font-weight: 500;
letter-spacing: 0.1em;
color: var(--text-primary);
box-shadow: 2px 0 4px rgba(0,0,0,0.1);
transition: transform 0.3s var(--ease-out-expo);
}
.tab:hover {
transform: translateX(4px);
}
.tab-1 { height: 18%; background: var(--tab-1); }
.tab-2 { height: 14%; background: var(--tab-2); }
.tab-3 { height: 20%; background: var(--tab-3); }
.tab-4 { height: 16%; background: var(--tab-4); }
.tab-5 { height: 14%; background: var(--tab-5); }
.tab-6 { height: 18%; background: var(--tab-6); }
/* Typography */
h1 {
font-family: var(--font-display);
font-size: var(--title-size);
font-weight: 900;
line-height: 1.2;
margin-bottom: var(--element-gap);
color: var(--text-primary);
}
h2 {
font-family: var(--font-display);
font-size: var(--h2-size);
font-weight: 500;
line-height: 1.3;
margin-bottom: var(--element-gap);
color: var(--text-primary);
}
h3 {
font-family: var(--font-body);
font-size: var(--h3-size);
font-weight: 700;
line-height: 1.4;
margin-bottom: calc(var(--element-gap) * 0.75);
color: var(--text-primary);
}
p {
font-size: var(--body-size);
line-height: 1.6;
color: var(--text-secondary);
margin-bottom: var(--element-gap);
}
/* Highlight box */
.highlight-box {
background: linear-gradient(135deg, var(--tab-5) 0%, var(--tab-1) 100%);
border-radius: 8px;
padding: clamp(0.75rem, 2vw, 1.5rem);
margin: var(--element-gap) 0;
}
.highlight-box p {
color: var(--text-primary);
margin: 0;
font-weight: 500;
}
/* Code/Prompt block */
.code-block {
background: #2d2d2d;
color: #f8f6f1;
border-radius: 8px;
padding: clamp(0.75rem, 2vw, 1.25rem);
font-family: 'Courier New', monospace;
font-size: var(--small-size);
line-height: 1.5;
overflow: hidden;
margin: var(--element-gap) 0;
}
.code-block pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
.code-block .placeholder {
color: #4ecca3;
}
.code-block .comment {
color: #888;
}
/* Structure items */
.structure-item {
display: flex;
align-items: flex-start;
gap: var(--element-gap);
margin-bottom: calc(var(--element-gap) * 0.75);
padding: clamp(0.5rem, 1.5vw, 1rem);
background: rgba(255,255,255,0.5);
border-radius: 6px;
border-left: 4px solid var(--tab-2);
}
.structure-number {
font-family: var(--font-display);
font-size: var(--h3-size);
font-weight: 900;
color: var(--tab-2);
min-width: 2rem;
}
.structure-content h4 {
font-size: var(--body-size);
font-weight: 700;
margin-bottom: calc(var(--element-gap) * 0.25);
}
.structure-content p {
font-size: var(--small-size);
margin: 0;
}
/* Two column layout */
.two-col {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--content-gap);
align-items: start;
}
/* Comparison boxes */
.compare-box {
padding: clamp(0.75rem, 2vw, 1.25rem);
border-radius: 8px;
}
.compare-bad {
background: rgba(231, 76, 60, 0.1);
border: 2px solid rgba(231, 76, 60, 0.3);
}
.compare-good {
background: rgba(78, 204, 163, 0.15);
border: 2px solid rgba(78, 204, 163, 0.4);
}
.compare-box h4 {
font-size: var(--body-size);
margin-bottom: calc(var(--element-gap) * 0.5);
}
.compare-bad h4 { color: #c0392b; }
.compare-good h4 { color: #27ae60; }
/* Step grid */
.step-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--element-gap);
margin: var(--element-gap) 0;
}
.step-card {
background: rgba(255,255,255,0.6);
border-radius: 8px;
padding: clamp(0.75rem, 2vw, 1rem);
text-align: center;
border-top: 4px solid var(--tab-3);
}
.step-number {
font-family: var(--font-display);
font-size: clamp(1.5rem, 3vw, 2rem);
font-weight: 900;
color: var(--tab-3);
}
.step-card h4 {
font-size: var(--body-size);
margin: calc(var(--element-gap) * 0.5) 0;
}
.step-card p {
font-size: var(--small-size);
margin: 0;
}
/* Check list */
.check-list {
background: rgba(255,255,255,0.5);
border-radius: 8px;
padding: clamp(0.75rem, 2vw, 1.25rem);
margin: var(--element-gap) 0;
}
.check-item {
display: flex;
align-items: center;
gap: calc(var(--element-gap) * 0.75);
margin-bottom: calc(var(--element-gap) * 0.5);
font-size: var(--body-size);
}
.check-item:last-child {
margin-bottom: 0;
}
.check-box {
width: clamp(1rem, 2vw, 1.25rem);
height: clamp(1rem, 2vw, 1.25rem);
border: 2px solid var(--tab-2);
border-radius: 4px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: var(--tab-2);
}
/* Progress indicator */
.progress-bar {
position: fixed;
top: 0;
left: 0;
height: 4px;
background: linear-gradient(90deg, var(--tab-1), var(--tab-3), var(--tab-4));
z-index: 1000;
transition: width 0.3s ease;
}
/* Navigation dots */
.nav-dots {
position: fixed;
right: clamp(0.5rem, 1.5vw, 1rem);
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 8px;
z-index: 1000;
}
.nav-dot {
width: clamp(8px, 1.5vw, 12px);
height: clamp(8px, 1.5vw, 12px);
border-radius: 50%;
background: rgba(255,255,255,0.3);
cursor: pointer;
transition: all 0.3s ease;
}
.nav-dot.active {
background: var(--tab-3);
transform: scale(1.2);
}
/* Keyboard hint */
.keyboard-hint {
position: fixed;
bottom: clamp(0.5rem, 2vw, 1rem);
right: clamp(0.5rem, 2vw, 1rem);
font-size: var(--small-size);
color: rgba(255,255,255,0.5);
z-index: 1000;
}
/* Slide number */
.slide-number {
position: absolute;
top: clamp(0.75rem, 2vw, 1.25rem);
right: clamp(3rem, 7vw, 5rem);
font-family: var(--font-display);
font-size: var(--h3-size);
color: var(--text-muted);
opacity: 0.5;
}
/* Section badge */
.section-badge {
display: inline-block;
background: var(--tab-4);
color: var(--text-primary);
padding: calc(var(--element-gap) * 0.25) calc(var(--element-gap) * 0.75);
border-radius: 20px;
font-size: var(--small-size);
font-weight: 700;
margin-bottom: var(--element-gap);
}
/* Animations */
.reveal {
opacity: 0;
transform: translateY(20px);
transition: opacity var(--duration-normal) var(--ease-out-expo),
transform var(--duration-normal) var(--ease-out-expo);
}
.slide.visible .reveal {
opacity: 1;
transform: translateY(0);
}
.reveal:nth-child(1) { transition-delay: 0.1s; }
.reveal:nth-child(2) { transition-delay: 0.15s; }
.reveal:nth-child(3) { transition-delay: 0.2s; }
.reveal:nth-child(4) { transition-delay: 0.25s; }
.reveal:nth-child(5) { transition-delay: 0.3s; }
/* Title slide */
.title-slide .slide-content {
align-items: center;
text-align: center;
}
.title-slide h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
.title-slide .subtitle {
font-size: var(--h3-size);
color: var(--text-secondary);
margin-bottom: var(--content-gap);
}
.title-meta {
display: flex;
gap: var(--content-gap);
margin-top: var(--content-gap);
font-size: var(--small-size);
color: var(--text-muted);
flex-wrap: wrap;
justify-content: center;
}
.title-meta span {
background: rgba(0,0,0,0.05);
padding: calc(var(--element-gap) * 0.5) var(--element-gap);
border-radius: 20px;
}
/* Responsive */
@media (max-height: 700px) {
:root {
--slide-padding: clamp(1rem, 3vw, 2rem);
--content-gap: clamp(0.75rem, 1.5vw, 1.5rem);
}
.step-grid {
gap: calc(var(--element-gap) * 0.5);
}
}
@media (max-height: 600px) {
:root {
--slide-padding: clamp(0.75rem, 2.5vw, 1.5rem);
--content-gap: clamp(0.5rem, 1vw, 1rem);
}
.tab-container {
display: none;
}
.paper-container {
margin-right: clamp(0.5rem, 2vw, 1.5rem);
}
.keyboard-hint {
display: none;
}
}
@media (max-width: 768px) {
.two-col {
grid-template-columns: 1fr;
}
.step-grid {
grid-template-columns: 1fr;
}
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
.reveal {
opacity: 1;
transform: none;
transition: none;
}
}
</style>
</head>
<body>
<!-- Progress bar -->
<div class="progress-bar" id="progressBar"></div>
<!-- Navigation dots -->
<nav class="nav-dots" id="navDots"></nav>
<!-- Keyboard hint -->
<div class="keyboard-hint">↑ ↓ 方向键切换</div>
<!-- ===========================================
SLIDE 1: 标题页
=========================================== -->
<section class="slide title-slide" data-slide="1">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">大纲</div>
<div class="tab tab-2">写作</div>
<div class="tab tab-3">修改</div>
<div class="tab tab-4">连贯</div>
<div class="tab tab-5">完成</div>
<div class="tab tab-6">分享</div>
</div>
<div class="slide-content">
<div class="reveal">
<span class="section-badge">AICODE-03 · 第5课</span>
</div>
<h1 class="reveal">我是大作家(下)</h1>
<p class="subtitle reveal">从大纲到完整故事</p>
<div class="highlight-box reveal">
<p>🎯 今天你要当导演AI 当编剧<br>完成一篇属于自己的短篇小说!</p>
</div>
<div class="title-meta reveal">
<span>⏱ 90分钟</span>
<span>🛠 Trae IDE</span>
<span>📖 目标1000字</span>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 2: 回顾上节课
=========================================== -->
<section class="slide" data-slide="2">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">回顾</div>
<div class="tab tab-2">设定</div>
<div class="tab tab-3">起点</div>
<div class="tab tab-4">目标</div>
<div class="tab tab-5">创作</div>
<div class="tab tab-6">完成</div>
</div>
<div class="slide-number">02</div>
<div class="slide-content">
<span class="section-badge reveal">🔗 联系 Connect</span>
<h2 class="reveal">还记得你的故事吗?</h2>
<p class="reveal">上节课,你设计了一个故事世界:</p>
<div class="step-grid reveal">
<div class="step-card">
<div class="step-number">1</div>
<h4>故事类型</h4>
<p>校园 / 魔法 / 穿越<br>动物 / 科幻...</p>
</div>
<div class="step-card">
<div class="step-number">2</div>
<h4>主角设定</h4>
<p>名字、身份<br>性格、能力</p>
</div>
<div class="step-card">
<div class="step-number">3</div>
<h4>故事地点</h4>
<p>学校 / 森林<br>太空 / 古代...</p>
</div>
</div>
<div class="highlight-box reveal">
<p>💡 今天,我们要把这些<strong>"设定"</strong>变成<strong>"完整的小说"</strong></p>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 3: 为什么需要大纲
=========================================== -->
<section class="slide" data-slide="3">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">骨架</div>
<div class="tab tab-2">大纲</div>
<div class="tab tab-3">作用</div>
<div class="tab tab-4">对比</div>
<div class="tab tab-5">理解</div>
<div class="tab tab-6">重要</div>
</div>
<div class="slide-number">03</div>
<div class="slide-content">
<span class="section-badge reveal">🏗️ 建构 Construct</span>
<h2 class="reveal">为什么需要大纲?</h2>
<div class="two-col reveal">
<div class="compare-box compare-bad">
<h4>❌ 没有大纲</h4>
<p>第一章:小明在森林里发现兔子...<br><br>第二章:小红在太空站遇到外星人...<br><br><strong>问题:</strong>主角变了?地点跳跃?前后矛盾!</p>
</div>
<div class="compare-box compare-good">
<h4>✅ 有大纲</h4>
<p>按大纲写每章 → 情节连贯<br><br><strong>大纲 = 骨架</strong><br>骨架搭好 → 再长"肉"(内容)<br>没有骨架 → 故事东倒西歪</p>
</div>
</div>
<div class="highlight-box reveal">
<p>🎯 好故事要先有设计(大纲),再写内容——就像盖房子先画图纸!</p>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 4: 章节结构 引发转收
=========================================== -->
<section class="slide" data-slide="4">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">章节</div>
<div class="tab tab-2">结构</div>
<div class="tab tab-3">引发</div>
<div class="tab tab-4">转收</div>
<div class="tab tab-5">口诀</div>
<div class="tab tab-6">记忆</div>
</div>
<div class="slide-number">04</div>
<div class="slide-content">
<span class="section-badge reveal">🏗️ 建构 Construct</span>
<h2 class="reveal">章节结构:引发转收</h2>
<div class="structure-item reveal">
<div class="structure-number"></div>
<div class="structure-content">
<h4>开头(引入)</h4>
<p>介绍主角,设定场景,埋下悬念</p>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number"></div>
<div class="structure-content">
<h4>发展(事件)</h4>
<p>主角遇到挑战/冒险,情节推进</p>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number"></div>
<div class="structure-content">
<h4>高潮(转折)</h4>
<p>冲突升级,最紧张的时刻</p>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number"></div>
<div class="structure-content">
<h4>结尾(收束)</h4>
<p>解决问题,留下回味</p>
</div>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 5: 第一步:生成大纲
=========================================== -->
<section class="slide" data-slide="5">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">提示词</div>
<div class="tab tab-2">大纲</div>
<div class="tab tab-3">生成</div>
<div class="tab tab-4">AI</div>
<div class="tab tab-5">协作</div>
<div class="tab tab-6">创作</div>
</div>
<div class="slide-number">05</div>
<div class="slide-content">
<span class="section-badge reveal">🏗️ 建构 Construct · 步骤1</span>
<h2 class="reveal">生成故事大纲</h2>
<p class="reveal">打开 Trae复制下面的提示词</p>
<div class="code-block reveal">
<pre>请根据我的角色设定,生成一个 3-4 章的故事大纲。
我的设定:
- 故事类型:<span class="placeholder">[你的类型]</span>
- 主角:<span class="placeholder">[名字]</span><span class="placeholder">[身份]</span><span class="placeholder">[性格]</span><span class="placeholder">[能力]</span>
- 地点:<span class="placeholder">[故事发生地]</span>
要求:
1. 每章用一句话概括
2. 情节要连贯,有吸引力
3. 体现主角的性格特点</pre>
</div>
<div class="highlight-box reveal">
<p>💡 <strong>不满意就改!</strong> 告诉 AI"让情节更曲折" 或 "让反派早点出现"</p>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 6: 第二步:逐章写作
=========================================== -->
<section class="slide" data-slide="6">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">逐章</div>
<div class="tab tab-2">写作</div>
<div class="tab tab-3">导演</div>
<div class="tab tab-4">编剧</div>
<div class="tab tab-5">协作</div>
<div class="tab tab-6">掌控</div>
</div>
<div class="slide-number">06</div>
<div class="slide-content">
<span class="section-badge reveal">🏗️ 建构 Construct · 步骤2</span>
<h2 class="reveal">逐章写作</h2>
<p class="reveal"><strong>为什么逐章写?</strong> 每章写完可检查修改,发现问题及时调整,更容易控制故事走向。</p>
<div class="code-block reveal">
<pre>请根据大纲写第一章200-300字。
要求:
1. 开头要吸引人,让读者想继续看
2. 介绍主角和场景
3. 用 Markdown 格式,标题用 #
4. 体现主角<span class="placeholder">[性格特点]</span></pre>
</div>
<div class="highlight-box reveal">
<p>🎯 你是导演AI 是编剧<br>每章 200-400 字,总计约 1000 字短篇</p>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 7: 第三步:一句话修改
=========================================== -->
<section class="slide" data-slide="7">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">修改</div>
<div class="tab tab-2">迭代</div>
<div class="tab tab-3">一句话</div>
<div class="tab tab-4">指令</div>
<div class="tab tab-5">完善</div>
<div class="tab tab-6">提升</div>
</div>
<div class="slide-number">07</div>
<div class="slide-content">
<span class="section-badge reveal">🏗️ 建构 Construct · 步骤3</span>
<h2 class="reveal">一句话修改</h2>
<p class="reveal">AI 写的是<strong>初稿</strong>,不完美很正常。用一句话告诉 AI 怎么改:</p>
<div class="structure-item reveal">
<div class="structure-number" style="color: var(--tab-4);"></div>
<div class="structure-content">
<h4>开头太平淡 → "开头加个悬念"</h4>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number" style="color: var(--tab-4);"></div>
<div class="structure-content">
<h4>细节不够 → "多加点环境细节"</h4>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number" style="color: var(--tab-4);"></div>
<div class="structure-content">
<h4>语气不对 → "改得符合小学生口吻"</h4>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number" style="color: var(--tab-4);"></div>
<div class="structure-content">
<h4>想加对话 → "加一段对话,更生动"</h4>
</div>
</div>
<div class="highlight-box reveal">
<p><strong>好故事是改出来的!</strong> 你是导演AI 是编剧</p>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 8: 第四步:检查连贯性
=========================================== -->
<section class="slide" data-slide="8">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">检查</div>
<div class="tab tab-2">连贯</div>
<div class="tab tab-3">一致性</div>
<div class="tab tab-4">衔接</div>
<div class="tab tab-5">修正</div>
<div class="tab tab-6">完整</div>
</div>
<div class="slide-number">08</div>
<div class="slide-content">
<span class="section-badge reveal">🏗️ 建构 Construct · 步骤4</span>
<h2 class="reveal">检查连贯性</h2>
<p class="reveal">写完两章后,检查这些问题:</p>
<div class="check-list reveal">
<div class="check-item">
<div class="check-box"></div>
<span>主角名字前后一致吗?</span>
</div>
<div class="check-item">
<div class="check-box"></div>
<span>主角性格有没有突然改变?</span>
</div>
<div class="check-item">
<div class="check-box"></div>
<span>地点描述有没有矛盾?</span>
</div>
<div class="check-item">
<div class="check-box"></div>
<span>前一章的悬念后一章有回应吗?</span>
</div>
<div class="check-item">
<div class="check-box"></div>
<span>时间线清晰吗?</span>
</div>
</div>
<div class="highlight-box reveal">
<p>💡 发现问题?用一句话让 AI 修正衔接问题</p>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 9: 学生实践
=========================================== -->
<section class="slide" data-slide="9">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">实践</div>
<div class="tab tab-2">写作</div>
<div class="tab tab-3">时间</div>
<div class="tab tab-4">创作</div>
<div class="tab tab-5">专注</div>
<div class="tab tab-6">完成</div>
</div>
<div class="slide-number">09</div>
<div class="slide-content">
<span class="section-badge reveal">🏗️ 建构 Construct · 实践时间</span>
<h2 class="reveal">开始写作吧!</h2>
<div class="step-grid reveal">
<div class="step-card">
<div class="step-number">1</div>
<h4>生成大纲</h4>
<p>3-4 章<br>引发转收</p>
</div>
<div class="step-card">
<div class="step-number">2</div>
<h4>逐章写作</h4>
<p>每章 200-300 字<br>你是导演</p>
</div>
<div class="step-card">
<div class="step-number">3</div>
<h4>检查连贯</h4>
<p>前后一致<br>发现问题就改</p>
</div>
</div>
<div class="highlight-box reveal">
<p>⏱️ <strong>实践时间20分钟</strong><br>目标:完成至少 1-2 章<br>提示:第一版不完美是正常的,大胆写!</p>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE 10: 总结
=========================================== -->
<section class="slide" data-slide="10">
<div class="paper-container">
<div class="binder-holes">
<div class="binder-hole"></div>
<div class="binder-hole"></div>
<div class="binder-hole"></div>
</div>
<div class="tab-container">
<div class="tab tab-1">总结</div>
<div class="tab tab-2">作业</div>
<div class="tab tab-3">预告</div>
<div class="tab tab-4">延续</div>
<div class="tab tab-5">书籍</div>
<div class="tab tab-6">完成</div>
</div>
<div class="slide-number">10</div>
<div class="slide-content">
<span class="section-badge reveal">🚀 延续 Continue</span>
<h2 class="reveal">今天学了什么?</h2>
<div class="structure-item reveal">
<div class="structure-number">1</div>
<div class="structure-content">
<h4>大纲作用</h4>
<p>骨架先搭好,故事才不倒</p>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number">2</div>
<div class="structure-content">
<h4>生成大纲</h4>
<p>3-4章结构引发转收</p>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number">3</div>
<div class="structure-content">
<h4>逐章写作</h4>
<p>你是导演AI是编剧</p>
</div>
</div>
<div class="structure-item reveal">
<div class="structure-number">4</div>
<div class="structure-content">
<h4>一句话修改</h4>
<p>好故事是改出来的</p>
</div>
</div>
<div class="highlight-box reveal">
<p>📚 <strong>课后作业:</strong>完成剩余章节(共 3-4 章,约 1000 字)+ 检查连贯性 + 起标题</p>
</div>
</div>
</div>
</section>
<!-- ===========================================
SLIDE PRESENTATION CONTROLLER
=========================================== -->
<script>
class SlidePresentation {
constructor() {
this.slides = document.querySelectorAll('.slide');
this.currentSlide = 0;
this.totalSlides = this.slides.length;
this.progressBar = document.getElementById('progressBar');
this.navDotsContainer = document.getElementById('navDots');
this.init();
}
init() {
this.createNavDots();
this.setupIntersectionObserver();
this.setupKeyboardNav();
this.setupTouchNav();
this.updateProgress();
}
createNavDots() {
this.slides.forEach((_, index) => {
const dot = document.createElement('div');
dot.className = 'nav-dot' + (index === 0 ? ' active' : '');
dot.addEventListener('click', () => this.goToSlide(index));
this.navDotsContainer.appendChild(dot);
});
this.navDots = document.querySelectorAll('.nav-dot');
}
setupIntersectionObserver() {
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 0.5
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
const slideIndex = Array.from(this.slides).indexOf(entry.target);
this.currentSlide = slideIndex;
this.updateNavDots();
this.updateProgress();
}
});
}, observerOptions);
this.slides.forEach(slide => observer.observe(slide));
}
setupKeyboardNav() {
document.addEventListener('keydown', (e) => {
switch(e.key) {
case 'ArrowDown':
case 'ArrowRight':
case 'PageDown':
case ' ':
e.preventDefault();
this.nextSlide();
break;
case 'ArrowUp':
case 'ArrowLeft':
case 'PageUp':
e.preventDefault();
this.prevSlide();
break;
case 'Home':
e.preventDefault();
this.goToSlide(0);
break;
case 'End':
e.preventDefault();
this.goToSlide(this.totalSlides - 1);
break;
}
});
}
setupTouchNav() {
let touchStartY = 0;
let touchEndY = 0;
document.addEventListener('touchstart', (e) => {
touchStartY = e.changedTouches[0].screenY;
}, { passive: true });
document.addEventListener('touchend', (e) => {
touchEndY = e.changedTouches[0].screenY;
this.handleSwipe(touchStartY, touchEndY);
}, { passive: true });
}
handleSwipe(startY, endY) {
const threshold = 50;
const diff = startY - endY;
if (Math.abs(diff) > threshold) {
if (diff > 0) {
this.nextSlide();
} else {
this.prevSlide();
}
}
}
goToSlide(index) {
if (index >= 0 && index < this.totalSlides) {
this.slides[index].scrollIntoView({ behavior: 'smooth' });
}
}
nextSlide() {
if (this.currentSlide < this.totalSlides - 1) {
this.goToSlide(this.currentSlide + 1);
}
}
prevSlide() {
if (this.currentSlide > 0) {
this.goToSlide(this.currentSlide - 1);
}
}
updateNavDots() {
this.navDots.forEach((dot, index) => {
dot.classList.toggle('active', index === this.currentSlide);
});
}
updateProgress() {
const progress = ((this.currentSlide + 1) / this.totalSlides) * 100;
this.progressBar.style.width = progress + '%';
}
}
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => new SlidePresentation());
} else {
new SlidePresentation();
}
</script>
</body>
</html>