跳转至

数学

影片代码
import manimgx as m


class MathHero(m.Scene):
    def construct(self) -> None:
        before = m.MathTex("a^2", "+", "b^2", "=", "c^2", font_size=96)
        after = m.MathTex("a^2", "=", "c^2", "-", "b^2", font_size=96)
        before[2].set_color(m.YELLOW)
        after[4].set_color(m.YELLOW)
        self.play(m.Write(before))
        self.play(m.TransformMatchingTex(before, after))
        self.wait()

MathTex 排版以 LaTeX 书写的公式:分数、根号、求和与积分、矩阵、 cases、希腊字母。请用原始字符串 r"..." 书写,以便 Python 保留其反斜杠。LaTeX 宏包和 \def 不起作用;ManimGX 不认识的命令会以其名称中止场景。

为 MathTex 提供多个字符串,每个字符串都是公式的一个组成部分,可单独着色、移动或制作 动画:MathTex("a^2", "+", "b^2")[2] 是 b²。在两个公式中以相同方式书写的部分,可通过 TransformMatchingTex 相互变换。

Tex 是包含公式的文本,公式位于 $ 符号之间。如果你熟悉 Typst,可直接 书写:Typst 接受 Typst 标记,MathTypst 接受以 Typst 数学语法书写的公式。

MathTex

代码
import manimgx as m


class MathTexExample(m.Scene):
    def construct(self) -> None:
        formula = m.MathTex("a^2", "+", "b^2", "=", "c^2", font_size=144)
        formula[0].set_color(m.BLUE)
        formula[2].set_color(m.GREEN)
        formula[4].set_color(m.YELLOW)
        self.play(m.Write(formula))
MathTexLatexExample
代码
import manimgx as m


class MathTexLatexExample(m.Scene):
    def construct(self) -> None:
        limit = r"\lim_{n \to \infty} \left(1 + \frac{1}{n}\right)^n = e"
        formulas = m.VGroup(
            m.MathTex(r"\int_0^1 x^2 \, dx = \frac{1}{3}"),
            m.MathTex(r"\begin{pmatrix} a & b \\ c & d \end{pmatrix}"),
            m.MathTex(limit),
            m.MathTex(r"\sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}"),
        )
        self.add(formulas.arrange_in_grid(rows=2, buff=1).scale(1.3))

LaTeX 数学,在引擎中排版,每个字符串为一个部分:MathTex("a^2", "+", "b^2")[2] 为 \(b^2\),可着色、移动或与另一公式匹配。

无需 LaTeX 安装:LaTeX 转换为 Typst(由 mitex,引擎的一部分)并以 展示样式排版,使用 New Computer Modern Math,未加样式时为白色。大部分 LaTeX 数学可转换:分数、根号、求和与积分、 矩阵(pmatrix、bmatrix、array)、cases 和 aligned、重音、\mathbb 和其他字母表、\text、\left 和 \right、\color、\newcommand。 包不可——\usepackage 及其命令(如 \ce 或 \SI)——\def 也不可: mitex 不知的命令引发 TypstError。

各字符串为一个公式,由 arg_separator 连接并整体排版,因此分割 公式不会移动任何字形。每个字符串为一个部分,即其添加字形的 MathTexPart,双花括号在字符串内设置独立 部分:MathTex("{{a^2}} + {{b^2}} = {{c^2}}") 有下面第一个示例的五个 部分。独立存在的字符串(其花括号、环境和 \left…\right 在其中闭合) 恰好持有其字形。其余,如分数的横线或 "^2" 等片段的字形,归入 其周围独立字符串之间的第一个片段:在 MathTex(r"\frac{", "a", "}{", "b", "}") 中横线属于闭合的 "}",TeX 在此绘制它,而在 MathTex(r"e^{i", r"\pi}") 中,在项内分割,每个字形 属于第一个部分。无法区分部分的公式引发 ValueError。

substrings_to_isolate 和 tex_to_color_map 进一步分割字符串; set_color_by_tex 和 get_part_by_tex 按其 LaTeX 查找部分, TransformMatchingTex 将每个部分移至 另一公式中以相同方式书写的部分。作为文本读取(见 Tex), 字符串以同样方式成为一个文本,含空格。

m.MathTex(*tex_strings, arg_separator=' ', substrings_to_isolate=None, tex_to_color_map=None, tex_environment='align*', **kwargs)
*tex_strings

公式,以 LaTeX 表示:每个字符串为一个部分(数字写为 字符串),字符串内的每个 {{…}} 也为一个部分。

arg_separator

将字符串连接为 tex_string 的分隔符,即它们排版的 公式(或文本)。

substrings_to_isolate

使其各自成为部分的子串:每个字符串在每个 子串的每次出现处分割。

tex_to_color_map

每个子串的颜色,子串成为独立部分 并着色。

tex_environment

字符串的读取方式:名称含 "align"(默认 "align*")为数学;任何其他或 None 为 LaTeX 文本,数学 在 $ 符号之间。

font_size

文本的大小:一个 em 为 font_size / 96 场景单位,默认时为 0.5, 48(Text 按其大写字母确定大小:48 时高 0.449 单位)。

typst_preamble

在文档之前设置的 Typst 代码:#set 和 #show 规则、#let 定义、导入(默认为 "")。

font_paths

字体文件(.ttf、.otf、.ttc、.otc)的目录,在 manimgx 附带的字体之前 连同其子目录一起搜索;指向文件的路径不添加任何内容 (默认为 None)。

should_center

mobject 是否居中于原点(默认为 True)。

height

