mdx-deck 演示者模式(Presenter Mode)与演讲者备注(Speaker Notes)完全指南
2026/9/23 9:20:20 网站建设 项目流程
  • 开发工具
  • 前端

【免费下载链接】mdx-deck

♠️ React MDX-based presentation decks

项目地址:https://gitcode.com/gh_mirrors/md/mdx-deck
点击查看免费下载

mdx-deck 是基于 React + MDX 的幻灯片演示框架,其"演示者模式"(Presenter Mode)专为现场演讲场景设计:演讲者在自己的屏幕控制进度,观众在投影仪上只看干净的幻灯片内容。本文以仓库文档 docs/presenting.md 为核心骨架,深入讲解演示者模式的完整操作流程、演讲者备注(Speaker Notes)的写法与底层实现原理,并结合 packages/gatsby-theme/src 源码,带你掌握一次专业演讲从"编写备注"到"双屏开讲"的完整闭环。

图片说明:上图为 mdx-deck 演示者模式的典型布局,来源 docs/images/presenter-mode.png,左侧为当前幻灯片(含缩略图指示器),右侧为下一张幻灯片预览,底部状态栏显示页码(Slide 1 of 7)、计时器、系统时钟与"Open in New Window"链接。

一、核心概念:什么是演示者模式

演示者模式(Presenter Mode)是 mdx-deck 面向真实演讲场景提供的"演讲者专属视图"。与观众看到的普通幻灯片不同,演示者模式下你的屏幕会额外显示:

  • 当前幻灯片:与投影仪/观众屏幕内容同步;
  • 下一张幻灯片预览:提前看到即将展示的内容,方便组织语言与节奏;
  • 演讲者备注(Speaker Notes):只显示在演示者屏幕上的提示文字;
  • 底部状态栏:页码(当前页/总页数)、演讲计时器、系统时钟、以及"在新窗口打开"链接。

从源码看,演示者模式由 packages/gatsby-theme/src/components/presenter.js 渲染,它通过useDeck()获取全局的演讲上下文(当前索引index、幻灯片总数length、演讲者备注notes),并使用Zoom组件对当前幻灯片(缩放3/4)和下一张幻灯片(Zoom ratio={4/3} zoom={1/4})进行缩放排版。底部状态栏则由 presenter-footer.js 提供,内嵌页码指示、新窗口链接、计时器(timer.js)与时钟(clock.js)。

这些组件组合后即形成文档开头截图 docs/images/presenter-mode.png 所示的界面。

二、进入演示者模式

根据 docs/presenting.md 的说明,进入演示者模式只需一个快捷键:

Opt + P

按下后,当前窗口即切换为演示者模式视图;再次按下则退出演示者模式,回到普通模式。

