star-map.md
组件 · COMPONENT

星图 StarMap

学习地图:一条折线穿过五个站点。走过的站墨色实心、实线相连;当前站朱色,外圈一道脉冲光晕;还没到的站白底灰边、虚线相连。

5 站 · 已完成 2 站
第 1 站认识与建库✓ 为什么是 Obsid…✓ 建库与初始设置第 2 站连接想法✓ 界面与核心操作✓ 双链与反向链接第 3 站3图谱与插件✓ 图谱视图插件安装与安全Dataview… 共 4 节第 4 站4笔记方法卡片盒方法论第 5 站5内化输出从收集到内化
import { StarMapSvg } from './components/v4/StarMapSvg.jsx'
import { buildStarMap } from './domain/v4/mapGeometry.js'

const CATS = [{ ls: [['为什么是 Obsidian'], ['建库与初始设置'], ['界面与核心操作'], ['双链与反向链接'], ['图谱视图'], ['插件安装与安全'], ['Dataview'], ['Templater'], ['卡片盒方法论'], ['从收集到内化']] }]
const MAP = {
  nodes: [
    { t: '认识与建库', ref: [[0, 0], [0, 1]] },
    { t: '连接想法', ref: [[0, 2], [0, 3]] },
    { t: '图谱与插件', ref: [[0, 4], [0, 5], [0, 6], [0, 7]] },
    { t: '笔记方法', ref: [[0, 8]] },
    { t: '内化输出', ref: [[0, 9]] },
  ],
  pts: [[86, 292], [212, 148], [336, 262], [478, 128], [614, 268]],
}
const DONE = new Set(['0-0-0', '0-0-1', '0-0-2', '0-0-3', '0-0-4'])

export function Roadmap() {
  const geo = buildStarMap(MAP, CATS, DONE, 0)
  return (
    <div style={{ width: '100%', maxWidth: 740, background: '#FFFFFF', borderRadius: 16, border: '1px solid rgba(0,0,0,.09)' }}>
      <StarMapSvg geo={geo} onNodeClick={() => {}} />
    </div>
  )
}

几何从哪来

buildStarMap(map, cats, doneSet, courseIdx) 把地图数据变成绘图几何:22 颗装饰背景星、站间连线、每站前三节课的预览。map.pts 是 740 × 400 画布上的坐标,与 map.nodes 一一对应;doneSet 里的键是 课程-系列-课节

属性取值默认说明
geobuildStarMap(...) 的返回值{ stars, edges, nodes, … }
onNodeClick(index) => void点击站点

铁律

✓ 要朱色只给当前站:它就是「你在这里」
✗ 不要给已完成的站也上朱色
✓ 要脉冲光晕只挂在当前站(zzmPulse 2.6s)