将 mobject 缩放至的高度,以场景单位计,而非按 font_size 确定大小 (默认为 None)。

width

将 mobject 缩放至的宽度,以场景单位计,而非按 font_size 确定大小; 若同时给出 height,则宽度最后设置(默认为 None)。

package_path

Typst 包导入的目录,将包存放为 namespace/name/version 目录: #import "@preview/name:1.0.0" 读取 preview/name/1.0.0(默认为 None: 除 mitex 外无任何包,mitex 由 manimgx 的引擎持有)。不下载任何内容。

background_stroke_color

绘制于填充之后的轮廓颜色(默认黑色)。

background_stroke_opacity

轮廓的不透明度,取值从 0 到 1(默认 1)。

background_stroke_width

轮廓的宽度,以场景单位的百分之一计(默认 0:无)。

sheen_factor

颜色朝 sheen_direction 变亮的程度,取值从 -1 到 1(默认 0); 负值变暗。

sheen_direction

颜色变亮的方向(默认 UL)。

joint_type

描边在路径转折处的连接方式:圆角、斜切或斜接,按二维场景的绘制方式 (参见 LineJointType;默认 AUTO:斜接)。

cap_style

描边在其显示的每一端的端点样式(开放路径的端点、虚线的端点):圆头、平头 或方头,按二维场景的绘制方式(参见 CapStyleType;默认 AUTO:平头)。

shade_in_3d

三维场景的光是否对该 mobject 着色。

material

其表面在三维场景中如何反射场景的光(参见 Material);None:Manim 的着色(默认)。

name

mobject 的名称;未给出时为其类名。

z_index

其在绘制顺序中的位置:索引较高者绘制于较低者之上 (默认 0)。

target

MoveToTarget 将 mobject 移动至的状态。

还接受 样式关键字。

源码

manimgx\mobjects\text.py

@prototype
def __init__(
    self,
    *tex_strings: str | float,
    arg_separator: str = " ",
    substrings_to_isolate: Iterable[str] | None = None,
    tex_to_color_map: Mapping[str, ParsableManimColor] | None = None,
    tex_environment: str | None = "align*",
    **kwargs: Unpack[TypstOptions],
) -> None:
    self.tex_to_color_map = dict(tex_to_color_map or {})
    isolate = list(substrings_to_isolate or []) + list(self.tex_to_color_map)
    math = bool(tex_environment and "align" in tex_environment)
    strings = _isolate_braces([str(s) for s in tex_strings], math)
    self.tex_strings = (
        [p for s in strings for p in _split(s, isolate, math)]
        if isolate
        else strings
    )
    """各字符串,每个为一个部分:参数,在 `{{…}}` 处和孤立子串
    周围分割。"""
    self.arg_separator = arg_separator
    self.tex_string = arg_separator.join(self.tex_strings)
    """整个公式或文本的 LaTeX:字符串由
    `arg_separator` 连接。"""
    self.tex_environment = tex_environment
    preamble = f"{_IMPORT}{_MANIMGRP}\n" if math else _IMPORT
    kwargs["typst_preamble"] = preamble + kwargs.get("typst_preamble", "")

    def layout(source: str) -> Layout:
        return typeset(
            source,
            kwargs["typst_preamble"],
            font_paths=kwargs.get("font_paths"),
            package_path=kwargs.get("package_path"),
        )

    if not math:
        body, starts, whole = self._compose(self.tex_strings, arg_separator)
        owners: dict[int, int] = {}
        if len(self.tex_strings) > 1 and starts:  # which string drew each item
            apart = ValueError(f"cannot tell these parts apart: {self.tex_strings}")
            reference = None if whole is None else layout(whole)
            try:
                drawn = layout(body)
            except TypstError as error:  # the text is fine, its parting is not
                if reference is None:
                    raise
                raise apart from error
            if reference is not None and not _same(drawn, reference):
                raise apart
            owners = self._owners(drawn, starts)
        super().__init__(body, **kwargs)
        self._regroup(owners, set(starts.values()))
    elif len(self.tex_strings) > 1:  # one formula, its parts told apart
        _, skeleton, holes = _one_formula(
            self.tex_strings, arg_separator, _engine.mitex_math
        )
        plain = typst_string(_fill(skeleton, holes))
        super().__init__(f"$ #eval({plain}, {_MITEX}) $", **kwargs)
        boxed = _fill(
            skeleton,
            {i: f'#manimgrp("p{i}", ${code}$)' for i, code in holes.items()},
        )
        self._regroup_by_twin(
            layout(
                f"$ #eval({typst_string(boxed)}, {_MITEX} + (manimgrp: manimgrp)) $"
            ),
            set(holes),
        )
    else:  # a part's box would drop to text style; keep display style
        parts = " ".join(
            f'#manimgrp("p{i}", $display(#{_math(_standalone(s))})$)'
            for i, s in enumerate(self.tex_strings)
        )
        super().__init__(f"$ {parts} $", **kwargs)
        self._regroup_by_labels()
    for tex, c in self.tex_to_color_map.items():
        self.set_color_by_tex(tex, c)

tex_strings

各字符串,每个为一个部分:参数,在 {{…}} 处和孤立子串 周围分割。

tex_string

整个公式或文本的 LaTeX:字符串由 arg_separator 连接。

get_parts_by_tex

查找 LaTeX 包含 tex 或等于 tex 的部分。

formula.get_parts_by_tex(tex, substring=True, case_sensitive=True)
tex

要查找的 LaTeX。

substring

LaTeX 包含 tex 的部分是否匹配;若否,仅 LaTeX 等于 tex 的部分。

