Files
NextEdu/.superpowers/brainstorm/41500-1782168322.9344/content/placeholder-markers.html
SpecialX 19a05091d3 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 无新增错误
2026-07-06 19:01:57 +08:00

252 lines
16 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.
<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>&nbsp;&nbsp;id: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 占位符 ID</span></div>
<div>&nbsp;&nbsp;nodeId: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 关联的节点 ID</span></div>
<div>&nbsp;&nbsp;offset: <span style="color:#10b981;">number</span>; <span style="color:#64748b;">// 在正文纯文本中的字符偏移量</span></div>
<div>&nbsp;&nbsp;label: <span style="color:#10b981;">string</span>; <span style="color:#64748b;">// 显示的标记("①" / "💡" / "●" / "【1】"</span></div>
<div>&nbsp;&nbsp;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>&nbsp;&nbsp;content: <span style="color:#10b981;">string</span>, <span style="color:#64748b;">// Markdown 原文</span></div>
<div>&nbsp;&nbsp;placeholders: <span style="color:#3b82f6;">ContentPlaceholder</span>[]</div>
<div>): <span style="color:#10b981;">string</span> {</div>
<div>&nbsp;&nbsp;<span style="color:#64748b;">// 按 offset 排序,在对应位置插入占位符标记</span></div>
<div>&nbsp;&nbsp;<span style="color:#64748b;">// 渲染为 &lt;span class="placeholder" data-node-id="xxx"&gt;&lt;/span&gt;</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>