Manim 是 3Blue1Brown 使用的著名数学动画库,以其精确的几何变换、LaTeX 渲染和流畅动画闻名,但依赖 Python 环境、FFmpeg 渲染视频,导致部署门槛高、实时交互难。manim-web 将其核心移植到 TypeScript,完全浏览器原生执行,利用 Canvas 2D/WebGL(Three.js 3D 支持)和 KaTeX 实现零依赖可视化。这不仅保留了原 API 相似性,还支持交互式场景,适用于 Web 教育工具、数据可视化仪表盘。
项目核心技术栈与实现原理
manim-web 的渲染层基于 WebGL,利用 Three.js 处理 3D 几何(如 Sphere、Surface3D)和光照(AmbientLight、DirectionalLight),2D 则 fallback 到 Canvas2D 以兼容低端设备。LaTeX 通过 KaTeX 即时渲染为 SVG 路径,支持 Create(描边绘制)、Transform(变形)等动画。动画系统采用时间线驱动:每个 Animation(如 FadeIn、MoveToTarget)定义 run 时长(默认 1s)、rateFunc(easing,如 linear、smooth)和 lagRatio(组动画延迟)。
关键创新是 Updater 机制:对象可附加动态回调,每帧(~60fps)更新位置 / 样式,实现 ValueTracker 驱动的实时曲线(如正弦波点追踪)。例如,ValueTracker.animateTo (target, duration=2) 平滑插值,支持 addUpdater ((mobj, dt) => mobj.rotate (dt)) 连续旋转。布尔运算(Union、Intersection)使用 ClipperLib 路径裁剪,3D 表面通过 ParametricFunction 生成顶点网格。
性能瓶颈主要在高分辨率 LaTeX(fontSize>48)和复杂网格(uResolution>50)。建议参数:strokeWidth=2-4(平衡清晰 / 渲染速)、fillOpacity=0.5(减少 overdraw)、numSamples=200(曲线采样)。浏览器 FPS 监控:requestAnimationFrame 内检查 deltaTime >16ms 时降级 resolution。
快速上手与基本参数配置
安装:npm i manim-web,导入 Scene/Circle 等。核心流程:
- 创建容器:
<div id="container" style="width:800px;height:450px;"></div> - 初始化 Scene:
new Scene(container, {width:800, height:450, backgroundColor:'#000'}) - 构建对象:
const circle = new Circle({radius:1.5, color:'blue', fillOpacity:0.8}); - 动画序列:
await scene.play(new Create(circle, {duration:1.5}), new Transform(circle, square)); - 渲染循环:Scene 自动管理 RAF。
示例:正方形变圆(经典 demo):
import { Scene, Circle, Square, Create, Transform, FadeOut } from 'manim-web';
async function demo(scene: Scene) {
const square = new Square({ sideLength: 3, color: 'blue' });
const circle = new Circle({ radius: 1.5, color: 'green' });
await scene.play(new Create(square, { rateFunc: 'ease-in-out', duration: 1 }));
await scene.play(new Transform(square, circle, { pathArc: Math.PI/4 })); // 弧形路径,参数可调
await scene.play(new FadeOut(circle));
}
const scene = new Scene(document.getElementById('container'));
demo(scene);
参数清单:
- Animation:duration=1(s),rateFunc='linear'/'cubic'/'ease',scaleFactor=1.2(缩放)。
- Mobject:strokeWidth=3,strokeOpacity=0.9,fillColor='hsl (200,50%,50%)'(动态色)。
- Axes/Graph:xRange=[-10,10,1](范围 / 刻度),plot (lambda x: sin (x), {color:'red', numSamples:300})。
- 3D:ThreeDScene (phi=75° 仰角,theta=-45° 方位,fov=30, distance=20),Surface3D (uResolution=24)。
回滚策略:复杂场景 FPS<30 时,切换 MathTexSVG(矢量路径优于栅格)、禁用 shadows(light intensity=1.0)。
高级用法:交互与框架集成
支持 Draggable/Hoverable:mobj.setDraggable() 绑定 pointermove,实现交互函数图。ValueTracker + Updater 示例(动态角度):
const tracker = new ValueTracker(0);
const line = new Line(LEFT, RIGHT);
line.addUpdater(mob => mob.rotate(tracker.value * Math.PI/180));
await scene.play(tracker.animateTo(360, {duration:4})); // 实时更新
框架集成:
- React:
<ManimScene construct={demo} width={800} height={450} /> - Vue:
<ManimScene :construct="demo" :width="800" /> - Python 迁移:
node tools/py2ts.cjs input.py -o output.ts半自动转换。
3D 案例:高斯表面 Surface3D(func=(u,v)=>[u, exp(-(u^2+v^2)), -v], checkerboardColors=['orange','blue']),结合 beginAmbientCameraRotation (0.1) 自动旋转。
监控要点:
- FPS:console.time ('frame'),阈值 < 45 降 uResolution=16。
- 内存:复杂网格 < 1M verts,避免 VMobject 无限 appendPoints。
- 兼容:Safari 降 WebGL2 to 1,polyfill KaTeX。
实际落地清单:
- 教育 demo:Sin/Cos 联动的单位圆 + 曲线(Axes.plot + Updater 线连接)。
- 数据图:BarChart + LaggedStart 逐条入场。
- 交互工具:ArgMin 优化可视化(dot 沿曲线滑至极值)。
- 导出:内置 GIF/Video(需 FFmpeg.js wasm,浏览器限 10s)。
此移植极大降低门槛,Web 开发者可即时原型数学内容,结合 WebAssembly 未来可进一步加速路径计算。
资料来源: [1] https://github.com/maloyan/manim-web (官方 Repo,包含 README 示例) [2] https://maloyan.github.io/manim-web/examples (在线 Demo)