从 use-keyboard.js 的源码可以看到这一快捷键的底层实现:

} else if (altKey) { switch (e.keyCode) { case keys.p: // 80,即字母 P context.setState(toggleMode(modes.presenter)) break ...

其中toggleMode会在当前模式与modes.presenter'PRESENTER',见 constants.js)之间切换,即"按一次进入,再按一次退出"。这里使用altKey(macOS 的Opt键即 Option/Alt 键)配合字母P组合触发,注意该判断位于shiftKey分支之后,且metaKey/ctrlKey按下时会直接忽略(第 39 行),因此与系统级或浏览器级快捷键冲突的概率较低。

演示者模式的完整快捷键一览

结合 use-keyboard.js 的完整按键映射(keys常量定义于第 8–20 行),以下是演示者模式及周边常用快捷键汇总:

快捷键功能源码依据
Opt + P切换演示者模式(Presenter Mode)case keys.p位于altKey分支
Opt + O切换概览模式(Overview Mode)case keys.o(键码 79)
Opt + G切换网格模式(Grid Mode)case keys.g(键码 71)
//PageDown/Space下一张幻灯片(或下一步骤)keys.right/down/pageDown/space
//PageUp上一张幻灯片(或上一步骤)keys.left/up/pageUp
Shift + Space上一张幻灯片shiftKey分支
Shift + P切换打印模式并进入/print页面shiftKey分支
Esc退出当前模式,回到普通模式case keys.esc

需要特别说明的是:按键处理器在inputselecttextareaabutton等元素获得焦点时会忽略自定义快捷键(use-keyboard.js),避免在编辑文本或点击链接时误触翻页。这在演示过程中需要小心:如果你刚点击过页面上的某个链接/按钮,快捷键可能暂时失效,此时按Esc或点击空白区域让焦点回到页面主体即可恢复。

三、双屏演讲的标准操作流程

docs/presenting.md 给出了现场演讲的完整流程,这是该文档的核心实战部分,原文如下:

  1. Opt + P进入演示者模式;
  2. 点击窗口底部的链接,在另一个标签页打开演示;
  3. 将新标签页移动到观众可见的屏幕或投影仪所在窗口;
  4. 在原始窗口控制演示进度;
  5. 务必隐藏鼠标光标,避免其显示在观众屏幕上。

结合源码,这一流程的每一步都有对应的实现支撑:

  • 第 2 步的"底部链接":即 presenter-footer.js 中的 "Open in New Window ↗︎" 链接,它通过globalHistory.location.href获取当前页面的完整 URL,并使用target="_blank"在新标签页打开:
<a href={globalHistory.location.href} rel="noopener noreferrer" target="_blank" sx={{ color: 'inherit', textDecoration: 'none' }}> Open in New Window ↗︎ </a>
  • 第 4 步的"控制演示":演示者窗口与观众窗口共享同一 URL 路由(均基于index路由),翻页动作通过 navigate.js 调用navigate([slug, n].join('/'))改变路由;而新窗口与该窗口共享浏览器的历史/缓存状态,因此在原始窗口翻页时,观众窗口会同步跳转。换言之,两个窗口通过路由保持"双端同步",这就是"控制原始窗口、观众看新窗口"得以成立的技术基础。

  • 第 5 步"隐藏鼠标":属于演讲礼仪/操作层面的建议,仓库本身未提供自动隐藏光标的开关,需要演讲者自行处理(例如使用操作系统级的"演示时隐藏光标"选项或移动鼠标到屏幕角落)。

关于步骤(Steps)与翻页的细节

在演示者模式下翻页时,要注意 mdx-deck 的翻页是"步骤感知"的。从 navigate.js 的实现可见:

export const next = context => { const { steps, step, setState } = context if (!steps || step >= steps) return nextSlide(context) setState({ step: step + 1 }) }

即:如果当前幻灯片内部有步骤(如<Steps>组件、Appear组件等产生的分步内容)且尚未播完,按翻页键会先推进步骤,步骤播完后再跳到下一张幻灯片。向后翻页时(previous)则会先回到上一张幻灯片并将步骤重置为该页的步骤总数。这与 docs/components.md 中Steps组件的用法配合使用,可以在演示者模式下实现"逐步揭示"的演讲效果。

四、演讲者备注(Speaker Notes)

4.1 基本用法

演讲者备注(Speaker Notes)是只在演示者模式中显示的提示文字,普通模式下观众永远看不到。根据 docs/presenting.md 的说明,只需在任意幻灯片中使用<Notes />组件即可:

import { Notes } from 'mdx-deck' # Slide Content <Notes> Only visible in presenter mode </Notes>

几点要点:

  • 必须在文件顶部import { Notes } from 'mdx-deck'
  • <Notes>的内容可以是纯文本 / Markdown 列表 / 任意 JSX。在 docs/demo.mdx 中可以看到两种典型写法:Markdown 列表写法(第 58–63 行)与 JSX 写法(第 85–90 行):
<Notes> - These are speaker notes - And they won't be rendered in your slide </Notes>
<Notes> <ul> <li>Speaker notes can also be</li> <li>Written in JSX</li> </ul> </Notes>
  • 备注不会渲染进观众看到的幻灯片,只存在于演示者模式的右侧预览区下方。

4.2 底层实现原理

Notes组件的实现在 packages/gatsby-theme/src/components/notes.js:

export const Notes = props => { const context = useDeck() useEffect(() => { context.register(context.index, 'notes', props.children) }, [props.children]) return false }

可以看到,Notes组件本身不渲染任何 DOMreturn false),它只是通过useDeck()拿到全局上下文,并把props.children(即你写在标签内的内容)注册到当前幻灯片索引(context.index)对应的元数据中。这里的context.register来自 app.js:

const register = (index, key, value) => { if (state.metadata[index] && state.metadata[index][key]) return setState({ metadata: { [index]: { [key]: value, }, }, }) }

metadata是全局 reducer 状态的一部分(初始为{},见 app.js),以{ [幻灯片索引]: { notes: 内容 } }的结构存储。注册有去重保护:同一页同一键(notes)只注册一次。

而备注的"消费方"是演示者模式组件 presenter.js:

const notes = context.notes ? React.Children.toArray(context.notes) : false ... {notes && ( <div sx={{ my: 3 }}> {notes} </div> )}

它从useDeck()中取出当前索引对应的notes元数据,渲染在右侧"下一张预览"的下方。只有演示者模式(PRESENTER)会渲染notes,普通模式根本不渲染 presenter.js,这从机制上保证了"备注只对演讲者可见"。