case_sensitive

大小写是否区分。

返回 各部分本身按顺序组成的新组。

源码

manimgx\mobjects\text.py

def get_parts_by_tex(
    self, tex: str, substring: bool = True, case_sensitive: bool = True
) -> VGroup:
    """查找 LaTeX 包含 `tex` 或等于 `tex` 的部分。

    Args:
        tex: 要查找的 LaTeX。
        substring: LaTeX 包含 `tex` 的部分是否匹配;若否,仅
            LaTeX 等于 `tex` 的部分。
        case_sensitive: 大小写是否区分。

    Returns:
        各部分本身按顺序组成的新组。
    """

    def match(s: str) -> bool:
        a, b = (tex, s) if case_sensitive else (tex.lower(), s.lower())
        return a in b if substring else a == b

    return VGroup(
        *(
            m
            for m in self.submobjects
            if isinstance(m, MathTexPart) and match(m.tex_string)
        )
    )

get_part_by_tex

代码
import manimgx as m


class MathTexGetPartByTexExample(m.Scene):
    def construct(self) -> None:
        formula = m.MathTex(
            r"\sin^2\theta", "+", r"\cos^2\theta", "=", "1", font_size=120
        )
        self.add(formula)
        self.play(m.Indicate(formula.get_part_by_tex(r"\cos")))

查找首个 LaTeX 包含 tex 或等于 tex 的部分。

formula.get_part_by_tex(tex, substring=True, case_sensitive=True)
tex

要查找的 LaTeX。

substring

LaTeX 包含 tex 的部分是否匹配;若否,仅 LaTeX 等于 tex 的部分。

case_sensitive

大小写是否区分。

返回 部分本身,若无匹配则为 None。

源码

manimgx\mobjects\text.py

def get_part_by_tex(
    self, tex: str, substring: bool = True, case_sensitive: bool = True
) -> Mobject | None:
    r"""查找首个 LaTeX 包含 `tex` 或等于 `tex` 的部分。

    Args:
        tex: 要查找的 LaTeX。
        substring: LaTeX 包含 `tex` 的部分是否匹配;若否,仅
            LaTeX 等于 `tex` 的部分。
        case_sensitive: 大小写是否区分。

    Returns:
        部分本身,若无匹配则为 None。

    Examples:
        ```python
        import manimgx as m


        class MathTexGetPartByTexExample(m.Scene):
            def construct(self) -> None:
                formula = m.MathTex(
                    r"\sin^2\theta", "+", r"\cos^2\theta", "=", "1", font_size=120
                )
                self.add(formula)
                self.play(m.Indicate(formula.get_part_by_tex(r"\cos")))
        ```
    """
    parts = self.get_parts_by_tex(tex, substring, case_sensitive)
    return parts[0] if len(parts) else None

index_of_part

查找部分在公式各部分中的位置;非部分的 mobject 引发 ValueError。

formula.index_of_part(part)
part

其中一个部分。

返回 其索引,从 0 开始。

源码

manimgx\mobjects\text.py

def index_of_part(self, part: Mobject) -> int:
    """查找部分在公式各部分中的位置;非部分的 mobject
    引发 ValueError。

    Args:
        part: 其中一个部分。

    Returns:
        其索引,从 0 开始。
    """
    return self.submobjects.index(part)

set_color_by_tex

MathTexSetColorByTexExample
代码
import manimgx as m


class MathTexSetColorByTexExample(m.Scene):
    def construct(self) -> None:
        formula = m.MathTex(
            "x + y = y + x", substrings_to_isolate=["x", "y"], font_size=144
        )
        formula.set_color_by_tex("x", m.YELLOW)
        formula.set_color_by_tex("y", m.BLUE)
        self.add(formula)

为 LaTeX 包含 tex 或等于 tex 的部分着色。

formula.set_color_by_tex(tex, color, substring=True, case_sensitive=True)
tex

要查找的 LaTeX。

color

它们的颜色。

substring

LaTeX 包含 tex 的部分是否匹配;若否,仅 LaTeX 等于 tex 的部分。

case_sensitive

大小写是否区分。

源码

manimgx\mobjects\text.py

def set_color_by_tex(
    self,
    tex: str,
    color: ParsableManimColor,
    substring: bool = True,
    case_sensitive: bool = True,
) -> Self:
    """为 LaTeX 包含 `tex` 或等于 `tex` 的部分着色。

    Args:
        tex: 要查找的 LaTeX。
        color: 它们的颜色。
        substring: LaTeX 包含 `tex` 的部分是否匹配;若否,仅
            LaTeX 等于 `tex` 的部分。
        case_sensitive: 大小写是否区分。

    Examples:
        ```python
        import manimgx as m


        class MathTexSetColorByTexExample(m.Scene):
            def construct(self) -> None:
                formula = m.MathTex(
                    "x + y = y + x", substrings_to_isolate=["x", "y"], font_size=144
                )
                formula.set_color_by_tex("x", m.YELLOW)
                formula.set_color_by_tex("y", m.BLUE)
                self.add(formula)
        ```
    """
    for part in self.get_parts_by_tex(tex, substring, case_sensitive):
        part.set_color(color)
    return self

set_color_by_tex_to_color_map

按 LaTeX 为部分着色:每个条目对应 LaTeX 包含它或等于它的 部分。

formula.set_color_by_tex_to_color_map(texs_to_color_map, substring=True, case_sensitive=True)
texs_to_color_map

每段 LaTeX 的颜色,按顺序应用。

substring

