OpenMontage 中的 ManimGL 文本渲染实战指南:Text 与 TexText 的字体、配色与排版全解析
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
导读
本文是 OpenMontage 开源视频生产系统内manimgl-best-practices技能体系中关于文本渲染的完整技术指南,系统讲解 ManimGL(3Blue1Brown 的 OpenGL 版 Manim)中Text与TexText两大文本类的使用方式:从基础创建、字体定制、逐词着色,到 LaTeX 混排、文本定位、背景描边与 VGroup 排版,并给出可直接运行的综合示例与最佳实践。读者学完后,可以独立编写出带有多字体、多颜色、多样式、公式混排的高质量 ManimGL 文本场景,并将其接入 OpenMontage 的数学 / 科学可视化视频生产流程。
ManimGL 提供了强大的文本渲染能力,核心由Text与TexText两个类承担:Text使用系统字体渲染纯文本,支持丰富的样式控制;TexText则在文本基础上叠加 LaTeX 渲染,适合文本与数学公式混排的场景。本文所有要点均可在仓库的 text 规则文档 及其姊妹规则(tex、t2c、styling、colors)中找到对应出处,同时配套了可运行的示例文件与场景模板供读者对照。
Text 类:基于系统字体的纯文本渲染
Text类使用系统已安装字体渲染文本,不依赖 LaTeX,因此渲染速度快、字体控制更直接,是标题、UI 元素、字幕等纯文本场景的首选。在 ManimGL 中所有代码都从from manimlib import *开始。
基础文本创建
最简单的用法是直接传入字符串,然后用self.add()加入场景:
from manimlib import * class TextExample(Scene): def construct(self): # Basic text text = Text("Hello ManimGL") self.add(text)仓库示例 simple_test.py 中就是用这种方式创建标题,再用Write(title)动画写入画面:
title = Text("ManimGL Test") title.to_edge(UP) self.play(Write(title)) self.wait()字体与字号定制
通过font参数指定系统字体名,通过font_size控制字号(单位为点,默认约 48):
# Specify font and size text = Text("Custom Font", font="Consolas", font_size=90)混合字体(t2f):当一段文本需要同时使用多种字体时,使用t2f(text-to-font)字典,将单词或短语映射到字体名:
# Different fonts for different parts text = Text( "Mixed fonts example", t2f={"Mixed": "Consolas", "fonts": "Arial"} )t2f是 ManimGL 文本样式家族(t2c/t2f/t2s/t2w)的一员,这组参数都以"文本子串 → 样式值"的字典形式工作,是text 规则文档强调的核心能力。
注意:
font依赖系统安装的字体,字体不存在时 ManimGL 会回退或报错。跨机器(如 CI 渲染)运行时,需要先确认目标系统已安装所用字体(详见下文"最佳实践"第 1 条)。
文本着色
对整个文本对象着色,直接传color参数;对特定单词着色,则使用t2c(text-to-color)字典:
# Color entire text text = Text("Colored Text", color=BLUE) # Color specific words text = Text( "The quick brown fox", t2c={"quick": BLUE, "brown": ORANGE, "fox": GREEN} )ManimGL 内置了丰富的颜色常量:基础色RED / GREEN / BLUE / YELLOW / CYAN / MAGENTA,灰度WHITE / GREY / BLACK,常用色ORANGE / PURPLE / PINK / BROWN / MAROON / TEAL / GOLD,以及带亮度后缀的变体(如BLUE_E最深 →BLUE_A最浅,参见 colors 规则):
# Blue variations (darkest to lightest) BLUE_E # 最深蓝 BLUE_D BLUE_C BLUE_B BLUE_A # 最浅蓝当内置常量不够用时,还可以用rgb_to_color与hex_to_rgb引入自定义颜色(colors.md):
from manimlib.utils.color import rgb_to_color, hex_to_rgb custom_color = rgb_to_color([0.5, 0.3, 0.8]) # RGB 取值 0~1 hex_color = "#FF5733" color = rgb_to_color(hex_to_rgb(hex_color)) # 十六进制色值文本样式:斜体与加粗
t2s(text-to-slant)控制斜体,t2w(text-to-weight)控制字重,同样以字典形式按词指定:
# Slant (italic) text = Text( "Italic and bold text", t2s={"Italic": ITALIC}, t2w={"bold": BOLD} )四件套组合:t2c(颜色)、t2f(字体)、t2s(倾斜)、t2w(字重)可以同时作用于同一文本对象,实现"逐词全维度定制":
# Combine color, font, slant, and weight text = Text( "Fully styled text", font="Arial", font_size=48, t2c={"styled": RED}, t2s={"styled": ITALIC}, t2w={"text": BOLD}, t2f={"text": "Consolas"} )这里styled一词被渲染为红色斜体 Arial,而text一词被渲染为加粗 Consolas——同一行文字里可以同时出现完全不同的视觉风格。t2c规则文档(t2c.md)给出了同样的组合示例:
text = Text( "Different styles and colors", t2c={"Different": RED, "colors": BLUE}, t2f={"styles": "Consolas"}, t2s={"styles": ITALIC}, t2w={"Different": BOLD} )TexText 类:文本与 LaTeX 公式的混排
TexText将 LaTeX 渲染能力与普通文本结合,适用于"叙述文字中内嵌数学表达式"的场景。它继承自 LaTeX 渲染管线,因此需要系统具备可用的 LaTeX 发行版(如 TeX Live / MacTeX)。
基础 TexText 用法
# Text with LaTeX support text = TexText("The integral $\\int_0^1 x^2 dx$ equals $\\frac{1}{3}$") # With font size text = TexText("Hello World", font_size=72)数学片段用$...$包裹,ManimGL 会将其作为数学模式渲染。在 Python 源码中字符串里的反斜杠需要写成\\,或者更推荐用大写R原始字符串避免转义问题(tex 规则):
sentence = TexText( "The area is ", R"$\pi r^2$", ".", t2c={R"$\pi r^2$": YELLOW} )isolate:拆解公式片段单独控制
isolate参数会把指定的子串拆分为独立的 submobject,之后就能用set_color_by_tex对每个片段单独着色,或对某个片段做独立动画:
# Isolate parts for coloring text = TexText( "Einstein's $E = mc^2$", isolate=["E", "m", "c"] ) text.set_color_by_tex("E", BLUE) text.set_color_by_tex("m", GREEN) text.set_color_by_tex("c", YELLOW)set_color_by_tex是创建后按 LaTeX 子串着色的常用方法,t2c 规则中还有更完整的演示:
formula = Tex(R"f(x) = x^2 + 2x + 1") formula.set_color_by_tex("x", BLUE) formula.set_color_by_tex("f", GREEN) formula.set_color_by_tex("1", YELLOW)isolate还可以与t2c组合使用,先拆解再着色,控制粒度更细(t2c.md):
equation = Tex( R"a^2 + b^2 = c^2", isolate=["a", "b", "c", "^2"], t2c={ "a": RED, "b": GREEN, "c": BLUE, "^2": YELLOW } )Text、TexText 与 Tex:三类文本对象的选择
三者的定位截然不同,仓库 tex 规则 与 text 规则 均给出了对照:
| 类 | 渲染方式 | 适用场景 |
|---|---|---|
Text | 系统字体,无 LaTeX | 纯文本、标题、UI 元素,字体控制最强 |
TexText | LaTeX,支持内嵌$...$ | 叙述文字与行内数学混排 |
Tex | 纯 LaTeX 数学模式 | 独立的数学表达式 |
# Use Text for pure text with custom fonts title = Text("Machine Learning", font="Helvetica", font_size=60) # Use TexText when mixing text and inline math description = TexText("The function $f(x) = x^2$ is convex") # Use Tex for pure mathematical expressions formula = Tex(R"\sum_{i=1}^n i = \frac{n(n+1)}{2}")需要注意 ManimGL 与 Manim 社区版(ManimCE)的差异:ManimGL 使用Tex(而非MathTex),LaTeX 字符串建议统一使用大写R原始字符串(tex.md):
# ManimGL - use Tex with capital R raw strings formula = Tex(R"\int_0^1 x^2 \, dx = \frac{1}{3}") # NOT like ManimCE: # formula = MathTex(r"\int...") # Wrong for ManimGL常用 LaTeX 符号速查
text 规则 整理了高频符号,写公式时可直接取用:
# Greek letters Tex(R"\alpha, \beta, \gamma, \delta, \theta, \phi, \pi") # Operators Tex(R"\sum, \prod, \int, \oint, \partial") # Relations Tex(R"\leq, \geq, \neq, \approx, \equiv") # Sets Tex(R"\in, \subset, \cup, \cap, \emptyset") # Arrows Tex(R"\rightarrow, \leftarrow, \Rightarrow, \Leftrightarrow") # Fractions Tex(R"\frac{a}{b}, \dfrac{a}{b}") # Roots Tex(R"\sqrt{x}, \sqrt[3]{x}") # Matrices Tex(R"\begin{pmatrix} a & b \\ c & d \end{pmatrix}")多行对齐公式则用\begin{align*}环境(tex.md):
equations = Tex(R""" \begin{align*} f(x) &= x^2 + 2x + 1 \\ &= (x + 1)^2 \end{align*} """)文本定位与布局
ManimGL 的场景画布围绕self.frame(相机视框)组织,文本定位主要依赖to_edge、next_to、arrange、set_width等 Mobject 布局方法。
基本定位
# Basic positioning text = Text("Top") text.to_edge(UP)多文本排列
VGroup将多个文本聚合,arrange按方向与间距自动排版:
# Arrange multiple texts title = Text("Title") subtitle = Text("Subtitle", font_size=36) VGroup(title, subtitle).arrange(DOWN, buff=0.5)宽度约束
长文本用set_width约束宽度以适配画布(FRAME_WIDTH - 1表示留出 1 个单位的安全边距):
# Set width text = Text("Long text that needs to fit") text.set_width(FRAME_WIDTH - 1)next_to用于将文本相对其他对象定位,是完整示例中常用的编排手段:
desc.next_to(title, DOWN, buff=0.5) math_desc.next_to(desc, DOWN, buff=1)文本背景与可读性增强
当文本叠加在复杂图形、图像或高饱和背景上时,需要增强对比度,ManimGL 提供两种方案。
set_backstroke:轮廓描边
set_backstroke在文本笔画后绘制一层描边(类似描边描影),宽度单位为像素:
# Set backstroke for readability text = Text("With Background", font_size=60) text.set_backstroke(BLACK, width=5)styling 规则 给出了在复杂背景上的完整演示:先生成 20 个随机圆叠加成背景,再放置带width=10黑色描边的白色大号文本,即可保证清晰可读:
background = VGroup(*[ Circle(radius=2 * np.random.random(), color=random_color()) for _ in range(20) ]) background.set_opacity(0.3) self.add(background) text = Text("Clear and Readable", font_size=72, color=WHITE) text.set_backstroke(BLACK, width=10) self.add(text)提示:
set_backstroke不仅适用于Text,也适用于Tex/TexText公式(tex.md),例如label = Tex(R"f(x)"); label.set_backstroke(BLACK, 5)。
BackgroundRectangle:半透明背景板
如果需要更重的背景衬托,可以手动创建BackgroundRectangle并叠放在文本下层。注意在 ManimGL 中需要从manimlib.mobject.svg.tex_mobject导入:
# Background rectangle (manually) from manimlib.mobject.svg.tex_mobject import BackgroundRectangle text = Text("Text") bg = BackgroundRectangle(text, color=BLACK, fill_opacity=0.8) self.add(bg, text)BackgroundRectangle会自动贴合文本的包围盒,fill_opacity=0.8的半透明黑底既能压住背景噪声,又不完全遮挡下层图形。
VGroup:文本排版的组织单元
多个文本行用VGroup聚合后,可以一次性完成对齐、间距与整体定位:
# Group multiple text objects line1 = Text("First line") line2 = Text("Second line") line3 = Text("Third line") paragraph = VGroup(line1, line2, line3) paragraph.arrange(DOWN, aligned_edge=LEFT, buff=0.3) paragraph.to_edge(LEFT)aligned_edge=LEFT让所有行左对齐,buff=0.3控制行间距,to_edge(LEFT)将整个段落贴到画布左缘。模板 math_scene.py 中的方程组就是用同样的模式组织的:
equations = VGroup( Tex(R"2x + 3y = 7"), Tex(R"x - y = 1"), ) equations.arrange(DOWN, aligned_edge=LEFT, buff=0.5) equations.next_to(title, DOWN, buff=1)综合示例:一镜到底的文本场景
text 规则 给出了一个综合示例,将字体、颜色、样式、定位与动画完整串联:
class ComprehensiveTextExample(Scene): def construct(self): # Title with custom font title = Text( "Text Rendering in ManimGL", font="Arial", font_size=72, color=BLUE ) title.to_edge(UP) # Description with mixed styling desc = Text( "Mix different fonts, colors, and styles", font="Helvetica", font_size=36, t2c={"fonts": RED, "colors": GREEN, "styles": YELLOW}, t2w={"Mix": BOLD} ) desc.next_to(title, DOWN, buff=0.5) # Mathematical description using TexText math_desc = TexText( "For equations like $E = mc^2$, use Tex or TexText", font_size=30 ) math_desc.next_to(desc, DOWN, buff=1) # Add all with animations self.play(Write(title)) self.play(FadeIn(desc, shift=DOWN)) self.play(Write(math_desc)) self.wait()配合动画:标题用Write逐字书写,描述行用FadeIn(shift=DOWN)从下淡入,公式说明用Write写出。渲染该场景的命令为:
manimgl text_scene.py ComprehensiveTextExample -w最佳实践清单
text 规则 总结了六条核心实践,结合仓库其他规则补充细节如下:
- 确保字体已安装:
Text依赖系统字体,跨环境(容器、CI)渲染前务必确认目标系统包含所用字体; - UI 元素用
Text:需要精确控制外观(字体、字重、间距)的标题、按钮、标签等一律使用Text; - 混排内容用
TexText:叙述文字中需要内嵌公式时使用TexText,纯公式则用Tex; - 复杂背景加 backstroke:文本叠加在图形之上时用
set_backstroke(黑色、宽度 5~10)保证可读性; - 用
VGroup组织布局:把相关文本聚合为组,统一arrange对齐与定位; t2c/t2f/t2s/t2w逐词定制:需要同段文字呈现不同风格时使用这组字典参数。
颜色层面建议(colors.md):优先使用命名常量保证可读性;为整个项目定义统一配色方案(如COLOR_SCHEME字典);保证文本与背景的对比度;用t2c给公式重点上色但不滥用,颜色过多会分散注意力。
常见模式速查
带背景的文本标签
封装一个"黑描边白字标签"工厂函数,适合图表坐标标签、图例、提示框:
def create_label(text_str, color=WHITE): label = Text(text_str, font_size=40, color=color) label.set_backstroke(BLACK, width=5) return label多行文本对齐
lines = [Text(line) for line in [ "Line 1", "Longer line 2", "Line 3" ]] paragraph = VGroup(*lines) paragraph.arrange(DOWN, aligned_edge=LEFT, buff=0.2)高亮关键词
sentence = Text( "This word is highlighted", t2c={"highlighted": YELLOW}, t2w={"highlighted": BOLD} )整段渐变色文本
利用 submobject 渐变方法给整行文字铺上渐变色(colors.md):
text = Text("Gradient Text") text.set_submobject_colors_by_gradient(BLUE, GREEN, YELLOW)渲染与调试:把文本场景跑起来
ManimGL 使用manimgl命令渲染(注意不是 ManimCE 的manim),完整 CLI 参考见 cli 规则。
常用渲染命令
# 低质量快速测试(开发期首选) manimgl scene.py MyScene -l # 高质量 1080p 渲染并写入文件 manimgl scene.py MyScene -h -w # 只查看最终帧 manimgl scene.py MyScene -s # 输出 GIF manimgl scene.py MyScene --format gif -o交互式开发(-se)
-se(skip and embed)是 ManimGL 的杀手级特性,可在指定行号进入 IPython 交互 shell,逐行调试文本布局与动画:
manimgl scene.py MyScene -se 15进入交互 shell 后可以直接调用play / add / remove / wait等缩写命令,配合checkpoint_paste()将剪贴板代码回放(参见 SKILL.md)。
常见故障排查
- LaTeX 无法渲染:检查 LaTeX 发行版是否安装、是否缺少宏包,尝试更简单的表达式,检查输出目录中的中间
.tex文件定位问题(tex.md); - t2c 未生效:确认子串与 LaTeX 源串完全一致(注意空格),必要时先用
isolate=拆解(t2c.md):# 反例:空格不匹配导致失效 wrong = Tex(R"a+b", t2c={"a + b": RED}) # 正例:按实际子串着色 right = Tex(R"a + b", t2c={"a": RED, "b": BLUE}) - 字体不生效:确认字体在系统中存在,且
font参数使用系统字体名。
在 OpenMontage 项目中的定位
本文所在的 manimgl-best-practices 是 OpenMontage 技能体系中面向"3Blue1Brown 风格数学/科学可视化"的实现级技能,与 manim-composer(负责把模糊创意转化为分镜脚本)形成"先规划、后实现"的分工:manim-composer产出scenes.md分镜,manimgl-best-practices负责用 ManimGL 代码落地,而本 text 规则 正是其中处理"字幕、标题、公式标注"的关键一环。配套的技能资源还包括 75 个可运行示例、4 个场景模板以及 18 个按主题拆分的规则文件(text、tex、t2c、styling、colors、cli等),可组合出完整的数学可视化视频生产链路。
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考