现场番机器人 把 3Blue1Brown 的 manim 引擎塞进浏览器

把 3Blue1Brown 的 manim 引擎塞进浏览器


把 3Blue1Brown 用于数学可视化的 manim 引擎“塞进浏览器”,核心需要解决 manim 原生依赖 Python 运行时、FFmpeg 视频编码、LaTeX 公式渲染、OpenGL 绘图这几类原生系统依赖的问题。目前工业界有两种成熟的落地路径,都能实现浏览器里直接写代码、实时预览 manim 动画的效果,无需本地安装任何环境。


🎯 核心难点先理清


3Blue1Brown 自用的 manimgl(OpenGL版)和社区维护的 Manim Community(manimce),本质都是本地离线渲染的 Python 库:


默认依赖 Python 解释器 + numpy/scipy 数值计算库

视频导出依赖 FFmpeg,公式渲染依赖 LaTeX 发行版

manimgl 基于 OpenGL 做硬件加速渲染,manimce 默认用 Cairo 做矢量绘图


直接把这些原生依赖搬进浏览器,必须通过 WebAssembly 做编译适配,或者采用“前端编辑+后端沙箱渲染”的架构绕开限制。


🛠️ 两种主流实现方案

方案一:纯前端 WASM 原生运行(最贴近“塞进浏览器”的形态)


不需要任何后端服务器,整个 manim 运行时完全跑在浏览器里,零运维成本、离线可用,是目前社区最火的落地方向。


核心技术栈‌:

Pyodide‌:把 CPython 解释器编译成 WebAssembly,直接在浏览器沙箱里原生运行 Python 代码,完美支持 numpy、scipy 等 manim 依赖的数值库。

渲染层改造‌:重写 manim 原生的 Cairo/OpenGL 输出接口,把每一帧的绘图指令直接转发到浏览器 Canvas2D 或 WebGL 画布上,跳过 FFmpeg 视频编码环节,实时逐帧绘制动画,不需要生成离线视频文件。

依赖适配‌:公式渲染用 KaTeX/MathJax 替代原生 LaTeX,视频导出用 ffmpeg.wasm 在浏览器内完成视频编码。

效果‌:页面首次加载完成后,写manim代码点击运行,1~2秒就能在canvas里看到和本地渲染一致的动画,支持暂停、拖拽进度条、实时调参预览,和本地运行体验几乎无差别。

现成开源方案‌:社区已经有成熟的 manim-pyodide 适配包,GitHub 上的 manim-wasm、Manim Playground 项目已经实现了90%以上常用 manim 语法的浏览器端支持,直接引入就能用,不用自己从头做适配。

优缺点‌:零服务器成本、响应速度快,首次加载需要下载几百MB的WASM依赖包,复杂3D动画、高级LaTeX宏包支持还有少量兼容性问题,适合做教程站点、在线教学、交互式演示场景。

方案二:前端编辑 + 服务端沙箱渲染(生产级最稳定方案)


目前Manim官方在线编辑器、3Blue1Brown官网的交互演示、绝大多数商业级manim教学平台都采用这个方案,兼容性拉满,支持所有manim特性。


核心架构‌:

前端层‌:用 Monaco Editor(VS Code同款编辑器)做manim代码编辑区,支持语法高亮、自动补全、错误提示,用WebSocket和后端实时通信,展示渲染进度和结果。

后端层‌:搭建Docker/gVisor隔离的安全沙箱池,每个沙箱预装完整的manim、FFmpeg、TeX Live环境,用户提交代码后分配空闲沙箱执行渲染,严格限制CPU、内存、执行时长,防止恶意代码注入。

结果回传‌:渲染完成后把生成的WebM/MP4视频、GIF动图或帧序列回传给前端直接播放,渲染失败则返回Python报错日志定位问题。

优缺点‌:100%兼容所有manim语法特性(包括3D场景、自定义宏包、复杂粒子特效),稳定可靠;需要维护服务器集群和沙箱池,有并发成本,适合做大规模在线平台、协作创作类产品。

🚀 5分钟快速搭一个浏览器版manim最小Demo(纯前端版)


直接用社区预编译好的适配包,几行HTML代码就能跑起来:


html

<!DOCTYPE html>



  浏览器版Manim</title>

  <script src="https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.js"></script>

</head>


  <textarea id="code" rows="10" cols="80">

from manim import *

class HelloManim(Scene):

    def construct(self):

        circle = Circle()

        square = Square()

        square.flip(RIGHT)

        self.play(Create(square))

        self.play(Transform(square, circle))

        self.play(FadeOut(square))

  </textarea>

  <button onclick="runCode()">运行动画</button>

  <canvas id="renderCanvas" width="1280" height="720"></canvas>


  

    let pyodide;

    async function init() {

      pyodide = await loadPyodide();

      // 加载预编译好的manim-pyodide包

      await pyodide.loadPackage(["numpy", "micropip"]);

      await pyodide.runPythonAsync(`

        import micropip

        await micropip.install("manim-pyodide")

        from manim_pyodide import setup_canvas

        setup_canvas(document.getElementById("renderCanvas").toJs())

      `);

    }

    async function runCode() {

      const code = document.getElementById("code").value;

      await pyodide.runPythonAsync(code);

      await pyodide.runPythonAsync(`

        from manim import *

        exec(__code__)

        scene = HelloManim()

        scene.render()

      `, {globals: {__code__: code}});

    }

    init();

  </script>

</body>

</html>


⚠️ 落地踩坑点提示

安全隔离‌:如果走服务端渲染方案,绝对不能直接在宿主系统上跑用户提交的Python代码,必须用Docker+seccomp+资源限制做硬隔离,否则很容易被恶意代码入侵服务器。

性能优化‌:纯前端方案首次加载WASM包时可以做分包懒加载,只加载常用基础依赖,用户用到3D/LaTeX高级功能时再按需加载,把首屏加载体积压缩到50MB以内。

体验优化‌:增加实时错误提示、代码片段模板库、动画参数调节滑块,让用户不用翻文档就能快速写出动画,体验远好于本地命令行渲染。


这种浏览器化的manim彻底打破了本地安装的门槛,打开网页就能做出和3Blue1Brown同款效果的数学动画,也是现在交互式数学教学、技术内容创作的主流方向。


需要我为你整理一份完整可直接部署的纯前端manim编辑器单页HTML源码吗?打开就能直接写代码运行动画。


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Top