ManimCE文档及源码教程笔记--(五)manim渲染文本和公式
manim渲染文本和公式
有两种不同的方式可以在视频中渲染文本:
1、使用Pango(text_mobject
)
2、使用乳胶(tex_mobject
)
如果你想呈现简单的文本,你应该使用文本Text
或MarkupText
,或者它的派生词,比如段落Paragraph
。有关更多信息,请参阅不含LaTeX的文本。
当你需要数学排版时,应该使用LaTeX。有关更多信息,请参阅带有LaTeX的文本。
不含LaTeX的文本
向动画中添加文本的最简单方法是使用text
类。它使用Pango库来呈现文本。使用Pango,您还可以呈现非英语字母,如你好 或こんにちは 或안녕하세요 或or مرحبا بالعالم。
这是一个简单的Hello World动画。
示例:HelloWorld
from manim import *
class HelloWorld(Scene):
def construct(self):
text = Text("Hello world", font_size=144)
self.add(text)
参考:Text
您还可以使用MarkupText
,它允许使用PangoMarkup(有关详细信息,请参阅MarkupText
文档)来呈现文本。例如:
示例:SingleLineColor
from manim import *
class SingleLineColor(Scene):
def construct(self):
text = MarkupText(
f'all in red <span fgcolor="{YELLOW}">except this</span>', color=RED
)
self.add(text)
参考:MarkupText
使用文本Text
本节介绍文本Text
的属性以及如何在动画中使用文本。
使用字体
您可以使用字体设置不同的字体font
。
笔记
使用的字体必须安装在您的系统中,Pango应该知道这一点。您可以使用manimpango.list_fonts()
获得字体列表。>> import manimpango >> manimpango.list_fonts() [...]
示例:FontsExample
from manim import *
class FontsExample(Scene):
def construct(self):
ft = Text("Noto Sans", font="Noto Sans")
self.add(ft)
设置倾斜和重量
倾斜是文本的样式,可以是正常(默认)NORMAL
、倾斜ITALIC
或倾斜OBLIQUE
。通常,对于许多字体,斜体和斜体看起来都很相似,但斜体使用罗马风格,而斜体使用斜体风格。
权重指定字体的粗体。您可以在manimpango.Weight
中看到权重列表。
示例:SlantsExample
from manim import *
class SlantsExample(Scene):
def construct(self):
a = Text("Italic", slant=ITALIC)
self.add(a)
示例:DifferentWeight
from manim import *
class DifferentWeight(Scene):
def construct(self):
import manimpango
g = VGroup()
weight_list = dict(
sorted(
{
weight: manimpango.Weight(weight).value
for weight in manimpango.Weight
}.items(),
key=lambda x: x[1],
)
)
for weight in weight_list:
g += Text(weight.name, weight=weight.name, font="Open Sans")
self.add(g.arrange(DOWN).scale(0.5))
使用颜色
可以使用颜色设置文本的颜色color
:
示例:SimpleColor
from manim import *
class SimpleColor(Scene):
def construct(self):
col = Text("RED COLOR", color=RED)
self.add(col)
可以使用t2c之类的实用程序为特定字符着色。如果文本包含连字(如迭代文本中所述),这可能会有问题。
t2c
接受两种类型的词典,
示例:Textt2cExample
from manim import *
class Textt2cExample(Scene):
def construct(self):
t2cindices = Text('Hello', t2c={'[1:-1]': BLUE}).move_to(LEFT)
t2cwords = Text('World',t2c={'rl':RED}).next_to(t2cindices, RIGHT)
self.add(t2cindices, t2cwords)
如果您想避免使用颜色时出现问题(由于连字),请考虑使用MarkupText
。
使用渐变
可以使用渐变添加渐变gradient
。该值必须是任意长度的iterable:
示例:GradientExample
from manim import *
class GradientExample(Scene):
def construct(self):
t = Text("Hello", gradient=(RED, BLUE, GREEN), font_size=96)
self.add(t)
您还可以使用t2g
表示具有文本特定字符的渐变。它与颜色界面的语法相似:
示例:t2gExample
from manim import *
class t2gExample(Scene):
def construct(self):
t2gindices = Text(
'Hello',
t2g={
'[1:-1]': (RED,GREEN),
},
).move_to(LEFT)
t2gwords = Text(
'World',
t2g={
'World':(RED,BLUE),
},
).next_to(t2gindices, RIGHT)
self.add(t2gindices, t2gwords)
设置行距
可以使用line_spacing
设置行距:
示例:LineSpacing
from manim import *
class LineSpacing(Scene):
def construct(self):
a = Text("Hello\nWorld", line_spacing=1)
b = Text("Hello\nWorld", line_spacing=4)
self.add(Group(a,b).arrange(LEFT, buff=5))
禁用连字
通过禁用连字,您将获得字符和子对象之间的一对一映射。这解决了文本着色的问题。
警告
请注意,对严重依赖连字(阿拉伯语文本)的文本使用此方法可能会产生意外的结果。
您可以通过将disable_ligatures
连字传递给文本Text
来禁用连字。例如:
示例:禁用连字
from manim import *
class DisableLigature(Scene):
def construct(self):
li = Text("fl ligature",font_size=96)
nli = Text("fl ligature", disable_ligatures=True, font_size=96)
self.add(Group(li, nli).arrange(DOWN, buff=.8))
迭代文本
文本对象的行为类似于VGroups
。因此,可以对文本进行切片和索引。
例如,可以通过迭代将每个字母设置为不同的颜色。
示例:IterateColor
from manim import *
class IterateColor(Scene):
def construct(self):
text = Text("Colors", font_size=96)
for letter in text:
letter.set_color(random_bright_color())
self.add(text)
警告
请注意,这里的连字可能会导致问题。如果需要字符到子对象的一对一映射,则应将disable\u
ligatures参数传递给文本Text
。请参见禁用连字。
使用MarkupText
MarkupText类似于文本Text
,它们之间的唯一区别是它接受并处理PangoMarkup(类似于html),而不仅仅是呈现纯文本。
有关PangoMarkup的更多详细信息和更多参考资料,请参阅MarkupText
的文档。
示例:MarkupTest
from manim import *
class MarkupTest(Scene):
def construct(self):
text = MarkupText(
f'<span underline="double" underline_color="green">double green underline</span> in red text<span fgcolor="{YELLOW}"> except this</span>',
color=RED,
font_size=34
)
self.add(text)
带LaTeX的文字
正如您可以使用文本Text
向视频中添加文本一样,您也可以使用Tex
插入LaTeX。
例如
示例:HelloLaTeX
from manim import *
class HelloLaTeX(Scene):
def construct(self):
tex = Tex(r"\LaTeX", font_size=144)
self.add(tex)
笔记
请注意,我们使用的是原始字符串(r'...'
)而不是常规字符串('...'
)。这是因为TeX代码使用了许多特殊字符,例如\在常规python字符串中具有特殊含义。另一种方法是写\\
以避开反斜杠:Tex('\\ LaTeX')
。
使用MathTex
默认情况下,传递给MathTex
的所有内容都处于数学模式。更准确地说,MathTex
是在align*
环境中处理的。使用Tex
可以实现类似的效果,方法是使用$
符号来封装公式:$\xrightarrow{x^6y^8}$
:
示例:MathTeXDemo
from manim import *
class MathTeXDemo(Scene):
def construct(self):
rtarrow0 = MathTex(r"\xrightarrow{x^6y^8}", font_size=96)
rtarrow1 = Tex(r"$\xrightarrow{x^6y^8}$", font_size=96)
self.add(VGroup(rtarrow0, rtarrow1).arrange(DOWN))
LaTeX命令和关键字参数,LaTeX commands and keyword arguments
我们可以在AMS数学软件包中使用任何标准的LaTeX命令。例如mathtt
数学文本类型或looparrowright
箭头。
示例:AMSLaTeX
from manim import *
class AMSLaTeX(Scene):
def construct(self):
tex = Tex(r'$\mathtt{H} \looparrowright$ \LaTeX', font_size=144)
self.add(tex)
在Manim方面,Tex
类还接受属性来更改输出的外观。这与Text
类非常相似。例如,color
关键字更改TeX mobject的颜色。
示例:LaTeXAttributes
from manim import *
class LaTeXAttributes(Scene):
def construct(self):
tex = Tex(r'Hello \LaTeX', color=BLUE, font_size=144)
self.add(tex)
额外LaTeX 包装
有些命令需要将特殊包加载到TeX模板中。例如,要使用mathscr
脚本,我们需要添加`mathrsfs包。由于默认情况下该包没有加载到Manim的tex模板中,因此我们必须手动添加它。
示例:AddPackageLatex
from manim import *
class AddPackageLatex(Scene):
def construct(self):
myTemplate = TexTemplate()
myTemplate.add_to_preamble(r"\usepackage{mathrsfs}")
tex = Tex(
r"$\mathscr{H} \rightarrow \mathbb{H}$}",
tex_template=myTemplate,
font_size=144,
)
self.add(tex)
子字符串和零件,Substrings and parts
TeX-mobject可以接受多个字符串作为参数。之后,您可以通过索引(如tex[1]
)或选择tex代码的部分来引用各个部分。在本例中,我们使用set_color_by_tex()
设置大星星\bigstar
的颜色:
示例:LaTeXSubstrings
from manim import *
class LaTeXSubstrings(Scene):
def construct(self):
tex = Tex('Hello', r'$\bigstar$', r'\LaTeX', font_size=144)
tex.set_color_by_tex('igsta', RED)
self.add(tex)
请注意,set_color_by_tex()
为包含tex的整个子字符串着色,而不仅仅是特定符号或tex表达式。考虑以下示例:
示例:IncorrectlatexSubstringColor
from manim import *
class IncorrectLaTeXSubstringColoring(Scene):
def construct(self):
equation = MathTex(
r"e^x = x^0 + x^1 + \frac{1}{2} x^2 + \frac{1}{6} x^3 + \cdots + \frac{1}{n!} x^n + \cdots"
)
equation.set_color_by_tex("x", YELLOW)
self.add(equation)
如你所见,这会将整个等式涂成黄色,这与预期相反。要仅将x
涂成黄色,我们必须执行以下操作:
示例:CorrectLatexSubstringColor
from manim import *
class CorrectLaTeXSubstringColoring(Scene):
def construct(self):
equation = MathTex(
r"e^x = x^0 + x^1 + \frac{1}{2} x^2 + \frac{1}{6} x^3 + \cdots + \frac{1}{n!} x^n + \cdots",
substrings_to_isolate="x"
)
equation.set_color_by_tex("x", YELLOW)
self.add(equation)
通过将substring_to_isolate
设置为x
,我们自动将MathTex
分割成子字符串,并将x
分量分割成单个子字符串。只有这样,才能使用set_color_by_tex()
来实现所需的结果。
注意,Manim还支持一种自定义语法,允许轻松地将TeX字符串拆分为子字符串:只需用双大括号将公式中要隔离的部分括起来。在字符串MathTex(r“{a^2}}+{b^2}={c^2}”)
中,呈现的mobject将由子字符串a^2
、+
、b^2
、=
、和c^2
组成。这使得使用TransformMatchingTex可以轻松编写类似文本片段之间的转换。
使用index_labels
标签处理复杂字符串
有时,您可能会使用非常复杂的MathTex
mobject,这使得您很难使用其单个组件。这就是调试函数index_labels()
非常有用的地方。
该方法显示了mobject子mobject的索引,允许您轻松找到要更改的mobject组件。
示例:IndexLabelsMathTex
from manim import *
class IndexLabelsMathTex(Scene):
def construct(self):
text = MathTex(r"\binom{2n}{n+2}", font_size=96)
# index the first (and only) term of the MathTex mob
self.add(index_labels(text[0]))
text[0][1:3].set_color(YELLOW)
text[0][3:6].set_color(RED)
self.add(text)
LaTeX数学字体-模板库
当排版数学公式时,在LaTeX中更改字体比常规文本更复杂。它需要更改用于编译TeX的模板。Manim附带了一组TexFontTemplates
供您使用。这些模板都将在数学模式下工作:
示例:LaTeXMathFonts
from manim import *
class LaTeXMathFonts(Scene):
def construct(self):
tex = Tex(
r"$x^2 + y^2 = z^2$",
tex_template=TexFontTemplates.french_cursive,
font_size=144,
)
self.add(tex)
Manim还有一个TexTemplateLibrary
,其中包含3Blue1Brown使用的TeX模板。一个例子是用于排版中文脚本的ctex模板。为此,必须在系统上安装ctex LaTeX软件包。此外,如果您只是排版文本,您可能根本不需要Tex
,应该使用Text
。
示例:LaTeXTemplateLibrary
from manim import *
class LaTeXTemplateLibrary(Scene):
def construct(self):
tex = Tex('Hello 你好 \\LaTeX', tex_template=TexTemplateLibrary.ctex, font_size=144)
self.add(tex)
对齐公式
MathTex
mobject是在LaTeX align*
环境中排版的。这意味着您可以在排版多行公式时使用对齐字符(&A):
示例:LaTeXAlignEnvironment
from manim import *
class LaTeXAlignEnvironment(Scene):
def construct(self):
tex = MathTex(r'f(x) &= 3 + 2 + 1\\ &= 5 + 1 \\ &= 6', font_size=96)
self.add(tex)