Reveal.js与Web演示技术

引言

Web 演示技术将幻灯片从封闭的二进制格式解放到开放的 Web 平台——版本控制、协作编辑、嵌入代码、实时交互都成为可能。Reveal.js、Slidev、Marp 是当前最主流的三个方案。本文深入对比这些技术,并提供完整的实战指南。

一、技术方案对比

维度 Reveal.js Slidev Marp
技术栈 HTML/CSS/JS Vue 3 + Vite Markdown + CSS
编写格式 HTML/Markdown Markdown + Vue 纯 Markdown
学习曲线
定制能力 极高
代码高亮 highlight.js Shiki (VS Code 引擎) Prism.js
导出格式 PDF/HTML PDF/PNG/SPA PDF/PPTX/HTML
动画 CSS + 内置插件 Vue Transitions + Motion CSS
演讲者视图 内置 内置
实时协作 插件(Multiplex)
NPM 包 reveal.js slidev @marp-team/marp-cli
适合人群 前端开发者 Vue 开发者 所有人

二、Reveal.js 深度实战

2.1 快速开始

# 安装
npm init reveal.js my-presentation
cd my-presentation
npm install
npm start
# 访问 http://localhost:8000

2.2 基础结构

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="dist/reveal.css">
    <link rel="stylesheet" href="dist/theme/black.css">
</head>
<body>
    <div class="reveal">
        <div class="slides">
            <!-- 每个 section 是一页幻灯片 -->
            <section>
                <h1>演示标题</h1>
                <p>副标题 | 作者 | 日期</p>
            </section>

            <section>
                <h2>要点页面</h2>
                <ul>
                    <li class="fragment">第一点(逐步显示)</li>
                    <li class="fragment">第二点</li>
                    <li class="fragment">第三点</li>
                </ul>
            </section>

            <!-- 垂直幻灯片(二维导航) -->
            <section>
                <section>
                    <h2>章节标题</h2>
                </section>
                <section>
                    <h3>章节内容 1</h3>
                </section>
                <section>
                    <h3>章节内容 2</h3>
                </section>
            </section>

            <!-- 代码高亮 -->
            <section>
                <h2>代码示例</h2>
                <pre><code class="language-python" data-trim data-line-numbers="1-3|5-7">
def hello():
    print("Hello, Reveal.js!")
    return True

def main():
    result = hello()
    print(f"Result: {result}")
                </code></pre>
            </section>

            <!-- 背景图片 -->
            <section data-background-image="bg.jpg"
                     data-background-size="cover">
                <h2 style="color: white;">全屏背景</h2>
            </section>
        </div>
    </div>

    <script src="dist/reveal.js"></script>
    <script src="plugin/highlight/highlight.js"></script>
    <script>
        Reveal.initialize({
            hash: true,
            slideNumber: true,
            transition: 'slide',
            plugins: [RevealHighlight]
        });
    </script>
</body>
</html>

2.3 高级功能

// 配置选项
Reveal.initialize({
    // 导航
    hash: true,             // URL 哈希导航
    history: true,          // 浏览器历史
    slideNumber: 'c/t',     // 页码格式(当前/总数)
    showSlideNumber: 'all',

    // 动画
    transition: 'slide',     // none/fade/slide/convex/concave/zoom
    transitionSpeed: 'default',

    // 布局
    width: 1920,
    height: 1080,
    margin: 0.04,
    minScale: 0.2,
    maxScale: 2.0,

    // 自动播放
    autoSlide: 5000,         // 5秒自动翻页
    loop: true,              // 循环播放

    // 触控
    touch: true,
    hideInactiveCursor: true,

    // 插件
    plugins: [
        RevealHighlight,     // 代码高亮
        RevealMarkdown,      // Markdown 支持
        RevealMath,          // 数学公式
        RevealNotes,         // 演讲者备注
        RevealSearch,        // 搜索
        RevealZoom           // 缩放
    ]
});

// 事件监听
Reveal.on('slidechanged', event => {
    console.log(`Slide: ${event.indexh}.${event.indexv}`);
});

// API 控制
Reveal.slide(2, 0);     // 跳转到第3页
Reveal.next();           // 下一页
Reveal.prev();           // 上一页
Reveal.isLastSlide();    // 是否最后一页

2.4 Markdown 模式

<section data-markdown>
    <textarea data-template>
        ## Markdown 幻灯片

        - 支持所有标准 Markdown 语法
        - **加粗** 和 *斜体*
        - `行内代码`

        ---

        ## 第二页(---分隔)

        | 列1 | 列2 | 列3 |
        |-----|-----|-----|
        | A   | B   | C   |

        Note: 这是演讲者备注

        ---

        ## 代码块

        ```python
        def hello():
            return "Hello World"
        ```
    </textarea>
</section>

2.5 自定义主题

/* custom-theme.css */
.reveal {
    --r-background-color: #0F172A;
    --r-main-font: 'Inter', sans-serif;
    --r-heading-font: 'Montserrat', sans-serif;
    --r-main-color: #E2E8F0;
    --r-heading-color: #F8FAFC;
    --r-link-color: #38BDF8;
    --r-heading-text-transform: none;
    --r-heading-font-weight: 700;
    --r-main-font-size: 28px;
    --r-heading1-size: 2.5em;
    --r-heading2-size: 1.8em;
}