LaTeX 包含该段的部分是否匹配;若否,仅 LaTeX 等于该段的部分。

case_sensitive

大小写是否区分。

源码

manimgx\mobjects\text.py

def set_color_by_tex_to_color_map(
    self,
    texs_to_color_map: Mapping[str, ParsableManimColor],
    substring: bool = True,
    case_sensitive: bool = True,
) -> Self:
    """按 LaTeX 为部分着色:每个条目对应 LaTeX 包含它或等于它的
    部分。

    Args:
        texs_to_color_map: 每段 LaTeX 的颜色,按顺序应用。
        substring: LaTeX 包含该段的部分是否匹配;若否,仅
            LaTeX 等于该段的部分。
        case_sensitive: 大小写是否区分。
    """
    for tex, color in texs_to_color_map.items():
        self.set_color_by_tex(tex, color, substring, case_sensitive)
    return self

MathTexPart

MathTex 的一个部分:其某个字符串为公式 添加的字形,作为知道该字符串的组。

m.MathTexPart(tex_string, *members)
tex_string

排版所用的 LaTeX。

*members

其字形。

源码

manimgx\mobjects\text.py

def __init__(self, tex_string: str, *members: Mobject) -> None:
    super().__init__(*members)
    self.tex_string = tex_string
    """该部分排版所用的 LaTeX。"""

tex_string

该部分排版所用的 LaTeX。

Tex

代码
import manimgx as m


class TexExample(m.Scene):
    def construct(self) -> None:
        text = m.Tex(
            r"\textbf{Bold}, \emph{emphasized},\\ and math: $e^{i\pi} = -1$",
            font_size=96,
        )
        self.play(m.Write(text))

LaTeX 文本,在引擎中排版并居中,每个字符串为一个部分:数学在 $ 符号之间。

它是将其字符串作为 LaTeX 文本读取的 MathTex:粗体 (\textbf)、斜体(\emph、\textit)、换行(\\)和行内数学 可转换。文本以 New Computer Modern 排版,如同 LaTeX 所设,数学以 New Computer Modern Math 排版;未加样式时为白色。各字符串为由 arg_separator(默认为空)连接的一个文本并整体排版,如同 MathTex 的 公式:Tex("Fade", "In") 读取 "FadeIn",分割文本不会移动任何 字形。其部分如同公式一样区分;两个字符串共享的连字 属于第一个。

m.Tex(*tex_strings, **kwargs)
*tex_strings

文本,以 LaTeX 表示:每个字符串为一个部分。

arg_separator

将字符串连接为 tex_string 的分隔符,即 MathTex 排版的公式, 或 Tex 排版的文本(默认 " ";Tex 为 "")。

substrings_to_isolate

使其各自成为部分的子串:每个字符串在每个子串的每次出现处 分割(默认 None)。

tex_to_color_map

每个子串的颜色,子串如 substrings_to_isolate 般成为独立部分 并着色(默认 None)。

tex_environment

字符串的读取方式:名称含 "align"("align*",MathTex 的 默认)为数学;任何其他("center",Tex 的默认,也使行 居中),或 None 为 LaTeX 文本,数学在 $ 符号之间。

font_size

文本的大小:一个 em 为 font_size / 96 场景单位,默认时为 0.5, 48(Text 按其大写字母确定大小:48 时高 0.449 单位)。

typst_preamble

在文档之前设置的 Typst 代码:#set 和 #show 规则、#let 定义、导入(默认为 "")。

font_paths

字体文件(.ttf、.otf、.ttc、.otc)的目录,在 manimgx 附带的字体之前 连同其子目录一起搜索;指向文件的路径不添加任何内容 (默认为 None)。

should_center

mobject 是否居中于原点(默认为 True)。

height

将 mobject 缩放至的高度,以场景单位计,而非按 font_size 确定大小 (默认为 None)。

width

将 mobject 缩放至的宽度,以场景单位计,而非按 font_size 确定大小; 若同时给出 height,则宽度最后设置(默认为 None)。

package_path

Typst 包导入的目录,将包存放为 namespace/name/version 目录: #import "@preview/name:1.0.0" 读取 preview/name/1.0.0(默认为 None: 除 mitex 外无任何包,mitex 由 manimgx 的引擎持有)。不下载任何内容。

background_stroke_color

绘制于填充之后的轮廓颜色(默认黑色)。

background_stroke_opacity

轮廓的不透明度,取值从 0 到 1(默认 1)。

background_stroke_width

轮廓的宽度,以场景单位的百分之一计(默认 0:无)。

sheen_factor

颜色朝 sheen_direction 变亮的程度,取值从 -1 到 1(默认 0); 负值变暗。

sheen_direction

颜色变亮的方向(默认 UL)。

joint_type

描边在路径转折处的连接方式:圆角、斜切或斜接,按二维场景的绘制方式 (参见 LineJointType;默认 AUTO:斜接)。

cap_style

描边在其显示的每一端的端点样式(开放路径的端点、虚线的端点):圆头、平头 或方头,按二维场景的绘制方式(参见 CapStyleType;默认 AUTO:平头)。

shade_in_3d

三维场景的光是否对该 mobject 着色。

material

其表面在三维场景中如何反射场景的光(参见 Material);None:Manim 的着色(默认)。

name

mobject 的名称;未给出时为其类名。

z_index

其在绘制顺序中的位置:索引较高者绘制于较低者之上 (默认 0)。

target

MoveToTarget 将 mobject 移动至的状态。

还接受 样式关键字。

源码

manimgx\mobjects\text.py