4.3 备注的编写建议

结合 docs/demo.mdx 中实际使用的备注风格,建议:

  • 用简短的要点列出"这张幻灯片你要讲什么、重点是什么、别忘了什么";
  • 可以直接放完整台词(纯文本即可),也可以放结构化列表;
  • 涉及图片幻灯片时,可以写图片意图说明(demo.mdx 第 109–111 行写的是Testing object fit,即记录测试意图);
  • 因为备注支持 JSX,甚至可以嵌入链接、强调等元素。

五、演示者模式的状态栏:页码、计时器与时钟

演示者模式底部状态栏(presenter-footer.js)从左到右包含四块内容:

  1. 页码指示{index} / {length - 1},即当前页(从 0 开始)与总页数(length - 1);
  2. "Open in New Window ↗︎"链接:用于双屏演讲时打开观众窗口;
  3. 计时器(Timer):由 timer.js 实现;
  4. 时钟(Clock):由 clock.js 实现。

计时器的操作

timer.js 提供两个按钮与一个时间显示:

  • Start / Stoptoggle切换timer布尔状态,计时中每秒把seconds + 1写入全局状态;
  • ResetsetState({ seconds: 0 })清零(当seconds为 0 时按钮禁用);
  • 时间显示格式为hh:mm:ss(依赖hhmmss库),如截图 docs/images/presenter-mode.png 底部的00:17

计时器状态(timerseconds)同样存于全局 context 中,因此切页、切换模式都不会丢失计时进度,方便演讲者精确控制每场演讲的时长。

时钟

clock.js 每秒刷新一次toLocaleTimeString()输出当前系统时间,帮助演讲者把握"讲了多久、还剩多少时间"。在截图 docs/images/presenter-mode.png 右下角可以看到示例时间5:41:17 PM

六、从演示到导出:演示者模式的延伸场景

演示者模式并非孤立功能,它与其他模式共享同一套模式状态机(constants.js 定义了normal / presenter / overview / grid / print五种模式)与同一套useDeck()上下文。掌握演示者模式后,你可以顺带了解:

  • 概览模式(Opt + O:左侧为可滚动缩略图列表(SlideList),右侧为当前幻灯片大图预览,点击缩略图即可跳转,实现在 overview.js,适合演讲前快速通览全部内容;
  • 网格模式(Opt + G:将全部幻灯片平铺展示;
  • 打印模式(Shift + P:跳转到/print路径,配合 docs/exporting.md 可导出 PDF 讲义。

注:概览、网格、打印等模式在 docs/presenting.md 中未展开描述,此处仅为演示者模式周边能力的延伸提示,具体用法可查阅 docs/api.md 与 docs/components.md。

七、常见问题排查

  • Opt + P无反应:检查当前焦点元素是否落在input/button等元素上(快捷键会被忽略);确认没有其他软件占用了Alt + P组合键。
  • 观众窗口不同步:确认两个窗口打开的是同一个 URL(含相同 slug 前缀);演示者窗口翻页实际是路由跳转(navigate([slug, n].join('/'))),观众窗口需保持在同一路由体系下。
  • 备注没有显示:确认在 mdx 文件顶部import { Notes } from 'mdx-deck';确认当前处于演示者模式(Opt + P),普通模式下不渲染备注。
  • 想要隐藏光标:仓库未内置该功能,请在操作系统层面设置"演示时隐藏指针",或演讲时把鼠标移出投影区域。

八、小结

演示者模式是 mdx-deck 现场演讲体验的核心。通过Opt + P一键进入,配合"新窗口打开 + 双屏同步"的流程设计,以及只对演讲者可见的<Notes>备注、页码/计时器/时钟状态栏,mdx-deck 把"写演示、讲演示、控演示"整合为一条流畅的工作流。如果想进一步深入,推荐继续阅读 docs/api.md(模式与上下文 API)、docs/components.md(StepsAppear等与翻页联动的组件),以及 docs/exporting.md(打印/导出),并可在 packages/gatsby-theme/src/components 目录下查看上述全部组件的源码实现。

  • 开发工具
  • 前端

【免费下载链接】mdx-deck

♠️ React MDX-based presentation decks

项目地址:https://gitcode.com/gh_mirrors/md/mdx-deck
点击查看免费下载

相关推荐

上一篇:为什么你的微服务拆分总是失败?Modularization-examples教你避免常见陷阱
下一篇:探索英特尔ISL的MultiObjectiveOptimization项目:多目标优化的新里程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询