|
| 1 | +--- |
| 2 | +title: 滚谱的扎法 |
| 3 | +date: "2026-05-04" |
| 4 | +kind: ESSAY |
| 5 | +summary: 从 MEI 到一个能在网页里横向滚动、声音同步的乐谱组件。 |
| 6 | +tint: dune |
| 7 | +draft: true |
| 8 | +--- |
| 9 | + |
| 10 | +import Score from '../../components/Score.astro'; |
| 11 | + |
| 12 | +{/* |
| 13 | + 起草大纲(按 cue 顺序): |
| 14 | +
|
| 15 | + why-mei — MEI / MusicXML 是什么。为什么不画 PNG。 |
| 16 | + Verovio 把 MEI 渲到 SVG 是个起点,但只是起点。 |
| 17 | + one-system — `breaks: 'none'` 把一首曲子排成一整条横向系统。 |
| 18 | + 天然给"横向滚动"提供了画布。 |
| 19 | + `pageWidth: 100000, adjustPageHeight: true`。 |
| 20 | + staff-anchor — viewBox 的坑:bbox 含装饰,装饰多 → staff 被压扁。 |
| 21 | + 解:以 staff body 为锚反推舞台高度(measure 一次, |
| 22 | + 重设 --score-h,回流,继续)。 |
| 23 | + 本博客的 staffHeight = 40 默认。 |
| 24 | + tile — Ravel 全曲 SVG 宽 ~37k px,撞 GPU 单纹理上限。 |
| 25 | + 沿小节切 tile(≤4096px),每片自己一个 viewBox |
| 26 | + crop,外层 GPU 各管各的。 |
| 27 | + anchors — 把每个音符的 onset ms 映射到屏幕 x。线性插值 + |
| 28 | + 游标缓存(O(1) 稳态)。msAtX/xAtMs 双向。 |
| 29 | + loop — 多份 SVG 副本贴边铺开 + 幻影前导 tile。看到的 |
| 30 | + seam 都是设计过的。 |
| 31 | + recap — 整套架构是写给一个人的:作者读自己的谱子的时候 |
| 32 | + 不应该被装饰量影响视觉权重,不应该被 GPU 限制 |
| 33 | + 打到 10fps,不应该听一段需要按 5 个键。 |
| 34 | +*/} |
| 35 | + |
| 36 | +<section data-cue="why-mei"> |
| 37 | + |
| 38 | +{/* TODO: MEI/MusicXML 简介,Verovio 是什么。 */} |
| 39 | + |
| 40 | +</section> |
| 41 | + |
| 42 | +<section data-cue="one-system"> |
| 43 | + |
| 44 | +{/* TODO: `breaks: 'none'` 的决定 */} |
| 45 | + |
| 46 | +<Score slug="jeux-deau" /> |
| 47 | + |
| 48 | +</section> |
| 49 | + |
| 50 | +<section data-cue="staff-anchor"> |
| 51 | + |
| 52 | +{/* TODO: viewBox 含装饰的问题 + staff-anchor 的解。 */} |
| 53 | + |
| 54 | +</section> |
| 55 | + |
| 56 | +<section data-cue="tile"> |
| 57 | + |
| 58 | +{/* TODO: GPU 纹理上限 + tile 切片。 */} |
| 59 | + |
| 60 | +<Score slug="jeux-deau-ravel" /> |
| 61 | + |
| 62 | +</section> |
| 63 | + |
| 64 | +<section data-cue="anchors"> |
| 65 | + |
| 66 | +{/* TODO: msAtX/xAtMs,游标缓存。 */} |
| 67 | + |
| 68 | +</section> |
| 69 | + |
| 70 | +<section data-cue="loop"> |
| 71 | + |
| 72 | +{/* TODO: 多副本 + 幻影 leader 的实现。 */} |
| 73 | + |
| 74 | +<Score slug="jeux-deau" loop /> |
| 75 | + |
| 76 | +</section> |
| 77 | + |
| 78 | +<section data-cue="recap"> |
| 79 | + |
| 80 | +{/* TODO: 收。整套是为读自己的谱子写的。 */} |
| 81 | + |
| 82 | +</section> |
0 commit comments