def __init__(
    self, *tex_strings: str | float, **kwargs: Unpack[MathTexOptions]
) -> None:
    kwargs.setdefault("arg_separator", "")
    kwargs.setdefault("tex_environment", "center")
    super().__init__(*tex_strings, **kwargs)

Typst

代码
import manimgx as m


class TypstExample(m.Scene):
    def construct(self) -> None:
        document = m.Typst(
            "*Typst* markup, _typeset_ in the engine:\n\n"
            "$ sum_(k=1)^n k = (n(n+1))/2 $\n\n"
            "with #text(fill: orange)[colors of its own]",
            font_size=64,
        )
        self.play(m.Write(document))

一个 Typst 文档,在引擎中排版:其排版中的每个字形和形状都是 一个部分,未加样式时为白色。

代码是 Typst 标记,即页面上文档的正文,页面大小恰好容纳其内容: *strong*、_emphasis_、$ 符号之间的数学、#set 和 #show 规则, 以及 Typst 的其余部分。各部分是 Typst 排版出的内容,按文档顺序排列, 不含空格:字形(TypstGlyph)和 形状(规则、分数的横线、方框)。带标签的方框 #box[…] <name> 是一个 组:select 可获取它。包从 package_path 导入 (以及 mitex,@preview/mitex:0.2.7,来自 ManimGX 的引擎),从不下载; Typst 无法排版的代码会引发 TypstError。

