Skip to content

场景与分组 ​

clear / remove 的场景语义、VGroup 的下标与嵌套、循环搭建,以及 3D 相机的「正」。

本页 6 条示例。代码引自 corpus/examples/scene/,截图为真机渲染的终态。

clear 后重新画 ​

clear 后画面清空,随后新画的物体单独出现。

clear 后重新画

py
"""clear 后重新画

@expect clear 后画面清空,随后新画的物体单独出现。"""

from manim import *


class ClearScene(Scene):
    def construct(self):
        self.add(Circle(radius=1.5))
        self.wait(0.2)
        self.clear()
        self.add(Square(side_length=2))
        self.wait(0.2)

remove 摘掉物体 ​

被 remove 的物体消失,其余物体原样保留:场景放三个物体,只 remove 其中一个(红圆,标注「remove」),终帧蓝方块与黄三角仍在、红圆不在——「只删一个」自证。

remove 摘掉物体

py
"""remove 摘掉物体

@expect 被 remove 的物体消失,其余物体原样保留:场景放三个物体,
        只 remove 其中一个(红圆,标注「remove」),终帧蓝方块与黄三角
        仍在、红圆不在——「只删一个」自证。
"""

from manim import *


class RemoveScene(Scene):
    def construct(self):
        square = Square(side_length=1.6, color=BLUE)
        square.move_to([-3.5, 0, 0])
        circle = Circle(radius=0.9, color=RED)
        circle.move_to([0, 0, 0])
        triangle = Triangle(color=YELLOW)
        triangle.move_to([3.5, 0, 0])
        self.play(Create(square), Create(circle), Create(triangle))

        gone = Text("remove", font_size=24, color=RED)
        gone.move_to([0, 1.6, 0])
        stay = Text("保留", font_size=24, color=GREY_A)
        stay.move_to([-3.5, 1.6, 0])
        stay2 = Text("保留", font_size=24, color=GREY_A)
        stay2.move_to([3.5, 1.6, 0])
        self.play(FadeIn(gone), FadeIn(stay), FadeIn(stay2))

        # 只摘红圆一个,其余原样保留
        self.remove(circle)
        self.wait(0.3)

VGroup + 下标取子物体 ​

下标取出的子物体单独被操作,越界下标抛 IndexError(print 断言为准)。

VGroup + 下标取子物体

py
"""VGroup + 下标取子物体

@expect 下标取出的子物体单独被操作,越界下标抛 IndexError(print 断言为准)。"""

from manim import *


class VgroupIndexScene(Scene):
    def construct(self):
        dots = VGroup(*[Dot(point=[i - 2, 0, 0]) for i in range(5)])
        self.play(FadeIn(dots))
        self.play(dots[0].animate.set_color(RED))
        self.wait(0.3)

VGroup 套 VGroup ​

嵌套组整体动、子组也单独动,两层互不串。自证:外层整体上移后红点跟着走,内层再单独变黄、红点颜色不变。

VGroup 套 VGroup

py
"""VGroup 套 VGroup

@expect 嵌套组整体动、子组也单独动,两层互不串。
自证:外层整体上移后红点跟着走,内层再单独变黄、红点颜色不变。"""

from manim import *


class VgroupNestedScene(Scene):
    def construct(self):
        inner = VGroup(Circle(radius=0.4), Square(side_length=0.6))
        inner.arrange(RIGHT, buff=0.3)
        outer = VGroup(inner, Dot(point=[0, -1.5, 0], color=RED))
        self.play(FadeIn(outer))
        # 第一步:外层整体上移——圆、方、红点一起动
        self.play(outer.animate.shift(UP * 0.8))
        # 第二步:内层单独变色——只有圆和方变黄,红点不动也不变色
        self.play(inner.animate.set_color(YELLOW))
        note = Text("外层整体上移,内层单独变色", font_size=24).move_to([0, -3.2, 0])
        self.play(FadeIn(note))
        self.wait(0.3)

循环搭一组方块 ​

循环搭出的一排(一列)方块,数量与循环次数一致。

循环搭一组方块

py
"""循环搭一组方块

@expect 循环搭出的一排(一列)方块,数量与循环次数一致。
@note VGroup() 无参构造 + add 累积,是很常见的搭法
"""

from manim import *


class LoopBuildScene(Scene):
    def construct(self):
        squares = VGroup()
        for i in range(4):
            sq = Square(side_length=0.8, color=BLUE)
            sq.shift(RIGHT * (i * 1.2 - 1.8))
            squares.add(sq)
        self.play(Create(squares))
        self.wait(0.3)

3D 相机的「正」:x 轴该在屏幕上水平 ​

五个立方体排成一个正十字:红(x=-4)在左、蓝(x=+4)在右,两者的高低完全一样;黄(y=+3)在上、橙(y=-3)在下,两者与中间绿块的横向位置完全一样。立方体各自露出顶面与正面(有光、有深度)。

3D 相机的「正」:x 轴该在屏幕上水平

py
"""3D 相机的「正」:x 轴该在屏幕上水平

@expect 五个立方体排成一个**正十字**:红(x=-4)在左、蓝(x=+4)在右,两者的高低完全一样;
        黄(y=+3)在上、橙(y=-3)在下,两者与中间绿块的横向位置完全一样。
        立方体各自露出顶面与正面(有光、有深度)。
@note 这条是「相机没被滚转」的哨兵,因为滚转是**看不出来的错**:相机位置、角度全都对,
      `getOrbitAngles()` 读回来分毫不差,只有画面歪——任何几何断言都抓不到它。
      2026-10-11 实测:manim-web 0.3.24 的 `Camera3D.orbit` 用 `this._up || (…)` 把「相机朝上」
      锁在**第一次**调用上,于是建场景时那组默认角度(phi=70°/theta=-135°)会一直残留——
      这里渲出来就是 x 轴的三个立方体**斜着往上**(歪 15°)。修法与出处见
      `src/engine/manim-patch.ts`。
"""

from manim import *


class ThreeDUprightScene(ThreeDScene):
    def construct(self):
        self.set_camera_orientation(phi=50 * DEGREES, theta=-90 * DEGREES)  # 正面俯视:x 轴该水平
        self.add(
            Cube(color=RED).shift([-4, 0, 0]),
            Cube(color=GREEN).shift([0, 0, 0]),
            Cube(color=BLUE).shift([4, 0, 0]),
            Cube(color=YELLOW).shift([0, 3, 0]),
            Cube(color=ORANGE).shift([0, -3, 0]),
        )

MIT licensed · Manim 与 Pyodide 各依其自身许可(见「安装」)