refactor(grades,attendance,error-book,elective): 组件化重构第 1 批 - 低风险模块
- grades: 拆分 batch-grade-entry (457→374) + grade-record-list (523→231),新增 4 个子组件 - attendance: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座 - error-book: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座 - elective: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座 - 删除 12 个重复组件,新增 app 层 filter 组件就近放置 - tsc 零错误,lint 无新增错误
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
<h2>课文锚点时间线布局</h2>
|
||||
<p class="subtitle">课文作为主轴,节点锚定到课文位置,形成教学流程时间线</p>
|
||||
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">备课编辑器 — 课文锚点时间线</div>
|
||||
<div class="mockup-body" style="padding:0;">
|
||||
<div style="font-family:monospace;font-size:12px;line-height:1.6;">
|
||||
<!-- 顶部工具栏 -->
|
||||
<div style="background:#1e293b;color:#e2e8f0;padding:8px 12px;display:flex;justify-content:space-between;align-items:center;">
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span>📖</span>
|
||||
<span style="font-weight:bold;">秋天(第一课时)</span>
|
||||
<span style="background:#334155;padding:2px 8px;border-radius:3px;font-size:10px;">语文 · 一年级上册 · 第一单元</span>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span style="font-size:10px;color:#94a3b8;">💾 已保存 · 2 分钟前</span>
|
||||
<span style="background:#334155;padding:4px 8px;border-radius:3px;font-size:10px;">📋 版本历史</span>
|
||||
<span style="background:#3b82f6;padding:4px 12px;border-radius:3px;font-size:10px;">💾 保存</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主体:左课文 + 右节点时间线 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 320px;gap:0;background:#fff;min-height:480px;">
|
||||
|
||||
<!-- 左侧:课文正文区(带锚点 gutter) -->
|
||||
<div style="display:grid;grid-template-columns:32px 1fr;background:#fffbeb;border-right:1px solid #e2e8f0;">
|
||||
|
||||
<!-- 锚点 gutter(显示锚点标记) -->
|
||||
<div style="background:#fef3c7;border-right:1px solid #fde68a;position:relative;">
|
||||
<!-- 锚点标记 -->
|
||||
<div style="position:absolute;top:60px;left:4px;background:#3b82f6;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">1</div>
|
||||
<div style="position:absolute;top:140px;left:4px;background:#f59e0b;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">2</div>
|
||||
<div style="position:absolute;top:200px;left:4px;background:#0ea5e9;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">3</div>
|
||||
<div style="position:absolute;top:280px;left:4px;background:#ec4899;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">4</div>
|
||||
<div style="position:absolute;top:360px;left:4px;background:#22c55e;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">5</div>
|
||||
</div>
|
||||
|
||||
<!-- 课文内容 -->
|
||||
<div style="padding:16px 20px;font-size:13px;color:#78350f;line-height:2;position:relative;">
|
||||
<div style="font-size:16px;font-weight:bold;color:#92400e;text-align:center;margin-bottom:16px;">秋天</div>
|
||||
|
||||
<p style="margin:0 0 12px 0;">
|
||||
<span style="background:#dbeafe;border-bottom:2px solid #3b82f6;padding:1px 2px;">天气凉了,树叶黄了,</span>
|
||||
一片片叶子从树上落下来。
|
||||
</p>
|
||||
<p style="margin:0 0 12px 0;">
|
||||
<span style="background:#fef3c7;border-bottom:2px solid #f59e0b;padding:1px 2px;">天空那么蓝,那么高。</span>
|
||||
一群大雁往南飞,
|
||||
</p>
|
||||
<p style="margin:0 0 12px 0;">
|
||||
<span style="background:#e0f2fe;border-bottom:2px solid #0ea5e9;padding:1px 2px;">一会儿排成个"人"字,</span>
|
||||
<span style="background:#fce7f3;border-bottom:2px solid #ec4899;padding:1px 2px;">一会儿排成个"一"字。</span>
|
||||
</p>
|
||||
<p style="margin:0 0 12px 0;">
|
||||
<span style="background:#dcfce7;border-bottom:2px solid #22c55e;padding:1px 2px;">啊!秋天来了!</span>
|
||||
</p>
|
||||
|
||||
<!-- 拖放提示 -->
|
||||
<div style="margin-top:24px;padding:8px;border:1px dashed #cbd5e1;border-radius:4px;text-align:center;font-size:10px;color:#94a3b8;">
|
||||
💡 选中文字可"关联节点",或从右侧拖动节点到课文某字前
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:节点时间线 -->
|
||||
<div style="background:#f8fafc;padding:12px;overflow-y:auto;">
|
||||
<div style="font-size:10px;color:#64748b;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;">教学流程时间线</div>
|
||||
|
||||
<!-- 已锚定节点(按课文位置排序) -->
|
||||
<div style="display:flex;flex-direction:column;gap:6px;">
|
||||
|
||||
<!-- 节点 1:导入(锚定到"天气凉了") -->
|
||||
<div style="background:#fff;border:1px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:4px;padding:8px;cursor:pointer;">
|
||||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||||
<span style="background:#3b82f6;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">1</span>
|
||||
<span style="font-size:11px;font-weight:bold;color:#1e3a8a;">💡 导入</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||||
</div>
|
||||
<div style="font-size:10px;color:#64748b;background:#eff6ff;padding:4px 6px;border-radius:3px;">
|
||||
"天气凉了,树叶黄了" → 提问:你见过秋天的树叶吗?
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 节点 2:文本研习(锚定到"天空那么蓝") -->
|
||||
<div style="background:#fff;border:1px solid #f59e0b;border-left:3px solid #f59e0b;border-radius:4px;padding:8px;cursor:pointer;">
|
||||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||||
<span style="background:#f59e0b;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">2</span>
|
||||
<span style="font-size:11px;font-weight:bold;color:#92400e;">📝 文本研习</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||||
</div>
|
||||
<div style="font-size:10px;color:#64748b;background:#fffbeb;padding:4px 6px;border-radius:3px;">
|
||||
"天空那么蓝,那么高" → 赏析:叠词的运用
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 节点 3:新授(锚定到"人字") -->
|
||||
<div style="background:#fff;border:1px solid #0ea5e9;border-left:3px solid #0ea5e9;border-radius:4px;padding:8px;cursor:pointer;">
|
||||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||||
<span style="background:#0ea5e9;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">3</span>
|
||||
<span style="font-size:11px;font-weight:bold;color:#075985;">📚 新授</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||||
</div>
|
||||
<div style="font-size:10px;color:#64748b;background:#f0f9ff;padding:4px 6px;border-radius:3px;">
|
||||
"一会儿排成个'人'字" → 讲解:大雁南飞
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 节点 4:练习(锚定到"一字") -->
|
||||
<div style="background:#fff;border:1px solid #ec4899;border-left:3px solid #ec4899;border-radius:4px;padding:8px;cursor:pointer;">
|
||||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||||
<span style="background:#ec4899;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">4</span>
|
||||
<span style="font-size:11px;font-weight:bold;color:#9f1239;">✏️ 练习</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||||
</div>
|
||||
<div style="font-size:10px;color:#64748b;background:#fdf2f8;padding:4px 6px;border-radius:3px;">
|
||||
"一会儿排成个'一'字" → 3 道题
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 节点 5:小结(锚定到"秋天来了") -->
|
||||
<div style="background:#fff;border:1px solid #22c55e;border-left:3px solid #22c55e;border-radius:4px;padding:8px;cursor:pointer;">
|
||||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">
|
||||
<span style="background:#22c55e;color:#fff;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:bold;">5</span>
|
||||
<span style="font-size:11px;font-weight:bold;color:#166534;">📌 小结</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">📍 锚定</span>
|
||||
</div>
|
||||
<div style="font-size:10px;color:#64748b;background:#f0fdf4;padding:4px 6px;border-radius:3px;">
|
||||
"啊!秋天来了!" → 总结全文
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<div style="border-top:1px dashed #cbd5e1;margin:8px 0;padding-top:8px;">
|
||||
<div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:1px;margin-bottom:6px;">未锚定节点</div>
|
||||
</div>
|
||||
|
||||
<!-- 未锚定节点 -->
|
||||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:6px;">
|
||||
<span style="font-size:11px;font-weight:bold;color:#1e3a8a;">🎯 教学目标</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">全局</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:6px;">
|
||||
<span style="font-size:11px;font-weight:bold;color:#92400e;">⭐ 重难点</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">全局</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:6px;">
|
||||
<span style="font-size:11px;font-weight:bold;color:#a855f7;">🏠 作业</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">课后</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:6px;">
|
||||
<span style="font-size:11px;font-weight:bold;color:#6366f1;">📋 板书设计</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">全局</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="background:#fff;border:1px dashed #cbd5e1;border-radius:4px;padding:8px;cursor:pointer;opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:6px;">
|
||||
<span style="font-size:11px;font-weight:bold;color:#64748b;">💭 教学反思</span>
|
||||
<span style="margin-left:auto;font-size:9px;color:#94a3b8;">课后</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加节点按钮 -->
|
||||
<div style="border:1px dashed #94a3b8;border-radius:4px;padding:8px;text-align:center;font-size:10px;color:#64748b;cursor:pointer;margin-top:4px;">
|
||||
+ 添加节点
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" style="margin-top:24px;">
|
||||
<h3>核心交互:两种锚定方式</h3>
|
||||
<div class="split">
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">方式 1:拖动节点到课文某字前</div>
|
||||
<div class="mockup-body" style="padding:16px;font-family:monospace;font-size:12px;">
|
||||
<div style="display:flex;gap:12px;">
|
||||
<div style="background:#f8fafc;padding:8px;border-radius:4px;">
|
||||
<div style="font-size:9px;color:#94a3b8;margin-bottom:4px;">右侧节点</div>
|
||||
<div style="background:#fff;border:1px solid #3b82f6;border-left:3px solid #3b82f6;padding:6px;border-radius:3px;cursor:grab;font-size:10px;">💡 导入</div>
|
||||
</div>
|
||||
<div style="font-size:18px;color:#94a3b8;align-self:center;">→</div>
|
||||
<div style="background:#fffbeb;padding:8px;border-radius:4px;flex:1;">
|
||||
<div style="font-size:9px;color:#94a3b8;margin-bottom:4px;">课文</div>
|
||||
<div style="font-size:11px;color:#78350f;line-height:1.8;">
|
||||
天气凉了,<span style="background:#dbeafe;border:2px dashed #3b82f6;padding:1px 2px;border-radius:2px;">|</span>树叶黄了,<br>
|
||||
一片片叶子从树上落下来。
|
||||
</div>
|
||||
<div style="font-size:9px;color:#3b82f6;margin-top:4px;">💡 节点锚定到此位置</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">方式 2:选中文字 → 关联节点</div>
|
||||
<div class="mockup-body" style="padding:16px;font-family:monospace;font-size:12px;">
|
||||
<div style="background:#fffbeb;padding:8px;border-radius:4px;margin-bottom:8px;">
|
||||
<div style="font-size:9px;color:#94a3b8;margin-bottom:4px;">1. 选中文字</div>
|
||||
<div style="font-size:11px;color:#78350f;line-height:1.8;">
|
||||
<span style="background:#fef08a;">天空那么蓝,那么高</span>。
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-size:18px;color:#94a3b8;text-align:center;">↓</div>
|
||||
<div style="background:#f8fafc;padding:8px;border-radius:4px;margin-top:8px;">
|
||||
<div style="font-size:9px;color:#94a3b8;margin-bottom:4px;">2. 弹出菜单选择节点</div>
|
||||
<div style="display:flex;gap:4px;flex-wrap:wrap;">
|
||||
<span style="background:#fff;border:1px solid #3b82f6;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">💡 导入</span>
|
||||
<span style="background:#fff;border:1px solid #f59e0b;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">📝 文本研习</span>
|
||||
<span style="background:#fff;border:1px solid #0ea5e9;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">📚 新授</span>
|
||||
<span style="background:#fff;border:1px solid #ec4899;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">✏️ 练习</span>
|
||||
<span style="background:#fff;border:1px solid #22c55e;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">📌 小结</span>
|
||||
<span style="background:#fff;border:1px dashed #94a3b8;padding:3px 6px;border-radius:3px;font-size:9px;cursor:pointer;">+ 新建节点</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" style="margin-top:24px;">
|
||||
<h3>数据模型:锚点(Anchor)</h3>
|
||||
<div style="background:#1e293b;color:#e2e8f0;padding:16px;border-radius:6px;font-family:monospace;font-size:11px;line-height:1.6;">
|
||||
<div style="color:#94a3b8;">// 节点锚点 — 记录节点与课文位置的关联</div>
|
||||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">NodeAnchor</span> {</div>
|
||||
<div> nodeId: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 关联的节点 ID</span></div>
|
||||
<div> type: <span style="color:#10b981;">"point"</span> | <span style="color:#10b981;">"range"</span>; <span style="color:#64748b;">// 点锚点 or 范围锚点</span></div>
|
||||
<div> start: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// 课文纯文本偏移量(字符)</span></div>
|
||||
<div> end?: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// range 锚点的结束偏移</span></div>
|
||||
<div> textPreview?: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 锚定文字预览(便于回显)</span></div>
|
||||
<div>}</div>
|
||||
<br>
|
||||
<div style="color:#94a3b8;">// LessonPlanDocument 扩展</div>
|
||||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">LessonPlanDocument</span> {</div>
|
||||
<div> version: <span style="color:#10b981;">3</span>; <span style="color:#64748b;">// 升级到 v3</span></div>
|
||||
<div> nodes: <span style="color:#3b82f6;">LessonPlanNode</span>[];</div>
|
||||
<div> edges: <span style="color:#3b82f6;">LessonPlanEdge</span>[]; <span style="color:#64748b;">// 保留:节点间连线</span></div>
|
||||
<div> anchors: <span style="color:#3b82f6;">NodeAnchor</span>[]; <span style="color:#64748b;">// 新增:节点与课文的锚点</span></div>
|
||||
<div>}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>这个设计的优势</h3>
|
||||
<div class="pros-cons">
|
||||
<div class="pros">
|
||||
<h4>优势</h4>
|
||||
<ul>
|
||||
<li><strong>教学流程可视化</strong>:节点按课文位置排序,天然形成时间线</li>
|
||||
<li><strong>节点与课文强关联</strong>:每个节点对应课文的哪部分一目了然</li>
|
||||
<li><strong>双模式锚定</strong>:拖动(点锚点)+ 选文字(范围锚点)</li>
|
||||
<li><strong>保留连线能力</strong>:节点间仍可连线(如"导入→新授"流程线)</li>
|
||||
<li><strong>未锚定节点</strong>:目标/重难点/作业/板书/反思等全局节点不强制锚定</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cons">
|
||||
<h4>需要注意</h4>
|
||||
<ul>
|
||||
<li>课文偏移量需基于纯文本(Markdown 渲染后需映射)</li>
|
||||
<li>课文内容变更后锚点可能失效(需重新定位或提示)</li>
|
||||
<li>数据结构升级到 v3,需迁移现有 v2 数据</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,292 @@
|
||||
<h2>画布式锚点布局 — 正文固定 + 节点散布 + 连线关联</h2>
|
||||
<p class="subtitle">保留 React Flow 画布交互,正文为不可移动但可缩放的中央容器,节点通过连线关联正文锚点</p>
|
||||
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">备课编辑器 — 画布视图(默认状态)</div>
|
||||
<div class="mockup-body" style="padding:0;background:#f1f5f9;overflow:hidden;">
|
||||
<div style="font-family:monospace;font-size:12px;line-height:1.6;position:relative;height:560px;">
|
||||
|
||||
<!-- 顶部工具栏 -->
|
||||
<div style="background:#1e293b;color:#e2e8f0;padding:8px 12px;display:flex;justify-content:space-between;align-items:center;z-index:10;position:relative;">
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span>📖</span>
|
||||
<span style="font-weight:bold;">秋天(第一课时)</span>
|
||||
<span style="background:#334155;padding:2px 8px;border-radius:3px;font-size:10px;">语文 · 一年级上册</span>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span style="font-size:10px;color:#94a3b8;">💾 已保存</span>
|
||||
<span style="background:#334155;padding:4px 8px;border-radius:3px;font-size:10px;">📋 版本</span>
|
||||
<span style="background:#3b82f6;padding:4px 12px;border-radius:3px;font-size:10px;">💾 保存</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 画布区域 -->
|
||||
<div style="position:relative;width:100%;height:520px;background:#f1f5f9;background-image:radial-gradient(#cbd5e1 1px, transparent 1px);background-size:20px 20px;overflow:hidden;">
|
||||
|
||||
<!-- SVG 连线层(默认 10% 透明度) -->
|
||||
<svg style="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;opacity:0.1;" viewBox="0 0 800 520">
|
||||
<!-- 节点1(导入) → 正文锚点1 -->
|
||||
<path d="M 130 120 Q 200 140 280 180" stroke="#3b82f6" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<circle cx="280" cy="180" r="4" fill="#3b82f6"/>
|
||||
<!-- 节点2(文本研习) → 正文锚点2 -->
|
||||
<path d="M 130 220 Q 200 230 280 240" stroke="#f59e0b" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<circle cx="280" cy="240" r="4" fill="#f59e0b"/>
|
||||
<!-- 节点3(新授) → 正文锚点3 -->
|
||||
<path d="M 670 120 Q 600 150 520 200" stroke="#0ea5e9" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<circle cx="520" cy="200" r="4" fill="#0ea5e9"/>
|
||||
<!-- 节点4(练习) → 正文锚点4 -->
|
||||
<path d="M 670 220 Q 600 240 520 260" stroke="#ec4899" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<circle cx="520" cy="260" r="4" fill="#ec4899"/>
|
||||
<!-- 节点5(小结) → 正文锚点5 -->
|
||||
<path d="M 670 340 Q 600 320 520 300" stroke="#22c55e" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<circle cx="520" cy="300" r="4" fill="#22c55e"/>
|
||||
<!-- 节点间连线(教学流程) -->
|
||||
<path d="M 130 140 L 130 200" stroke="#64748b" stroke-width="1.5" fill="none"/>
|
||||
<path d="M 670 140 L 670 200" stroke="#64748b" stroke-width="1.5" fill="none"/>
|
||||
<path d="M 670 240 L 670 320" stroke="#64748b" stroke-width="1.5" fill="none"/>
|
||||
</svg>
|
||||
|
||||
<!-- 中央:正文容器(不可移动,可缩放) -->
|
||||
<div style="position:absolute;left:280px;top:80px;width:240px;background:#fffbeb;border:2px solid #f59e0b;border-radius:8px;padding:12px;box-shadow:0 4px 12px rgba(0,0,0,0.1);">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;border-bottom:1px solid #fde68a;padding-bottom:6px;">
|
||||
<span style="font-size:11px;font-weight:bold;color:#92400e;">📜 课文正文</span>
|
||||
<span style="font-size:9px;color:#94a3b8;background:#fef3c7;padding:1px 4px;border-radius:2px;">🔒 固定</span>
|
||||
</div>
|
||||
<div style="font-size:13px;color:#78350f;line-height:1.8;">
|
||||
<div style="text-align:center;font-weight:bold;margin-bottom:6px;">秋天</div>
|
||||
<p style="margin:0 0 4px 0;">
|
||||
<span style="background:#dbeafe;border-bottom:2px solid #3b82f6;">天气凉了</span>,树叶黄了,
|
||||
</p>
|
||||
<p style="margin:0 0 4px 0;">
|
||||
<span style="background:#fef3c7;border-bottom:2px solid #f59e0b;">天空那么蓝</span>,那么高。
|
||||
</p>
|
||||
<p style="margin:0 0 4px 0;">
|
||||
一群大雁往南飞,
|
||||
</p>
|
||||
<p style="margin:0 0 4px 0;">
|
||||
一会儿排成个<span style="background:#e0f2fe;border-bottom:2px solid #0ea5e9;">"人"字</span>,
|
||||
</p>
|
||||
<p style="margin:0 0 4px 0;">
|
||||
一会儿排成个<span style="background:#fce7f3;border-bottom:2px solid #ec4899;">"一"字</span>。
|
||||
</p>
|
||||
<p style="margin:0;">
|
||||
<span style="background:#dcfce7;border-bottom:2px solid #22c55e;">啊!秋天来了!</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- 缩放控件 -->
|
||||
<div style="position:absolute;bottom:-12px;right:-12px;background:#fff;border:1px solid #f59e0b;border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;font-size:12px;cursor:pointer;box-shadow:0 2px 4px rgba(0,0,0,0.1);">🔍</div>
|
||||
</div>
|
||||
|
||||
<!-- 左侧节点 -->
|
||||
<!-- 节点1:导入 -->
|
||||
<div style="position:absolute;left:30px;top:90px;width:140px;background:#fff;border:1px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);cursor:move;">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#3b82f6;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">1</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#1e3a8a;">💡 导入</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">提问:你见过秋天的树叶吗?</div>
|
||||
<!-- React Flow Handle 标记 -->
|
||||
<div style="position:absolute;right:-4px;top:50%;width:8px;height:8px;background:#3b82f6;border-radius:50%;border:1px solid #fff;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 节点2:文本研习 -->
|
||||
<div style="position:absolute;left:30px;top:200px;width:140px;background:#fff;border:1px solid #f59e0b;border-left:3px solid #f59e0b;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);cursor:move;">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#f59e0b;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">2</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#92400e;">📝 文本研习</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">赏析:叠词的运用</div>
|
||||
<div style="position:absolute;right:-4px;top:50%;width:8px;height:8px;background:#f59e0b;border-radius:50%;border:1px solid #fff;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧节点 -->
|
||||
<!-- 节点3:新授 -->
|
||||
<div style="position:absolute;left:630px;top:90px;width:140px;background:#fff;border:1px solid #0ea5e9;border-left:3px solid #0ea5e9;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);cursor:move;">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#0ea5e9;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">3</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#075985;">📚 新授</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">讲解:大雁南飞</div>
|
||||
<div style="position:absolute;left:-4px;top:50%;width:8px;height:8px;background:#0ea5e9;border-radius:50%;border:1px solid #fff;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 节点4:练习 -->
|
||||
<div style="position:absolute;left:630px;top:200px;width:140px;background:#fff;border:1px solid #ec4899;border-left:3px solid #ec4899;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);cursor:move;">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#ec4899;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">4</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#9f1239;">✏️ 练习</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">3 道题</div>
|
||||
<div style="position:absolute;left:-4px;top:50%;width:8px;height:8px;background:#ec4899;border-radius:50%;border:1px solid #fff;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 节点5:小结 -->
|
||||
<div style="position:absolute;left:630px;top:320px;width:140px;background:#fff;border:1px solid #22c55e;border-left:3px solid #22c55e;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);cursor:move;">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#22c55e;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">5</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#166534;">📌 小结</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">总结全文</div>
|
||||
<div style="position:absolute;left:-4px;top:50%;width:8px;height:8px;background:#22c55e;border-radius:50%;border:1px solid #fff;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 顶部全局节点(未锚定) -->
|
||||
<div style="position:absolute;left:30px;top:10px;width:100px;background:#fff;border:1px dashed #3b82f6;border-radius:6px;padding:6px;box-shadow:0 2px 4px rgba(0,0,0,0.05);opacity:0.8;">
|
||||
<div style="font-size:9px;font-weight:bold;color:#1e3a8a;">🎯 教学目标</div>
|
||||
</div>
|
||||
<div style="position:absolute;left:140px;top:10px;width:100px;background:#fff;border:1px dashed #f59e0b;border-radius:6px;padding:6px;box-shadow:0 2px 4px rgba(0,0,0,0.05);opacity:0.8;">
|
||||
<div style="font-size:9px;font-weight:bold;color:#92400e;">⭐ 重难点</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部全局节点(未锚定) -->
|
||||
<div style="position:absolute;left:30px;top:440px;width:100px;background:#fff;border:1px dashed #a855f7;border-radius:6px;padding:6px;box-shadow:0 2px 4px rgba(0,0,0,0.05);opacity:0.8;">
|
||||
<div style="font-size:9px;font-weight:bold;color:#9333ea;">🏠 作业</div>
|
||||
</div>
|
||||
<div style="position:absolute;left:140px;top:440px;width:100px;background:#fff;border:1px dashed #6366f1;border-radius:6px;padding:6px;box-shadow:0 2px 4px rgba(0,0,0,0.05);opacity:0.8;">
|
||||
<div style="font-size:9px;font-weight:bold;color:#4f46e5;">📋 板书设计</div>
|
||||
</div>
|
||||
<div style="position:absolute;left:250px;top:440px;width:100px;background:#fff;border:1px dashed #64748b;border-radius:6px;padding:6px;box-shadow:0 2px 4px rgba(0,0,0,0.05);opacity:0.8;">
|
||||
<div style="font-size:9px;font-weight:bold;color:#475569;">💭 教学反思</div>
|
||||
</div>
|
||||
|
||||
<!-- React Flow Controls(右下角) -->
|
||||
<div style="position:absolute;bottom:12px;right:12px;background:#fff;border:1px solid #e2e8f0;border-radius:4px;padding:4px;display:flex;flex-direction:column;gap:2px;box-shadow:0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;border-radius:2px;">+</div>
|
||||
<div style="width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;border-radius:2px;">−</div>
|
||||
<div style="width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:10px;border-radius:2px;">⌖</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加节点按钮(左下角) -->
|
||||
<div style="position:absolute;bottom:12px;left:12px;background:#3b82f6;color:#fff;padding:6px 12px;border-radius:4px;font-size:10px;cursor:pointer;box-shadow:0 2px 4px rgba(59,130,246,0.3);">
|
||||
+ 添加节点
|
||||
</div>
|
||||
|
||||
<!-- 透明度提示 -->
|
||||
<div style="position:absolute;top:12px;right:12px;background:#fff;border:1px solid #e2e8f0;border-radius:4px;padding:4px 8px;font-size:9px;color:#64748b;">
|
||||
连线默认 10% 透明度 · 选中节点时完整显示
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中状态对比 -->
|
||||
<div class="section" style="margin-top:24px;">
|
||||
<h3>选中节点时的连线显示对比</h3>
|
||||
<div class="split">
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">默认状态 — 连线 10% 透明度</div>
|
||||
<div class="mockup-body" style="padding:16px;background:#f1f5f9;">
|
||||
<svg style="width:100%;height:120px;" viewBox="0 0 300 120">
|
||||
<path d="M 30 60 Q 120 60 270 60" stroke="#3b82f6" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
<rect x="10" y="45" width="40" height="30" fill="#fff" stroke="#3b82f6" rx="4"/>
|
||||
<text x="30" y="64" text-anchor="middle" font-size="10" fill="#1e3a8a">导入</text>
|
||||
<rect x="250" y="45" width="40" height="30" fill="#fffbeb" stroke="#f59e0b" stroke-width="2" rx="4"/>
|
||||
<text x="270" y="64" text-anchor="middle" font-size="10" fill="#92400e">课文</text>
|
||||
</svg>
|
||||
<div style="text-align:center;font-size:10px;color:#94a3b8;">连线几乎不可见,画布干净</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">选中"导入"节点 — 连线 100% 显示</div>
|
||||
<div class="mockup-body" style="padding:16px;background:#f1f5f9;">
|
||||
<svg style="width:100%;height:120px;" viewBox="0 0 300 120">
|
||||
<path d="M 30 60 Q 120 60 270 60" stroke="#3b82f6" stroke-width="2.5" fill="none" stroke-dasharray="4 4" opacity="1"/>
|
||||
<circle cx="270" cy="60" r="5" fill="#3b82f6"/>
|
||||
<rect x="10" y="45" width="40" height="30" fill="#fff" stroke="#3b82f6" stroke-width="3" rx="4"/>
|
||||
<text x="30" y="64" text-anchor="middle" font-size="10" fill="#1e3a8a">导入</text>
|
||||
<rect x="250" y="45" width="40" height="30" fill="#fffbeb" stroke="#f59e0b" stroke-width="2" rx="4"/>
|
||||
<text x="270" y="64" text-anchor="middle" font-size="10" fill="#92400e">课文</text>
|
||||
</svg>
|
||||
<div style="text-align:center;font-size:10px;color:#3b82f6;">连线完整显示,高亮锚点位置</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据模型 -->
|
||||
<div class="section">
|
||||
<h3>数据模型设计</h3>
|
||||
<div style="background:#1e293b;color:#e2e8f0;padding:16px;border-radius:6px;font-family:monospace;font-size:11px;line-height:1.6;">
|
||||
<div style="color:#94a3b8;">// 正文容器节点(特殊节点类型,不可拖动,可缩放)</div>
|
||||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">TextbookContentNode</span> <span style="color:#f59e0b;">extends</span> <span style="color:#3b82f6;">LessonPlanNode</span> {</div>
|
||||
<div> type: <span style="color:#10b981;">"textbook_content"</span>; <span style="color:#64748b;">// 新增节点类型</span></div>
|
||||
<div> data: {</div>
|
||||
<div> chapterId: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 关联教材章节</span></div>
|
||||
<div> content: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// Markdown 正文(缓存)</span></div>
|
||||
<div> zoom: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// 缩放比例 0.5-2.0</span></div>
|
||||
<div> };</div>
|
||||
<div> position: { x: <span style="color:#10b981;">number</span>; y: <span style="color:#10b981;">number</span> }; <span style="color:#64748b;">// 固定位置(不可拖动)</span></div>
|
||||
<div> draggable: <span style="color:#10b981;">false</span>; <span style="color:#64748b;">// React Flow 节点锁定</span></div>
|
||||
<div>}</div>
|
||||
<br>
|
||||
<div style="color:#94a3b8;">// 锚点连线(节点 → 正文位置)</div>
|
||||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">AnchorEdge</span> <span style="color:#f59e0b;">extends</span> <span style="color:#3b82f6;">LessonPlanEdge</span> {</div>
|
||||
<div> type: <span style="color:#10b981;">"anchor"</span>; <span style="color:#64748b;">// 锚点连线(vs "flow" 流程连线)</span></div>
|
||||
<div> source: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 节点 ID</span></div>
|
||||
<div> target: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 正文节点 ID</span></div>
|
||||
<div> targetHandle: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// "anchor:123:145"(正文偏移量 start:end)</span></div>
|
||||
<div>}</div>
|
||||
<br>
|
||||
<div style="color:#94a3b8;">// LessonPlanDocument v3</div>
|
||||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">LessonPlanDocument</span> {</div>
|
||||
<div> version: <span style="color:#10b981;">3</span>;</div>
|
||||
<div> nodes: <span style="color:#3b82f6;">LessonPlanNode</span>[]; <span style="color:#64748b;">// 含 1 个 textbook_content + N 个教学节点</span></div>
|
||||
<div> edges: <span style="color:#3b82f6;">AnchorEdge</span> | <span style="color:#3b82f6;">FlowEdge</span>[]; <span style="color:#64748b;">// 锚点连线 + 流程连线</span></div>
|
||||
<div>}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 交互流程 -->
|
||||
<div class="section">
|
||||
<h3>核心交互流程</h3>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
|
||||
<div style="background:#fff;border:1px solid #e2e8f0;border-radius:6px;padding:12px;">
|
||||
<h4 style="margin:0 0 8px 0;color:#3b82f6;">🔗 锚定节点到正文</h4>
|
||||
<ol style="margin:0;padding-left:16px;font-size:11px;color:#475569;line-height:1.8;">
|
||||
<li>教师选中正文某段文字(或某个字)</li>
|
||||
<li>选中后弹出浮动菜单:"关联节点 →"</li>
|
||||
<li>从下拉列表选择已有节点,或"新建节点"</li>
|
||||
<li>创建 AnchorEdge,source=节点, target=正文节点, targetHandle="anchor:start:end"</li>
|
||||
<li>正文对应文字高亮显示(节点颜色)</li>
|
||||
<li>连线默认 10% 透明,选中节点时 100%</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div style="background:#fff;border:1px solid #e2e8f0;border-radius:6px;padding:12px;">
|
||||
<h4 style="margin:0 0 8px 0;color:#22c55e;">🖱️ 拖动节点到正文</h4>
|
||||
<ol style="margin:0;padding-left:16px;font-size:11px;color:#475569;line-height:1.8;">
|
||||
<li>教师从右侧节点列表拖动一个节点</li>
|
||||
<li>拖动过程中,正文区域高亮可放置区域</li>
|
||||
<li>拖到正文某个字前释放</li>
|
||||
<li>创建点锚点(point anchor),targetHandle="anchor:pos"</li>
|
||||
<li>节点自动定位到正文旁边(左或右空位)</li>
|
||||
<li>连线默认 10% 透明,选中时完整显示</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>设计要点</h3>
|
||||
<div class="pros-cons">
|
||||
<div class="pros">
|
||||
<h4>优势</h4>
|
||||
<ul>
|
||||
<li><strong>保留画布交互</strong>:缩放/平移/拖动节点,与当前备课模块一致</li>
|
||||
<li><strong>正文固定居中</strong>:不可拖动,始终是视觉中心</li>
|
||||
<li><strong>连线语义化</strong>:anchor 锚点连线 vs flow 流程连线</li>
|
||||
<li><strong>透明度策略</strong>:默认 10%,选中时 100%,画布不杂乱</li>
|
||||
<li><strong>正文可缩放</strong>:教师可放大正文便于阅读</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cons">
|
||||
<h4>技术挑战</h4>
|
||||
<ul>
|
||||
<li>正文偏移量需基于纯文本(Markdown 渲染后映射)</li>
|
||||
<li>正文内容变更后锚点需重新定位</li>
|
||||
<li>React Flow 自定义节点需处理正文渲染</li>
|
||||
<li>数据结构升级 v2 → v3,需迁移</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,226 @@
|
||||
<h2>备课模块布局方案对比</h2>
|
||||
<p class="subtitle">3 种布局方案 — 课文固定中央,教学节点围绕组织</p>
|
||||
|
||||
<div class="cards" data-multiselect>
|
||||
<!-- 方案 A -->
|
||||
<div class="card" data-choice="a" onclick="toggleSelect(this)">
|
||||
<div class="card-image" style="padding:12px;background:#f8fafc;">
|
||||
<div style="font-family:monospace;font-size:11px;line-height:1.4;">
|
||||
<div style="border:1px solid #cbd5e1;background:#e2e8f0;padding:4px 8px;border-radius:4px 4px 0 0;display:flex;justify-content:space-between;">
|
||||
<span>📖 秋天(第一课时)</span>
|
||||
<span>💾 已保存</span>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:200px 1fr 200px;gap:4px;padding:8px;background:#fff;border:1px solid #cbd5e1;border-top:none;border-radius:0 0 4px 4px;min-height:280px;">
|
||||
<!-- 左侧:课前 -->
|
||||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||||
<div style="font-size:9px;color:#64748b;text-align:center;">课前</div>
|
||||
<div style="background:#dbeafe;border:1px solid #3b82f6;padding:4px;border-radius:3px;font-size:10px;">🎯 教学目标</div>
|
||||
<div style="background:#fef3c7;border:1px solid #f59e0b;padding:4px;border-radius:3px;font-size:10px;">⭐ 重难点</div>
|
||||
<div style="background:#e0f2fe;border:1px solid #0ea5e9;padding:4px;border-radius:3px;font-size:10px;">💡 导入</div>
|
||||
<div style="background:#fce7f3;border:1px solid #ec4899;padding:4px;border-radius:3px;font-size:10px;">📝 文本研习</div>
|
||||
</div>
|
||||
<!-- 中央:课文 -->
|
||||
<div style="background:#fffbeb;border:2px solid #f59e0b;padding:8px;border-radius:4px;display:flex;flex-direction:column;">
|
||||
<div style="font-size:10px;color:#92400e;font-weight:bold;margin-bottom:4px;">📜 课文正文</div>
|
||||
<div style="font-size:9px;color:#78350f;line-height:1.5;flex:1;">
|
||||
天气凉了,树叶黄了,<br>
|
||||
一片片叶子从树上落下来。<br>
|
||||
<span style="background:#fef08a;">天空那么蓝,那么高</span>。<br>
|
||||
一群大雁往南飞,<br>
|
||||
一会儿排成个"人"字,<br>
|
||||
一会儿排成个"一"字。<br>
|
||||
<span style="background:#bbf7d0;">啊!秋天来了!</span>
|
||||
</div>
|
||||
<div style="font-size:8px;color:#92400e;margin-top:4px;">💡 选中文字可添加批注</div>
|
||||
</div>
|
||||
<!-- 右侧:课中/课后 -->
|
||||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||||
<div style="font-size:9px;color:#64748b;text-align:center;">课中</div>
|
||||
<div style="background:#dcfce7;border:1px solid #22c55e;padding:4px;border-radius:3px;font-size:10px;">📚 新授</div>
|
||||
<div style="background:#ede9fe;border:1px solid #8b5cf6;padding:4px;border-radius:3px;font-size:10px;">✏️ 练习</div>
|
||||
<div style="background:#fee2e2;border:1px solid #ef4444;padding:4px;border-radius:3px;font-size:10px;">📌 小结</div>
|
||||
<div style="font-size:9px;color:#64748b;text-align:center;margin-top:4px;">课后</div>
|
||||
<div style="background:#f3e8ff;border:1px solid #a855f7;padding:4px;border-radius:3px;font-size:10px;">🏠 作业</div>
|
||||
<div style="background:#e0e7ff;border:1px solid #6366f1;padding:4px;border-radius:3px;font-size:10px;">📋 板书设计</div>
|
||||
<div style="background:#f1f5f9;border:1px solid #64748b;padding:4px;border-radius:3px;font-size:10px;">💭 教学反思</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h3>A. 三栏布局(课前/课文/课后)</h3>
|
||||
<p>课文固定中央(琥珀色边框),左侧"课前"节点(目标/重难点/导入/文本研习),右侧"课中+课后"节点(新授/练习/小结/作业/板书/反思)。节点按教学流程纵向排列。点击节点在右侧抽屉编辑。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 方案 B -->
|
||||
<div class="card" data-choice="b" onclick="toggleSelect(this)">
|
||||
<div class="card-image" style="padding:12px;background:#f8fafc;">
|
||||
<div style="font-family:monospace;font-size:11px;line-height:1.4;">
|
||||
<div style="border:1px solid #cbd5e1;background:#e2e8f0;padding:4px 8px;border-radius:4px 4px 0 0;display:flex;justify-content:space-between;">
|
||||
<span>📖 秋天(第一课时)</span>
|
||||
<span>💾 已保存</span>
|
||||
</div>
|
||||
<div style="padding:8px;background:#fff;border:1px solid #cbd5e1;border-top:none;border-radius:0 0 4px 4px;min-height:280px;">
|
||||
<!-- 顶部:目标/重难点 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-bottom:4px;">
|
||||
<div style="background:#dbeafe;border:1px solid #3b82f6;padding:4px;border-radius:3px;font-size:10px;text-align:center;">🎯 教学目标</div>
|
||||
<div style="background:#fef3c7;border:1px solid #f59e0b;padding:4px;border-radius:3px;font-size:10px;text-align:center;">⭐ 重难点</div>
|
||||
</div>
|
||||
<!-- 中央:课文 + 左右两侧节点 -->
|
||||
<div style="display:grid;grid-template-columns:120px 1fr 120px;gap:4px;margin-bottom:4px;">
|
||||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||||
<div style="background:#e0f2fe;border:1px solid #0ea5e9;padding:4px;border-radius:3px;font-size:9px;text-align:center;">💡 导入</div>
|
||||
<div style="background:#fce7f3;border:1px solid #ec4899;padding:4px;border-radius:3px;font-size:9px;text-align:center;">📝 文本研习</div>
|
||||
</div>
|
||||
<div style="background:#fffbeb;border:2px solid #f59e0b;padding:8px;border-radius:4px;text-align:center;">
|
||||
<div style="font-size:10px;color:#92400e;font-weight:bold;">📜 课文正文</div>
|
||||
<div style="font-size:9px;color:#78350f;margin-top:4px;">天气凉了,树叶黄了...<br>天空那么蓝...<br>一群大雁往南飞...</div>
|
||||
</div>
|
||||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||||
<div style="background:#dcfce7;border:1px solid #22c55e;padding:4px;border-radius:3px;font-size:9px;text-align:center;">📚 新授</div>
|
||||
<div style="background:#ede9fe;border:1px solid #8b5cf6;padding:4px;border-radius:3px;font-size:9px;text-align:center;">✏️ 练习</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 底部:小结/作业/板书/反思 -->
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:4px;">
|
||||
<div style="background:#fee2e2;border:1px solid #ef4444;padding:4px;border-radius:3px;font-size:9px;text-align:center;">📌 小结</div>
|
||||
<div style="background:#f3e8ff;border:1px solid #a855f7;padding:4px;border-radius:3px;font-size:9px;text-align:center;">🏠 作业</div>
|
||||
<div style="background:#e0e7ff;border:1px solid #6366f1;padding:4px;border-radius:3px;font-size:9px;text-align:center;">📋 板书</div>
|
||||
<div style="background:#f1f5f9;border:1px solid #64748b;padding:4px;border-radius:3px;font-size:9px;text-align:center;">💭 反思</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h3>B. 上下分区布局</h3>
|
||||
<p>顶部目标/重难点横排,中央课文 + 左右导入/文本研习/新授/练习,底部小结/作业/板书/反思横排。按"目标→导入→课文→新授→小结"的阅读顺序自然流动。视觉层次更清晰。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 方案 C -->
|
||||
<div class="card" data-choice="c" onclick="toggleSelect(this)">
|
||||
<div class="card-image" style="padding:12px;background:#f8fafc;">
|
||||
<div style="font-family:monospace;font-size:11px;line-height:1.4;">
|
||||
<div style="border:1px solid #cbd5e1;background:#e2e8f0;padding:4px 8px;border-radius:4px 4px 0 0;display:flex;justify-content:space-between;">
|
||||
<span>📖 秋天(第一课时)</span>
|
||||
<span>💾 已保存</span>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:8px;background:#fff;border:1px solid #cbd5e1;border-top:none;border-radius:0 0 4px 4px;min-height:280px;">
|
||||
<!-- 左侧:课文 -->
|
||||
<div style="display:flex;flex-direction:column;gap:4px;">
|
||||
<div style="background:#fffbeb;border:2px solid #f59e0b;padding:8px;border-radius:4px;flex:1;">
|
||||
<div style="font-size:10px;color:#92400e;font-weight:bold;">📜 课文正文</div>
|
||||
<div style="font-size:9px;color:#78350f;margin-top:4px;line-height:1.5;">
|
||||
天气凉了,树叶黄了,<br>
|
||||
一片片叶子从树上落下来。<br>
|
||||
<span style="background:#fef08a;">天空那么蓝,那么高</span>。<br>
|
||||
一群大雁往南飞...
|
||||
</div>
|
||||
</div>
|
||||
<div style="background:#fce7f3;border:1px solid #ec4899;padding:4px;border-radius:3px;font-size:10px;text-align:center;">📝 文本研习(批注)</div>
|
||||
</div>
|
||||
<!-- 右侧:教学流程时间线 -->
|
||||
<div style="display:flex;flex-direction:column;gap:3px;">
|
||||
<div style="font-size:9px;color:#64748b;text-align:center;">教学流程</div>
|
||||
<div style="background:#dbeafe;border:1px solid #3b82f6;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#3b82f6;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">1</span>
|
||||
🎯 教学目标
|
||||
</div>
|
||||
<div style="background:#fef3c7;border:1px solid #f59e0b;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#f59e0b;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">2</span>
|
||||
⭐ 重难点
|
||||
</div>
|
||||
<div style="background:#e0f2fe;border:1px solid #0ea5e9;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#0ea5e9;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">3</span>
|
||||
💡 导入
|
||||
</div>
|
||||
<div style="background:#dcfce7;border:1px solid #22c55e;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#22c55e;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">4</span>
|
||||
📚 新授
|
||||
</div>
|
||||
<div style="background:#ede9fe;border:1px solid #8b5cf6;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#8b5cf6;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">5</span>
|
||||
✏️ 练习
|
||||
</div>
|
||||
<div style="background:#fee2e2;border:1px solid #ef4444;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#ef4444;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">6</span>
|
||||
📌 小结
|
||||
</div>
|
||||
<div style="background:#f3e8ff;border:1px solid #a855f7;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#a855f7;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">7</span>
|
||||
🏠 作业
|
||||
</div>
|
||||
<div style="background:#e0e7ff;border:1px solid #6366f1;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#6366f1;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">8</span>
|
||||
📋 板书
|
||||
</div>
|
||||
<div style="background:#f1f5f9;border:1px solid #64748b;padding:3px 6px;border-radius:3px;font-size:9px;display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#64748b;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;">9</span>
|
||||
💭 反思
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h3>C. 左课文 + 右时间线</h3>
|
||||
<p>左侧课文正文(固定)+ 文本研习批注,右侧教学流程时间线(编号 1-9 按顺序)。点击时间线节点展开编辑抽屉。最贴近传统教案本格式,结构清晰。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" style="margin-top:24px;">
|
||||
<h3>三种方案的核心差异</h3>
|
||||
<div class="pros-cons">
|
||||
<div class="pros">
|
||||
<h4>方案 A 三栏</h4>
|
||||
<ul>
|
||||
<li>课文始终居中可见</li>
|
||||
<li>课前/课后分区直观</li>
|
||||
<li>节点可拖动微调位置</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cons">
|
||||
<h4>方案 A 三栏</h4>
|
||||
<ul>
|
||||
<li>三栏可能拥挤(小屏)</li>
|
||||
<li>教学流程顺序不够明显</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pros-cons">
|
||||
<div class="pros">
|
||||
<h4>方案 B 上下分区</h4>
|
||||
<ul>
|
||||
<li>视觉层次最清晰</li>
|
||||
<li>阅读顺序自然(上→下)</li>
|
||||
<li>课文居中突出</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cons">
|
||||
<h4>方案 B 上下分区</h4>
|
||||
<ul>
|
||||
<li>节点位置较固定</li>
|
||||
<li>纵向空间需求大</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pros-cons">
|
||||
<div class="pros">
|
||||
<h4>方案 C 左课文+右时间线</h4>
|
||||
<ul>
|
||||
<li>最接近传统教案</li>
|
||||
<li>教学流程顺序最明确</li>
|
||||
<li>课文阅读体验最佳</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cons">
|
||||
<h4>方案 C 左课文+右时间线</h4>
|
||||
<ul>
|
||||
<li>节点画布感弱(更像列表)</li>
|
||||
<li>失去节点图连线能力</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,251 @@
|
||||
<h2>正文占位符标记布局</h2>
|
||||
<p class="subtitle">正文中嵌入占位符标记(特殊符号),默认接近透明,选中节点时完整显示</p>
|
||||
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">备课编辑器 — 默认状态(占位符 10% 透明度)</div>
|
||||
<div class="mockup-body" style="padding:0;background:#f1f5f9;overflow:hidden;">
|
||||
<div style="font-family:monospace;font-size:12px;line-height:1.6;position:relative;height:560px;">
|
||||
|
||||
<!-- 顶部工具栏 -->
|
||||
<div style="background:#1e293b;color:#e2e8f0;padding:8px 12px;display:flex;justify-content:space-between;align-items:center;z-index:10;position:relative;">
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span>📖</span>
|
||||
<span style="font-weight:bold;">秋天(第一课时)</span>
|
||||
<span style="background:#334155;padding:2px 8px;border-radius:3px;font-size:10px;">语文 · 一年级上册</span>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span style="font-size:10px;color:#94a3b8;">💾 已保存</span>
|
||||
<span style="background:#3b82f6;padding:4px 12px;border-radius:3px;font-size:10px;">💾 保存</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 画布区域 -->
|
||||
<div style="position:relative;width:100%;height:520px;background:#f1f5f9;background-image:radial-gradient(#cbd5e1 1px, transparent 1px);background-size:20px 20px;overflow:hidden;">
|
||||
|
||||
<!-- SVG 连线层(默认 10% 透明度) -->
|
||||
<svg style="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;opacity:0.1;" viewBox="0 0 800 520">
|
||||
<path d="M 130 120 Q 200 140 290 175" stroke="#3b82f6" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<path d="M 130 220 Q 200 230 290 215" stroke="#f59e0b" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<path d="M 670 120 Q 600 150 510 195" stroke="#0ea5e9" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<path d="M 670 220 Q 600 240 510 235" stroke="#ec4899" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<path d="M 670 340 Q 600 320 510 275" stroke="#22c55e" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
</svg>
|
||||
|
||||
<!-- 中央:正文容器(不可移动) -->
|
||||
<div style="position:absolute;left:280px;top:60px;width:240px;background:#fffbeb;border:2px solid #f59e0b;border-radius:8px;padding:12px;box-shadow:0 4px 12px rgba(0,0,0,0.1);">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;border-bottom:1px solid #fde68a;padding-bottom:6px;">
|
||||
<span style="font-size:11px;font-weight:bold;color:#92400e;">📜 课文正文</span>
|
||||
<span style="font-size:9px;color:#94a3b8;background:#fef3c7;padding:1px 4px;border-radius:2px;">🔒 固定</span>
|
||||
</div>
|
||||
<div style="font-size:13px;color:#78350f;line-height:2;">
|
||||
<div style="text-align:center;font-weight:bold;margin-bottom:6px;">秋天</div>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 占位符 1(导入节点)- 默认 10% 透明度 -->
|
||||
<span style="display:inline-block;background:#3b82f6;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.1;margin-right:2px;">①</span>天气凉了,树叶黄了,
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 占位符 2(文本研习)- 默认 10% 透明度 -->
|
||||
<span style="display:inline-block;background:#f59e0b;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.1;margin-right:2px;">②</span>天空那么蓝,那么高。
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
一群大雁往南飞,
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
一会儿排成个"人"字<span style="display:inline-block;background:#0ea5e9;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.1;margin-left:2px;">③</span>,
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
一会儿排成个"一"字<span style="display:inline-block;background:#ec4899;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.1;margin-left:2px;">④</span>。
|
||||
</p>
|
||||
<p style="margin:0;">
|
||||
<span style="display:inline-block;background:#22c55e;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.1;margin-right:2px;">⑤</span>啊!秋天来了!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 左侧节点 -->
|
||||
<div style="position:absolute;left:30px;top:90px;width:140px;background:#fff;border:1px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#3b82f6;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">1</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#1e3a8a;">💡 导入</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">提问:你见过秋天的树叶吗?</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:30px;top:200px;width:140px;background:#fff;border:1px solid #f59e0b;border-left:3px solid #f59e0b;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#f59e0b;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">2</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#92400e;">📝 文本研习</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">赏析:叠词的运用</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧节点 -->
|
||||
<div style="position:absolute;left:630px;top:90px;width:140px;background:#fff;border:1px solid #0ea5e9;border-left:3px solid #0ea5e9;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#0ea5e9;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">3</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#075985;">📚 新授</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">讲解:大雁南飞</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:630px;top:200px;width:140px;background:#fff;border:1px solid #ec4899;border-left:3px solid #ec4899;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#ec4899;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">4</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#9f1239;">✏️ 练习</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">3 道题</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:630px;top:320px;width:140px;background:#fff;border:1px solid #22c55e;border-left:3px solid #22c55e;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#22c55e;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">5</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#166534;">📌 小结</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">总结全文</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;top:12px;right:12px;background:#fff;border:1px solid #e2e8f0;border-radius:4px;padding:4px 8px;font-size:9px;color:#64748b;">
|
||||
占位符默认 10% · 选中节点时 100% 显示
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中状态对比 -->
|
||||
<div class="section" style="margin-top:24px;">
|
||||
<h3>选中"导入"节点时的状态变化</h3>
|
||||
<div class="split">
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">默认 — 占位符 ① 10% 透明度</div>
|
||||
<div class="mockup-body" style="padding:16px;background:#fffbeb;">
|
||||
<div style="font-size:14px;color:#78350f;line-height:2;font-family:serif;">
|
||||
<span style="display:inline-block;background:#3b82f6;color:#fff;border-radius:3px;padding:0 5px;font-size:10px;font-weight:bold;opacity:0.1;margin-right:3px;">①</span>天气凉了,树叶黄了,
|
||||
</div>
|
||||
<div style="margin-top:12px;font-size:10px;color:#94a3b8;text-align:center;">
|
||||
占位符几乎不可见 · 画布干净
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">选中"导入"节点 — 占位符 ① 100% + 连线显示</div>
|
||||
<div class="mockup-body" style="padding:16px;background:#fffbeb;">
|
||||
<div style="font-size:14px;color:#78350f;line-height:2;font-family:serif;">
|
||||
<span style="display:inline-block;background:#3b82f6;color:#fff;border-radius:3px;padding:0 5px;font-size:10px;font-weight:bold;opacity:1;margin-right:3px;box-shadow:0 0 0 2px #3b82f633;">①</span>天气凉了,树叶黄了,
|
||||
</div>
|
||||
<div style="margin-top:12px;font-size:10px;color:#3b82f6;text-align:center;">
|
||||
占位符完整显示 · 连线高亮 · 锚定位置清晰
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 占位符样式选项 -->
|
||||
<div class="section">
|
||||
<h3>占位符样式选项</h3>
|
||||
<p class="subtitle">选择占位符在正文中的视觉呈现方式</p>
|
||||
<div class="cards" data-multiselect>
|
||||
<div class="card" data-choice="number" onclick="toggleSelect(this)">
|
||||
<div class="card-image" style="padding:20px;background:#fffbeb;text-align:center;">
|
||||
<div style="font-size:16px;color:#78350f;font-family:serif;line-height:2;">
|
||||
<span style="display:inline-block;background:#3b82f6;color:#fff;border-radius:3px;padding:0 6px;font-size:11px;font-weight:bold;">①</span>天气凉了
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h3>数字圆圈</h3>
|
||||
<p>①②③④⑤ — 与节点编号对应,简洁清晰</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" data-choice="icon" onclick="toggleSelect(this)">
|
||||
<div class="card-image" style="padding:20px;background:#fffbeb;text-align:center;">
|
||||
<div style="font-size:16px;color:#78350f;font-family:serif;line-height:2;">
|
||||
<span style="display:inline-block;background:#3b82f6;color:#fff;border-radius:3px;padding:1px 5px;font-size:11px;">💡</span>天气凉了
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h3>节点图标</h3>
|
||||
<p>💡📝📚✏️📌 — 与节点类型图标一致,直观</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" data-choice="dot" onclick="toggleSelect(this)">
|
||||
<div class="card-image" style="padding:20px;background:#fffbeb;text-align:center;">
|
||||
<div style="font-size:16px;color:#78350f;font-family:serif;line-height:2;">
|
||||
<span style="display:inline-block;background:#3b82f6;color:#fff;border-radius:50%;width:10px;height:10px;font-size:8px;text-align:center;line-height:10px;">●</span>天气凉了
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h3>彩色圆点</h3>
|
||||
<p>● — 极简,颜色对应节点,不干扰阅读</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" data-choice="bracket" onclick="toggleSelect(this)">
|
||||
<div class="card-image" style="padding:20px;background:#fffbeb;text-align:center;">
|
||||
<div style="font-size:16px;color:#78350f;font-family:serif;line-height:2;">
|
||||
<span style="color:#3b82f6;font-weight:bold;">【1】</span>天气凉了
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h3>方括号编号</h3>
|
||||
<p>【1】【2】【3】— 类似脚注标记,学术感</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据模型更新 -->
|
||||
<div class="section">
|
||||
<h3>占位符数据模型</h3>
|
||||
<div style="background:#1e293b;color:#e2e8f0;padding:16px;border-radius:6px;font-family:monospace;font-size:11px;line-height:1.6;">
|
||||
<div style="color:#94a3b8;">// 正文中的占位符标记</div>
|
||||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">ContentPlaceholder</span> {</div>
|
||||
<div> id: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 占位符 ID</span></div>
|
||||
<div> nodeId: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 关联的节点 ID</span></div>
|
||||
<div> offset: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// 在正文纯文本中的字符偏移量</span></div>
|
||||
<div> label: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 显示的标记("①" / "💡" / "●" / "【1】")</span></div>
|
||||
<div> color: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 节点颜色(用于占位符背景)</span></div>
|
||||
<div>}</div>
|
||||
<br>
|
||||
<div style="color:#94a3b8;">// 正文渲染时注入占位符</div>
|
||||
<div><span style="color:#f59e0b;">function</span> <span style="color:#3b82f6;">renderContentWithPlaceholders</span>(</div>
|
||||
<div> content: <span style="color:#10b981;">string</span>, <span style="color:#64748b;">// Markdown 原文</span></div>
|
||||
<div> placeholders: <span style="color:#3b82f6;">ContentPlaceholder</span>[]</div>
|
||||
<div>): <span style="color:#10b981;">string</span> {</div>
|
||||
<div> <span style="color:#64748b;">// 按 offset 排序,在对应位置插入占位符标记</span></div>
|
||||
<div> <span style="color:#64748b;">// 渲染为 <span class="placeholder" data-node-id="xxx">①</span></span></div>
|
||||
<div>}</div>
|
||||
<br>
|
||||
<div style="color:#94a3b8;">// CSS 透明度控制</div>
|
||||
<div>.placeholder { <span style="color:#10b981;">opacity</span>: <span style="color:#f59e0b;">0.1</span>; <span style="color:#10b981;">transition</span>: <span style="color:#f59e0b;">opacity 0.2s</span>; }</div>
|
||||
<div>.placeholder.active { <span style="color:#10b981;">opacity</span>: <span style="color:#f59e0b;">1</span>; }</div>
|
||||
<div>.placeholder:hover { <span style="color:#10b981;">opacity</span>: <span style="color:#f59e0b;">0.6</span>; }</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>交互流程</h3>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
|
||||
<div style="background:#fff;border:1px solid #e2e8f0;border-radius:6px;padding:12px;">
|
||||
<h4 style="margin:0 0 8px 0;color:#3b82f6;">🔗 添加占位符</h4>
|
||||
<ol style="margin:0;padding-left:16px;font-size:11px;color:#475569;line-height:1.8;">
|
||||
<li>教师点击正文某个位置(光标位置)</li>
|
||||
<li>或选中一段文字后释放</li>
|
||||
<li>弹出菜单:"在此处添加节点 →"</li>
|
||||
<li>选择节点类型或已有节点</li>
|
||||
<li>在正文对应位置插入占位符标记</li>
|
||||
<li>创建 AnchorEdge 连线</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div style="background:#fff;border:1px solid #e2e8f0;border-radius:6px;padding:12px;">
|
||||
<h4 style="margin:0 0 8px 0;color:#22c55e;">👁️ 选中节点时的视觉反馈</h4>
|
||||
<ol style="margin:0;padding-left:16px;font-size:11px;color:#475569;line-height:1.8;">
|
||||
<li>点击画布上的某个节点</li>
|
||||
<li>该节点对应的占位符 opacity 从 0.1 → 1</li>
|
||||
<li>连线从 10% → 100% 显示</li>
|
||||
<li>占位符添加 active 样式(边框/阴影)</li>
|
||||
<li>其他占位符保持 10% 透明度</li>
|
||||
<li>点击空白处恢复默认状态</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,376 @@
|
||||
<h2>两种锚定方式的视觉规则</h2>
|
||||
<p class="subtitle">范围锚定(选文本)vs 点锚定(插入占位符)— 默认/选中状态对比</p>
|
||||
|
||||
<!-- 规则总览 -->
|
||||
<div class="section">
|
||||
<h3>视觉规则总览</h3>
|
||||
<div style="background:#1e293b;color:#e2e8f0;padding:16px;border-radius:6px;font-family:monospace;font-size:11px;line-height:1.8;">
|
||||
<div style="color:#94a3b8;">// 两种锚定方式</div>
|
||||
<div><span style="color:#f59e0b;">type</span> <span style="color:#3b82f6;">AnchorType</span> = <span style="color:#10b981;">"range"</span> | <span style="color:#10b981;">"point"</span>;</div>
|
||||
<br>
|
||||
<div style="color:#94a3b8;">// 范围锚定(选一段文本关联节点)</div>
|
||||
<div><span style="color:#94a3b8;">// 文本背景色 = 节点颜色</span></div>
|
||||
<div>.range-anchor {</div>
|
||||
<div> <span style="color:#10b981;">background-color</span>: <span style="color:#f59e0b;">var(--node-color)</span>; <span style="color:#64748b;">// 节点颜色</span></div>
|
||||
<div> <span style="color:#10b981;">opacity</span>: <span style="color:#f59e0b;">0</span>; <span style="color:#64748b;">// 默认完全透明(和正常文本一样)</span></div>
|
||||
<div>}</div>
|
||||
<div>.range-anchor.active {</div>
|
||||
<div> <span style="color:#10b981;">opacity</span>: <span style="color:#f59e0b;">0.3</span>; <span style="color:#64748b;">// 选中节点时显示背景色</span></div>
|
||||
<div>}</div>
|
||||
<br>
|
||||
<div style="color:#94a3b8;">// 点锚定(在文本中插入占位符)</div>
|
||||
<div>.point-anchor {</div>
|
||||
<div> <span style="color:#10b981;">opacity</span>: <span style="color:#f59e0b;">0.3</span>; <span style="color:#64748b;">// 默认半透明</span></div>
|
||||
<div>}</div>
|
||||
<div>.point-anchor.active {</div>
|
||||
<div> <span style="color:#10b981;">opacity</span>: <span style="color:#f59e0b;">1</span>; <span style="color:#64748b;">// 选中节点时不透明</span></div>
|
||||
<div>}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 完整画布:默认状态 -->
|
||||
<div class="section">
|
||||
<h3>完整画布 — 默认状态</h3>
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">默认状态(未选中任何节点)</div>
|
||||
<div class="mockup-body" style="padding:0;background:#f1f5f9;overflow:hidden;">
|
||||
<div style="font-family:monospace;font-size:12px;line-height:1.6;position:relative;height:480px;">
|
||||
|
||||
<!-- 画布 -->
|
||||
<div style="position:relative;width:100%;height:480px;background:#f1f5f9;background-image:radial-gradient(#cbd5e1 1px, transparent 1px);background-size:20px 20px;overflow:hidden;">
|
||||
|
||||
<!-- SVG 连线层(默认 10% 透明度) -->
|
||||
<svg style="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;opacity:0.1;" viewBox="0 0 800 480">
|
||||
<path d="M 130 100 Q 200 120 290 155" stroke="#3b82f6" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<path d="M 130 200 Q 200 210 290 195" stroke="#f59e0b" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<path d="M 670 100 Q 600 130 510 175" stroke="#0ea5e9" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<path d="M 670 200 Q 600 220 510 215" stroke="#ec4899" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
<path d="M 670 320 Q 600 300 510 255" stroke="#22c55e" stroke-width="2" fill="none" stroke-dasharray="4 4"/>
|
||||
</svg>
|
||||
|
||||
<!-- 中央:正文容器 -->
|
||||
<div style="position:absolute;left:280px;top:40px;width:240px;background:#fffbeb;border:2px solid #f59e0b;border-radius:8px;padding:12px;box-shadow:0 4px 12px rgba(0,0,0,0.1);">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;border-bottom:1px solid #fde68a;padding-bottom:6px;">
|
||||
<span style="font-size:11px;font-weight:bold;color:#92400e;">📜 课文正文</span>
|
||||
<span style="font-size:9px;color:#94a3b8;background:#fef3c7;padding:1px 4px;border-radius:2px;">🔒 固定</span>
|
||||
</div>
|
||||
<div style="font-size:13px;color:#78350f;line-height:2.2;">
|
||||
<div style="text-align:center;font-weight:bold;margin-bottom:6px;">秋天</div>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 范围锚定:默认 opacity:0(完全透明,和正常文本一样) -->
|
||||
<span style="background:#3b82f6;opacity:0;color:#78350f;">天气凉了</span>,树叶黄了,
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 点锚定:默认 opacity:0.3(半透明) -->
|
||||
<span style="display:inline-block;background:#f59e0b;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.3;margin-right:2px;">②</span>天空那么蓝,那么高。
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
一群大雁往南飞,
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 范围锚定:默认 opacity:0 -->
|
||||
一会儿排成个<span style="background:#0ea5e9;opacity:0;color:#78350f;">"人"字</span>
|
||||
<!-- 点锚定:默认 opacity:0.3 -->
|
||||
<span style="display:inline-block;background:#ec4899;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.3;margin-left:2px;">④</span>,
|
||||
</p>
|
||||
<p style="margin:0;">
|
||||
<!-- 点锚定:默认 opacity:0.3 -->
|
||||
<span style="display:inline-block;background:#22c55e;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.3;margin-right:2px;">⑤</span>啊!秋天来了!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 左侧节点 -->
|
||||
<div style="position:absolute;left:30px;top:70px;width:140px;background:#fff;border:1px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#3b82f6;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">1</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#1e3a8a;">💡 导入</span>
|
||||
<span style="margin-left:auto;font-size:8px;color:#94a3b8;background:#eff6ff;padding:1px 4px;border-radius:2px;">范围</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">提问:你见过秋天的树叶吗?</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:30px;top:180px;width:140px;background:#fff;border:1px solid #f59e0b;border-left:3px solid #f59e0b;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#f59e0b;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">2</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#92400e;">📝 文本研习</span>
|
||||
<span style="margin-left:auto;font-size:8px;color:#94a3b8;background:#fffbeb;padding:1px 4px;border-radius:2px;">点</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">赏析:叠词的运用</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧节点 -->
|
||||
<div style="position:absolute;left:630px;top:70px;width:140px;background:#fff;border:1px solid #0ea5e9;border-left:3px solid #0ea5e9;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#0ea5e9;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">3</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#075985;">📚 新授</span>
|
||||
<span style="margin-left:auto;font-size:8px;color:#94a3b8;background:#f0f9ff;padding:1px 4px;border-radius:2px;">范围</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">讲解:大雁南飞</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:630px;top:180px;width:140px;background:#fff;border:1px solid #ec4899;border-left:3px solid #ec4899;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#ec4899;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">4</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#9f1239;">✏️ 练习</span>
|
||||
<span style="margin-left:auto;font-size:8px;color:#94a3b8;background:#fdf2f8;padding:1px 4px;border-radius:2px;">点</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">3 道题</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:630px;top:300px;width:140px;background:#fff;border:1px solid #22c55e;border-left:3px solid #22c55e;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#22c55e;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">5</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#166534;">📌 小结</span>
|
||||
<span style="margin-left:auto;font-size:8px;color:#94a3b8;background:#f0fdf4;padding:1px 4px;border-radius:2px;">点</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">总结全文</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;top:12px;right:12px;background:#fff;border:1px solid #e2e8f0;border-radius:4px;padding:6px 10px;font-size:9px;color:#64748b;">
|
||||
<div>🔵 范围锚定:默认 opacity:0</div>
|
||||
<div>🔴 点锚定:默认 opacity:0.3</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中节点 1(范围锚定)的状态 -->
|
||||
<div class="section">
|
||||
<h3>选中"导入"节点(范围锚定)— 文本背景显示</h3>
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">选中节点 1 — "天气凉了"背景色显示</div>
|
||||
<div class="mockup-body" style="padding:0;background:#f1f5f9;overflow:hidden;">
|
||||
<div style="font-family:monospace;font-size:12px;line-height:1.6;position:relative;height:320px;">
|
||||
<div style="position:relative;width:100%;height:320px;background:#f1f5f9;background-image:radial-gradient(#cbd5e1 1px, transparent 1px);background-size:20px 20px;overflow:hidden;">
|
||||
|
||||
<!-- SVG 连线层(选中节点的连线 100% 显示) -->
|
||||
<svg style="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;" viewBox="0 0 800 320">
|
||||
<!-- 选中节点的连线 100% 显示 -->
|
||||
<path d="M 130 80 Q 200 100 290 135" stroke="#3b82f6" stroke-width="2.5" fill="none" stroke-dasharray="4 4" opacity="1"/>
|
||||
<circle cx="290" cy="135" r="5" fill="#3b82f6"/>
|
||||
<!-- 其他连线保持 10% -->
|
||||
<path d="M 130 180 Q 200 190 290 175" stroke="#f59e0b" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
<path d="M 670 80 Q 600 110 510 155" stroke="#0ea5e9" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
<path d="M 670 180 Q 600 200 510 195" stroke="#ec4899" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
<path d="M 670 280 Q 600 260 510 235" stroke="#22c55e" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
</svg>
|
||||
|
||||
<!-- 正文容器 -->
|
||||
<div style="position:absolute;left:280px;top:20px;width:240px;background:#fffbeb;border:2px solid #f59e0b;border-radius:8px;padding:12px;box-shadow:0 4px 12px rgba(0,0,0,0.1);">
|
||||
<div style="font-size:13px;color:#78350f;line-height:2.2;">
|
||||
<div style="text-align:center;font-weight:bold;margin-bottom:6px;">秋天</div>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 范围锚定:选中时 opacity:0.3(背景色显示) -->
|
||||
<span style="background:#3b82f6;opacity:0.3;color:#78350f;border-radius:2px;">天气凉了</span>,树叶黄了,
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 点锚定:未选中,保持 0.3 -->
|
||||
<span style="display:inline-block;background:#f59e0b;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.3;margin-right:2px;">②</span>天空那么蓝,那么高。
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">一群大雁往南飞,</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
一会儿排成个<span style="background:#0ea5e9;opacity:0;color:#78350f;">"人"字</span>
|
||||
<span style="display:inline-block;background:#ec4899;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.3;margin-left:2px;">④</span>,
|
||||
</p>
|
||||
<p style="margin:0;">
|
||||
<span style="display:inline-block;background:#22c55e;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.3;margin-right:2px;">⑤</span>啊!秋天来了!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中的节点 1(高亮边框) -->
|
||||
<div style="position:absolute;left:30px;top:50px;width:140px;background:#fff;border:2px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:6px;padding:8px;box-shadow:0 0 0 3px #3b82f633,0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#3b82f6;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">1</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#1e3a8a;">💡 导入</span>
|
||||
<span style="margin-left:auto;font-size:8px;color:#fff;background:#3b82f6;padding:1px 4px;border-radius:2px;">范围·选中</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">提问:你见过秋天的树叶吗?</div>
|
||||
</div>
|
||||
|
||||
<!-- 其他节点(正常状态) -->
|
||||
<div style="position:absolute;left:30px;top:160px;width:140px;background:#fff;border:1px solid #f59e0b;border-left:3px solid #f59e0b;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#f59e0b;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">2</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#92400e;">📝 文本研习</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:630px;top:50px;width:140px;background:#fff;border:1px solid #0ea5e9;border-left:3px solid #0ea5e9;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#0ea5e9;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">3</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#075985;">📚 新授</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;top:12px;right:12px;background:#fff;border:1px solid #3b82f6;border-radius:4px;padding:6px 10px;font-size:9px;color:#3b82f6;">
|
||||
✅ 选中"导入"节点 → "天气凉了"背景显示
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中节点 2(点锚定)的状态 -->
|
||||
<div class="section">
|
||||
<h3>选中"文本研习"节点(点锚定)— 占位符不透明</h3>
|
||||
<div class="mockup">
|
||||
<div class="mockup-header">选中节点 2 — 占位符 ② 100% 显示</div>
|
||||
<div class="mockup-body" style="padding:0;background:#f1f5f9;overflow:hidden;">
|
||||
<div style="font-family:monospace;font-size:12px;line-height:1.6;position:relative;height:320px;">
|
||||
<div style="position:relative;width:100%;height:320px;background:#f1f5f9;background-image:radial-gradient(#cbd5e1 1px, transparent 1px);background-size:20px 20px;overflow:hidden;">
|
||||
|
||||
<svg style="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;" viewBox="0 0 800 320">
|
||||
<path d="M 130 80 Q 200 100 290 135" stroke="#3b82f6" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
<!-- 选中节点的连线 100% -->
|
||||
<path d="M 130 180 Q 200 190 290 175" stroke="#f59e0b" stroke-width="2.5" fill="none" stroke-dasharray="4 4" opacity="1"/>
|
||||
<circle cx="290" cy="175" r="5" fill="#f59e0b"/>
|
||||
<path d="M 670 80 Q 600 110 510 155" stroke="#0ea5e9" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
<path d="M 670 180 Q 600 200 510 195" stroke="#ec4899" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
<path d="M 670 280 Q 600 260 510 235" stroke="#22c55e" stroke-width="2" fill="none" stroke-dasharray="4 4" opacity="0.1"/>
|
||||
</svg>
|
||||
|
||||
<div style="position:absolute;left:280px;top:20px;width:240px;background:#fffbeb;border:2px solid #f59e0b;border-radius:8px;padding:12px;box-shadow:0 4px 12px rgba(0,0,0,0.1);">
|
||||
<div style="font-size:13px;color:#78350f;line-height:2.2;">
|
||||
<div style="text-align:center;font-weight:bold;margin-bottom:6px;">秋天</div>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 范围锚定:未选中,opacity:0 -->
|
||||
<span style="background:#3b82f6;opacity:0;color:#78350f;">天气凉了</span>,树叶黄了,
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
<!-- 点锚定:选中时 opacity:1(不透明) -->
|
||||
<span style="display:inline-block;background:#f59e0b;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:1;margin-right:2px;box-shadow:0 0 0 2px #f59e0b44;">②</span>天空那么蓝,那么高。
|
||||
</p>
|
||||
<p style="margin:0 0 6px 0;">一群大雁往南飞,</p>
|
||||
<p style="margin:0 0 6px 0;">
|
||||
一会儿排成个<span style="background:#0ea5e9;opacity:0;color:#78350f;">"人"字</span>
|
||||
<span style="display:inline-block;background:#ec4899;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.3;margin-left:2px;">④</span>,
|
||||
</p>
|
||||
<p style="margin:0;">
|
||||
<span style="display:inline-block;background:#22c55e;color:#fff;border-radius:3px;padding:0 4px;font-size:9px;font-weight:bold;opacity:0.3;margin-right:2px;">⑤</span>啊!秋天来了!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:30px;top:50px;width:140px;background:#fff;border:1px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#3b82f6;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">1</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#1e3a8a;">💡 导入</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中的节点 2(高亮边框) -->
|
||||
<div style="position:absolute;left:30px;top:160px;width:140px;background:#fff;border:2px solid #f59e0b;border-left:3px solid #f59e0b;border-radius:6px;padding:8px;box-shadow:0 0 0 3px #f59e0b33,0 2px 6px rgba(0,0,0,0.08);">
|
||||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px;">
|
||||
<span style="background:#f59e0b;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">2</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#92400e;">📝 文本研习</span>
|
||||
<span style="margin-left:auto;font-size:8px;color:#fff;background:#f59e0b;padding:1px 4px;border-radius:2px;">点·选中</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#64748b;">赏析:叠词的运用</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;left:630px;top:50px;width:140px;background:#fff;border:1px solid #0ea5e9;border-left:3px solid #0ea5e9;border-radius:6px;padding:8px;box-shadow:0 2px 6px rgba(0,0,0,0.08);opacity:0.7;">
|
||||
<div style="display:flex;align-items:center;gap:4px;">
|
||||
<span style="background:#0ea5e9;color:#fff;border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;font-size:8px;font-weight:bold;">3</span>
|
||||
<span style="font-size:10px;font-weight:bold;color:#075985;">📚 新授</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position:absolute;top:12px;right:12px;background:#fff;border:1px solid #f59e0b;border-radius:4px;padding:6px 10px;font-size:9px;color:#f59e0b;">
|
||||
✅ 选中"文本研习"节点 → 占位符 ② 不透明显示
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 两种锚定方式对比表 -->
|
||||
<div class="section">
|
||||
<h3>两种锚定方式对比</h3>
|
||||
<div style="overflow-x:auto;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:12px;">
|
||||
<thead>
|
||||
<tr style="background:#1e293b;color:#e2e8f0;">
|
||||
<th style="padding:8px 12px;text-align:left;border:1px solid #334155;">特性</th>
|
||||
<th style="padding:8px 12px;text-align:left;border:1px solid #334155;">范围锚定(选文本)</th>
|
||||
<th style="padding:8px 12px;text-align:left;border:1px solid #334155;">点锚定(插入占位符)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr style="background:#fff;">
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;font-weight:bold;">触发方式</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">选中一段文字 → 关联节点</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">点击文本某位置 → 插入占位符</td>
|
||||
</tr>
|
||||
<tr style="background:#f8fafc;">
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;font-weight:bold;">视觉表现</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">文本背景色 = 节点颜色</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">插入标记符号(①②③)</td>
|
||||
</tr>
|
||||
<tr style="background:#fff;">
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;font-weight:bold;">默认透明度</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">
|
||||
<span style="background:#3b82f6;color:#fff;padding:2px 6px;border-radius:3px;font-size:10px;">opacity: 0</span>
|
||||
<span style="color:#64748b;font-size:10px;">(完全透明,和正常文本一样)</span>
|
||||
</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">
|
||||
<span style="background:#f59e0b;color:#fff;padding:2px 6px;border-radius:3px;font-size:10px;">opacity: 0.3</span>
|
||||
<span style="color:#64748b;font-size:10px;">(半透明,隐约可见)</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="background:#f8fafc;">
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;font-weight:bold;">选中时透明度</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">
|
||||
<span style="background:#3b82f6;color:#fff;padding:2px 6px;border-radius:3px;font-size:10px;">opacity: 0.3</span>
|
||||
<span style="color:#64748b;font-size:10px;">(背景色显示)</span>
|
||||
</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">
|
||||
<span style="background:#f59e0b;color:#fff;padding:2px 6px;border-radius:3px;font-size:10px;">opacity: 1</span>
|
||||
<span style="color:#64748b;font-size:10px;">(不透明,完整显示)</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="background:#fff;">
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;font-weight:bold;">连线透明度</td>
|
||||
<td colspan="2" style="padding:8px 12px;border:1px solid #e2e8f0;">
|
||||
默认 <span style="background:#64748b;color:#fff;padding:2px 6px;border-radius:3px;font-size:10px;">opacity: 0.1</span> · 选中时 <span style="background:#3b82f6;color:#fff;padding:2px 6px;border-radius:3px;font-size:10px;">opacity: 1</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="background:#f8fafc;">
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;font-weight:bold;">适用场景</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">节点与具体文字内容相关(如赏析某词、讲解某句)</td>
|
||||
<td style="padding:8px 12px;border:1px solid #e2e8f0;">节点对应文本某个位置(如在此处开始导入、在此处小结)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据模型 -->
|
||||
<div class="section">
|
||||
<h3>数据模型</h3>
|
||||
<div style="background:#1e293b;color:#e2e8f0;padding:16px;border-radius:6px;font-family:monospace;font-size:11px;line-height:1.6;">
|
||||
<div style="color:#94a3b8;">// 锚点 — 统一接口,区分 type</div>
|
||||
<div><span style="color:#f59e0b;">interface</span> <span style="color:#3b82f6;">NodeAnchor</span> {</div>
|
||||
<div> id: <span style="color:#10b981;">string</span>;</div>
|
||||
<div> nodeId: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 关联的节点</span></div>
|
||||
<div> type: <span style="color:#10b981;">"range"</span> | <span style="color:#10b981;">"point"</span>; <span style="color:#64748b;">// 两种锚定方式</span></div>
|
||||
<div> start: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// 正文纯文本偏移量</span></div>
|
||||
<div> end?: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// range 锚定的结束偏移(point 无)</span></div>
|
||||
<div> textPreview?: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// range 锚定的文字预览</span></div>
|
||||
<div>}</div>
|
||||
<br>
|
||||
<div style="color:#94a3b8;">// 渲染规则</div>
|
||||
<div><span style="color:#f59e0b;">function</span> <span style="color:#3b82f6;">getAnchorStyle</span>(anchor: <span style="color:#3b82f6;">NodeAnchor</span>, isActive: <span style="color:#10b981;">boolean</span>) {</div>
|
||||
<div> <span style="color:#f59e0b;">if</span> (anchor.type === <span style="color:#10b981;">"range"</span>) {</div>
|
||||
<div> <span style="color:#f59e0b;">return</span> { backgroundColor: getNodeColor(anchor.nodeId), opacity: isActive ? <span style="color:#f59e0b;">0.3</span> : <span style="color:#f59e0b;">0</span> };</div>
|
||||
<div> } <span style="color:#f59e0b;">else</span> { <span style="color:#64748b;">// point</span></div>
|
||||
<div> <span style="color:#f59e0b;">return</span> { opacity: isActive ? <span style="color:#f59e0b;">1</span> : <span style="color:#f59e0b;">0.3</span> };</div>
|
||||
<div> }</div>
|
||||
<div>}</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user