文本以 Libertinus Serif 排版,数学以 New Computer Modern Math 排版, 即 Typst 的默认值,除非代码设置了其他字体。字体为 ManimGX 附带的字体, 因此文档在每台机器上看起来相同:Typst 自带的(这两种、New Computer Modern 和 DejaVu Sans Mono)、Noto Sans,以及为上述字体所缺文字体提供的 Noto 字体,从阿拉伯文、希伯来文和天城体到中文、日文和韩文,以及符号和 表情符号;字体缺少的字符会用拥有该字符的字体排版。font_paths 中的 字体优先,仅当代码命名的字体族在上述字体中均无时才读取系统字体。段落 方向和汉字的字形跟随代码的 lang 和 dir(#set text(lang: "ja")、 #set text(dir: rtl));Text 从其字符设置它们。

Typst 以其默认墨色(黑色)绘制的内容取 color,代码设置的颜色予以保留, 除非绘制关键字(fill_color 等)在每个部分之上重新绘制。文档排版一次: 相同的代码在任何进程中从磁盘缓存读回。

m.Typst(typst_code, *, font_size=DEFAULT_FONT_SIZE, typst_preamble='', font_paths=None, should_center=True, height=None, width=None, package_path=None, font_scale=1.0, color=None, fill_color=None, fill_opacity=None, stroke_color=None, stroke_opacity=None, stroke_width=None, opacity=None, **kwargs)
typst_code

文档:Typst 标记。

font_size

文本的大小:一个 em 为 font_size / 96 场景单位(48 时 为 0.5)。

typst_preamble

在文档之前设置的 Typst 代码:规则、定义、 导入。

font_paths

字体文件的目录,连同其子目录在 ManimGX 附带的字体 之前搜索。

should_center

mobject 是否居中于原点。

height

将 mobject 缩放至的高度,以场景单位计;None 则按 font_size 确定大小。

width

在 height 之后将 mobject 缩放至的宽度,以场景单位计;None 则按 font_size 确定大小。

package_path

Typst 包导入的目录(作为 namespace/name/version 目录),除 ManimGX 引擎持有的 mitex 外; None 表示除 mitex 外无任何包。

font_scale

文本排版时比 font_size 大多少:排版按 font_size * font_scale 缩放,而 font_size 读取 font_size。 Text 将其设为字体自身的缩放比例,使每个字体中 大写字母的高度相同。

color

Typst 默认墨色(黑色)的颜色;None 为白色。

fill_color

每个部分的填充颜色;None 保留排版的颜色。

fill_opacity

每个部分的填充不透明度,从 0 到 1;None 保留 排版的不透明度。

stroke_color

每个部分的描边颜色;None 保留排版的颜色。

stroke_opacity

每个部分的描边不透明度,从 0 到 1;None 保留 排版的不透明度。

stroke_width

每个部分的描边宽度,以百分之一场景单位计; None 保留排版的宽度,其随 mobject 缩放。

opacity

每个部分的填充和描边的不透明度,从 0 到 1,在 fill_opacity 或 stroke_opacity 未给出的地方使用;None 保留 排版的不透明度。

background_stroke_color

绘制于填充之后的轮廓颜色(默认黑色)。

background_stroke_opacity

轮廓的不透明度,取值从 0 到 1(默认 1)。

background_stroke_width

轮廓的宽度,以场景单位的百分之一计(默认 0:无)。

sheen_factor

颜色朝 sheen_direction 变亮的程度,取值从 -1 到 1(默认 0); 负值变暗。

sheen_direction

颜色变亮的方向(默认 UL)。

joint_type

描边在路径转折处的连接方式:圆角、斜切或斜接,按二维场景的绘制方式 (参见 LineJointType;默认 AUTO:斜接)。

cap_style

描边在其显示的每一端的端点样式(开放路径的端点、虚线的端点):圆头、平头 或方头,按二维场景的绘制方式(参见 CapStyleType;默认 AUTO:平头)。

shade_in_3d

三维场景的光是否对该 mobject 着色。

material

其表面在三维场景中如何反射场景的光(参见 Material);None:Manim 的着色(默认)。

name

mobject 的名称;未给出时为其类名。

z_index

其在绘制顺序中的位置:索引较高者绘制于较低者之上 (默认 0)。

target

MoveToTarget 将 mobject 移动至的状态。

还接受 样式关键字。

源码

manimgx\mobjects\text.py

@prototype
def __init__(
    self,
    typst_code: str,
    *,
    font_size: float = DEFAULT_FONT_SIZE,
    typst_preamble: str = "",
    font_paths: list[str | Path] | None = None,
    should_center: bool = True,
    height: float | None = None,
    width: float | None = None,
    package_path: str | Path | None = None,
    font_scale: float = 1.0,
    color: Colors | None = None,
    fill_color: Colors | None = None,
    fill_opacity: float | Sequence[float] | None = None,
    stroke_color: Colors | None = None,
    stroke_opacity: float | Sequence[float] | None = None,
    stroke_width: float | None = None,
    opacity: float | None = None,
    **kwargs: Unpack[Look],
):
    super().__init__(stroke_color=None, fill_color=None, **kwargs)
    self.set_color(WHITE if color is None else color)
    # how much larger than font_size the text is set (a font's calibration: see Text)
    self._font_scale = font_scale
    self.typst_code = typst_code
    """mobject 排版所用的 Typst 代码。"""
    self.typst_preamble = typst_preamble
    """在其之前设置的 Typst 代码。"""
    # unless a stroke width is given, a stroke keeps its share of its part's size as
    # typeset: (part, its size and its stroke width as typeset)
    self._strokes_scale = stroke_width is None
    self._strokes: list[tuple[VMobject, float, float]] = []
    # A height overrides font sizing; width is fitted afterward in either case.
    placed = should_center and height is None
    self.initial_height = self._build(
        typeset(
            typst_code,
            typst_preamble,
            font_paths=font_paths,
            package_path=package_path,
        ),
        font_size * font_scale * SCALE_FACTOR_PER_FONT_POINT if placed else None,
    )
    if opacity is not None:  # both, where one isn't given its own
        fill_opacity = opacity if fill_opacity is None else fill_opacity
        stroke_opacity = opacity if stroke_opacity is None else stroke_opacity
    self.set_style(
        fill_color=fill_color,
        fill_opacity=fill_opacity,
        stroke_color=stroke_color,
        stroke_opacity=stroke_opacity,
        stroke_width=stroke_width,
    )
    if should_center and not placed:
        self.center()
    if height is not None:
        self.set(height=height)
    elif not placed:
        self.font_size = font_size
    if width is not None:
        self.set(width=width)

typst_code

mobject 排版所用的 Typst 代码。

typst_preamble

在其之前设置的 Typst 代码。

font_size

mobject 的有效字号,包含缩放。构造时给出的显式宽度或高度 决定此大小。将其设为正数可将 mobject 缩放至该大小。

typst.font_size
源码

manimgx\mobjects\text.py

def font_size(self) -> float:
    """mobject 的有效字号,包含缩放。构造时给出的显式宽度或高度
    决定此大小。将其设为正数可将 mobject 缩放至该大小。"""
    return (
        self.height
        / self.initial_height
        / SCALE_FACTOR_PER_FONT_POINT
        / self._font_scale
    )

select

TypstSelectExample
代码
import manimgx as m


class TypstSelectExample(m.Scene):
    def construct(self) -> None:
        text = m.Typst(
            "Label a #box[box] <noun> to #box[select] <verb> it",
            font_size=96,
        )
        text.select("noun").set_color(m.YELLOW)
        text.select("verb").set_color(m.BLUE)
        self.add(text)

查找带标签组的各部分:将每个具有该标签的组作为一个整体。

标签为代码中方框命名,#box[…] <name>; MathTypst 也将 {{ … }} 作为一个组,由 {{ … : name }} 命名或按顺序编号。未知标签引发 KeyError,超出 范围的编号引发 IndexError。

typst.select(key)
key

标签;或 MathTypst 未命名 {{ … }} 组的编号,从 0 开始。

返回 各部分本身(非副本)按顺序组成的新组。

源码

manimgx\mobjects\text.py

def select(self, key: str | int) -> VGroup:
    """查找带标签组的各部分:将每个具有该标签的组作为一个整体。

    标签为代码中方框命名,`#box[…] <name>`;
    [MathTypst][manimgx.MathTypst] 也将 `{{ … }}` 作为一个组,由
    `{{ … : name }}` 命名或按顺序编号。未知标签引发 KeyError,超出
    范围的编号引发 IndexError。

    Args:
        key: 标签;或 MathTypst 未命名 `{{ … }}` 组的编号,从
            0 开始。

    Returns:
        各部分本身(非副本)按顺序组成的新组。

    Examples:
        ```python
        import manimgx as m


        class TypstSelectExample(m.Scene):
            def construct(self) -> None:
                text = m.Typst(
                    "Label a #box[box] <noun> to #box[select] <verb> it",
                    font_size=96,
                )
                text.select("noun").set_color(m.YELLOW)
                text.select("verb").set_color(m.BLUE)
                self.add(text)
        ```
    """
    label = f"_grp-{key}" if isinstance(key, int) else key
    if label not in self.labels:
        error = IndexError if isinstance(key, int) else KeyError
        raise error(f"no group {key!r}; labels: {list(self.labels)}")
    return self.labels[label]

scale

将 mobject 及其整个族围绕某点缩放,如同 Mobject.scale 所做;排版绘制的描边(规则、 方框轮廓)保持其占部分大小的份额,除非 mobject 由 stroke_width 创建。

typst.scale(scale_factor, scale_stroke=False, **kwargs)
scale_factor

缩放因子:2 将 mobject 大小加倍,0.5 减半;或 沿 x、y 和 z 的各因子。

scale_stroke

其他描边的宽度是否也按因子缩放。

about_point

保持不动的点,以场景坐标表示;它优先于 about_edge。

about_edge

mobject 边界框上保持不动的点,以方向命名: UP 表示其顶边的中点,UR 表示其右上角,ORIGIN 表示其中心。

源码

manimgx\mobjects\text.py

def scale(
    self,
    scale_factor: float | Vector3DLike,
    scale_stroke: bool = False,
    **kwargs: Unpack[Pivot],
) -> Self:
    """将 mobject 及其整个族围绕某点缩放,如同
    [Mobject.scale][manimgx.Mobject.scale] 所做;排版绘制的描边(规则、
    方框轮廓)保持其占部分大小的份额,除非 mobject 由 `stroke_width`
    创建。

    Args:
        scale_factor: 缩放因子:2 将 mobject 大小加倍,0.5 减半;或
            沿 x、y 和 z 的各因子。
        scale_stroke: 其他描边的宽度是否也按因子缩放。
        **kwargs: [Pivot 关键字][manimgx.mobject.Pivot]。
    """
    result = super().scale(scale_factor, scale_stroke=scale_stroke, **kwargs)
    self._scale_strokes()
    return result

MathTypst

代码
import manimgx as m


class MathTypstExample(m.Scene):
    def construct(self) -> None:
        formula = m.MathTypst(
            "{{ a^2 : a }} + {{ b^2 : b }} = {{ c^2 : c }}", font_size=144
        )
        formula.select("a").set_color(m.BLUE)
        formula.select("b").set_color(m.GREEN)
        formula.select("c").set_color(m.YELLOW)
        self.play(m.Write(formula))

以 Typst 数学语法表示的公式,以展示样式排版:其部分为 字形和形状,未加样式时为白色。

MathTypst("x^2 + y^2") 排版 $ x^2 + y^2 $,使用 New Computer Modern Math。 双花括号构成组,select 可获取:{{ x^2 }} 按顺序编号,0 为第一个,{{ x^2 : square }} 命名为 "square";花括号 不被排版。

m.MathTypst(math_expression, **kwargs)
math_expression

公式,以 Typst 数学表示。

font_size

文本的大小:一个 em 为 font_size / 96 场景单位,默认时为 0.5, 48(Text 按其大写字母确定大小:48 时高 0.449 单位)。

typst_preamble

在文档之前设置的 Typst 代码:#set 和 #show 规则、#let 定义、导入(默认为 "")。

font_paths

字体文件(.ttf、.otf、.ttc、.otc)的目录,在 manimgx 附带的字体之前 连同其子目录一起搜索;指向文件的路径不添加任何内容 (默认为 None)。

should_center

mobject 是否居中于原点(默认为 True)。

height

将 mobject 缩放至的高度,以场景单位计,而非按 font_size 确定大小 (默认为 None)。

width

将 mobject 缩放至的宽度,以场景单位计,而非按 font_size 确定大小; 若同时给出 height,则宽度最后设置(默认为 None)。

package_path

Typst 包导入的目录,将包存放为 namespace/name/version 目录: #import "@preview/name:1.0.0" 读取 preview/name/1.0.0(默认为 None: 除 mitex 外无任何包,mitex 由 manimgx 的引擎持有)。不下载任何内容。

background_stroke_color

绘制于填充之后的轮廓颜色(默认黑色)。

background_stroke_opacity

轮廓的不透明度,取值从 0 到 1(默认 1)。

background_stroke_width

轮廓的宽度,以场景单位的百分之一计(默认 0:无)。

sheen_factor

颜色朝 sheen_direction 变亮的程度,取值从 -1 到 1(默认 0); 负值变暗。

sheen_direction

颜色变亮的方向(默认 UL)。

joint_type

描边在路径转折处的连接方式:圆角、斜切或斜接,按二维场景的绘制方式 (参见 LineJointType;默认 AUTO:斜接)。

cap_style

描边在其显示的每一端的端点样式(开放路径的端点、虚线的端点):圆头、平头 或方头,按二维场景的绘制方式(参见 CapStyleType;默认 AUTO:平头)。

shade_in_3d

三维场景的光是否对该 mobject 着色。

material

其表面在三维场景中如何反射场景的光(参见 Material);None:Manim 的着色(默认)。

name

mobject 的名称;未给出时为其类名。

z_index

其在绘制顺序中的位置:索引较高者绘制于较低者之上 (默认 0)。

target

MoveToTarget 将 mobject 移动至的状态。

还接受 样式关键字。

源码

manimgx\mobjects\text.py

@prototype
def __init__(self, math_expression: str, **kwargs: Unpack[TypstOptions]):
    processed, labels = _groups(math_expression)
    preamble = kwargs.get("typst_preamble", "")
    if labels and _MANIMGRP not in preamble:
        kwargs["typst_preamble"] = (
            f"{_MANIMGRP}\n{preamble}" if preamble else _MANIMGRP
        )
    super().__init__(f"$ {processed} $", **kwargs)

排版文本的组成部分

每个文本和公式都由字形组成,正如 Typst 所排版的那样:每个字形知道自己绘制的是源文本中的 哪些字符。Typst 无法排版的源文本会以 Typst 的错误中止场景。

TypstGlyph

Typst 所设置的一个字形,排版 mobject 的一个部分:其轮廓,已放置,以及 它绘制的源字符。

node 是字形的源节点在 Typst 代码中起始的位置(若不来自代码则为 -1), drawn 为该节点文本中它绘制的字节,key 为其轮廓, x_advance 为其以字体单位计的宽度。

color

填充与描边共用的颜色(默认白色);None 表示该类的默认值。

fill_color

填充的颜色;未给出时为 color。多个颜色沿 sheen_direction 构成渐变。

fill_opacity

填充的不透明度,取值从 0 到 1(默认 0:无填充)。

stroke_color

描边的颜色;未给出时为 color。多个颜色构成渐变。

stroke_opacity

描边的不透明度,取值从 0 到 1(默认 1)。

stroke_width

描边的宽度,以场景单位的百分之一计(默认 4;0:无描边)。

background_stroke_color

绘制于填充之后的轮廓颜色(默认黑色)。

background_stroke_opacity

轮廓的不透明度,取值从 0 到 1(默认 1)。

background_stroke_width

轮廓的宽度,以场景单位的百分之一计(默认 0:无)。

sheen_factor

颜色朝 sheen_direction 变亮的程度,取值从 -1 到 1(默认 0); 负值变暗。

sheen_direction

颜色变亮的方向(默认 UL)。

joint_type

描边在路径转折处的连接方式:圆角、斜切或斜接,按二维场景的绘制方式 (参见 LineJointType;默认 AUTO:斜接)。

cap_style

描边在其显示的每一端的端点样式(开放路径的端点、虚线的端点):圆头、平头 或方头,按二维场景的绘制方式(参见 CapStyleType;默认 AUTO:平头)。

shade_in_3d

三维场景的光是否对该 mobject 着色。

material

其表面在三维场景中如何反射场景的光(参见 Material);None:Manim 的着色(默认)。

name

mobject 的名称;未给出时为其类名。

z_index

其在绘制顺序中的位置:索引较高者绘制于较低者之上 (默认 0)。

target

MoveToTarget 将 mobject 移动至的状态。

还接受 样式关键字。

源码

manimgx\mobject.py

def __init__(self, **kwargs: Unpack[Style]) -> None:
    if (
        "color" in kwargs and kwargs["color"] is None
    ):  # not given: the class's default
        del kwargs["color"]
    self.style = style_defaults(type(self)) | kwargs
    """待定的构造器样式,包括类的默认值。基础颜色初始化会消耗此实例条目;
    当前外观保存在 [paint][manimgx.Mobject.paint] 中。点云保留其默认值供后续点使用。"""
    name = self.style.get("name")
    self.name = type(self).__name__ if name is None else name
    """mobject 的名称:其类的名称,除非创建时指定了名称。"""
    self.dim = 3
    """其每个点拥有的坐标数:3。"""
    self.target: Mobject | None = self.style.get("target")
    """[MoveToTarget][manimgx.MoveToTarget] 将 mobject 移动到的状态:由
    [generate_target][manimgx.Mobject.generate_target] 创建,或在创建 mobject 时给定;
    若两者皆无则为 None。"""
    self.z_index = self.style.get("z_index", 0.0)
    """mobject 在绘制顺序中的位置:索引值较高的绘制在索引值较低的之上
    (默认 0);参见 [set_z_index][manimgx.Mobject.set_z_index]。"""
    self.submobjects: list[Mobject] = []
    """mobject 的子对象,按绘制顺序排列:在相同 z 索引下,每个绘制在之前的之上。"""
    self.updaters: list[Updater[Self]] = []
    """mobject 自身的更新器,按运行顺序排列;参见
    [add_updater][manimgx.Mobject.add_updater]。"""
    self.updating_suspended = False
    """mobject 的更新器是否被暂停;参见
    [suspend_updating][manimgx.Mobject.suspend_updating]。"""
    self.paint = _UNPAINTED
    """mobject 自身当前的样式,作为一个值:其颜色、不透明度、
    描边宽度和光泽。样式方法会替换它;它永远不会被就地修改。"""
    self.reset_points()
    self.generate_points()
    self.init_colors()

node

字形来源的源节点在 Typst 代码中起始的位置,以字节计。由包代码 绘制的字形(包函数设置的根号)来自其周围代码的最内层元素(其方程); 若无则为 -1。

drawn

该节点文本中字形簇绘制的字节,从哪到哪:对于字符串 字面量,为其值的字节;若节点是其周围的元素则为 -1, -1。

key

其轮廓和字体插入符的来源键,在每个进程中相同。 赋予键不会改变活动字形的轮廓或插入符。

x_advance

其前进量,即它在行中占据的宽度,以字体单位计:连字 的插入符将其分割。

manimgx.drawing.typesetting.TypstError

当 Typst 无法排版文档,或 LaTeX 无法转换为 Typst 时抛出的错误: 其消息为 Typst(或 mitex)的消息,每个错误附带其所在源码的字节位置, 从整个被排版文档的起始处计数——页面设置和前导部分位于代码之前。

Pivot

变换所保持不动的点:给定的点,或 mobject 边界框上的一个点。

当两个关键字均未指定时,缩放、旋转或拉伸保持 mobject 的中心不动, 而函数或矩阵关于原点应用。

about_point

保持不动的点,以场景坐标表示;它优先于 about_edge。

about_edge

mobject 边界框上保持不动的点,以方向命名: UP 表示其顶边的中点,UR 表示其右上角,ORIGIN 表示其中心。

about_point

保持不动的点,以场景坐标表示;它优先于 about_edge。

about_edge

mobject 边界框上保持不动的点,以方向命名: UP 表示其顶边的中点,UR 表示其右上角,ORIGIN 表示其中心。