.reveal .slides section {
    text-align: left;
    padding: 40px;
}

.reveal h1 {
    border-bottom: 3px solid var(--r-link-color);
    padding-bottom: 16px;
}

.reveal code {
    background: rgba(56, 189, 248, 0.1);
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 0.85em;
}

三、Slidev 实战

3.1 快速开始

npm init slidev@latest my-slides
cd my-slides
npm run dev

3.2 Slidev 语法

---
theme: seriph
background: https://source.unsplash.com/1920x1080/?technology
class: text-center
highlighter: shiki
lineNumbers: false
drawings:
  persist: false
transition: slide-left
---

# 欢迎来到 Slidev

用 Markdown 写演示文稿

<div class="abs-br m-6 flex gap-2">
  <a href="https://github.com" target="_blank">GitHub</a>
</div>

---
layout: two-cols
---

# 左侧内容

- 要点一
- 要点二
- 要点三

::right::

# 右侧内容

```python
def hello():
    return "Hello Slidev"

layout: center class: text-center

居中大标题

这段文字也居中显示


transition: fade-out

代码高亮

function greet(name: string) {
  // 第一步高亮
  console.log(`Hello, ${name}!`)

  return true  // 第二步高亮
}

Vue 组件


### 3.3 Slidev vs Reveal.js

| 场景 | 推荐 | 原因 |
|------|------|------|
| 技术分享 | Slidev | 代码高亮最好、Vue 组件可嵌入 |
| 大型会议 | Reveal.js | 更成熟、更多插件、演讲者模式 |
| 快速演示 | Slidev | Markdown 即写即看 |
| 深度定制 | Reveal.js | HTML/CSS/JS 完全控制 |
| 团队协作 | Slidev | Git 友好、Markdown 简单 |
| 非技术受众 | Marp | 导出 PPTX、最简单 |

## 四、Marp 实战

### 4.1 基础用法

```markdown
---
marp: true
theme: default
paginate: true
header: '灵阙学院'
footer: '2025.09'
---

# 标题页

Marp 是最简单的 Markdown 演示工具

---

## 内容页

- 自动分页(三个横线分隔)
- 支持 HTML 标签
- 支持数学公式

$$E = mc^2$$

---

<!-- _class: invert -->
<!-- _backgroundColor: #1E293B -->

## 暗色模式页面

通过指令控制单页样式

---

## 图片页面

![bg right:40%](https://picsum.photos/800/600)

图片在右侧占 40% 宽度
文字在左侧

---

## 多列布局

<div style="display: flex; gap: 20px;">
<div>

### 列 1
- 内容 A
- 内容 B

</div>
<div>

### 列 2
- 内容 C
- 内容 D

</div>
</div>

4.2 Marp CLI

# 安装
npm install -g @marp-team/marp-cli

# 导出 PDF
marp slides.md --pdf

# 导出 PPTX
marp slides.md --pptx

# 导出 HTML
marp slides.md --html

# 实时预览
marp --preview slides.md

# 自定义主题
marp slides.md --theme custom.css --pdf

五、AI 集成:自动生成 Web 演示

def generate_revealjs(topic: str, num_slides: int = 10) -> str:
    """使用 AI 生成 Reveal.js 演示文稿"""
    content = generate_presentation_content(topic, num_slides)

    html_slides = []
    for slide in content["slides"]:
        if slide.get("layout_type") == "title_slide":
            html_slides.append(f"""
            <section>
                <h1>{slide['title']}</h1>
                <p>{slide.get('subtitle', '')}</p>
            </section>""")
        else:
            bullets = "".join(
                f'<li class="fragment">{bp}</li>'
                for bp in slide.get("bullet_points", [])
            )
            html_slides.append(f"""
            <section>
                <h2>{slide['title']}</h2>
                <ul>{bullets}</ul>
                <aside class="notes">{slide.get('speaker_notes', '')}</aside>
            </section>""")

    template = f"""<!DOCTYPE html>
<html><head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/theme/white.css">
</head><body>
<div class="reveal"><div class="slides">
{''.join(html_slides)}
</div></div>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5/dist/reveal.js"></script>
<script>Reveal.initialize({{hash:true,slideNumber:true}});</script>
</body></html>"""

    output_path = f"{topic.replace(' ', '_')}.html"
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(template)
    return output_path

六、部署与分发

部署方式 适用 特点
GitHub Pages 开源项目 免费、自动部署
Vercel/Netlify 团队项目 CI/CD、自定义域名
S3 + CloudFront 企业 可控、高可用
Docker 内网 离线可用
本地 HTML 文件 应急 最简单
# Slidev 构建并部署到 GitHub Pages
npx slidev build --base /my-slides/
# 将 dist/ 目录推送到 gh-pages 分支

# Reveal.js 构建
npm run build
# 将 dist/ 部署到任意静态托管

总结

Web 演示技术为技术团队提供了比 PowerPoint 更灵活的选择。Reveal.js 适合需要深度定制的大型演示,Slidev 适合 Vue 开发者的日常技术分享,Marp 适合追求极简的 Markdown 用户。三者都支持 Git 版本控制、代码高亮和 PDF 导出,是"代码即演示"理念的最佳实践。


Maurice | maurice_wen@proton.me