创建自定义动画

尽管 Manim 有许多内置动画,但你也会发现有时你需要从 :class:'~.Mobject' 的一种状态平滑地动画到另一种状态。如果你发现自己处于这种情况,那么你可以定义自己的自定义动画。你首先扩展 :class:'~.Animation' 类并覆盖它的 :meth:'~.Animation.interpolate_mobject' 来。:meth:'~.Animation.interpolate_mobject' 方法接收 alpha 作为参数,该参数从 0 开始,并在整个动画中发生变化。所以,你只需要根据 interpolate_mobject 方法中的 alpha 值在 Animation 中作 self.mobject。然后你就会得到 :class:'~.Animation' 的所有好处,比如在不同的运行时间内播放它或使用不同的 rate 函数。

假设你从一个数字开始,想要创建一个 :class:'~.Transform' 动画,将其转换为目标数字。你可以使用 :class:'~.FadeTransform' 来实现,它将淡出起始数字并淡入目标数字。但是当我们考虑将一个数字从一个数字转换为另一个数字时,一种直观的方法是平滑地递增或递减它。Manim 有一个功能,允许你通过定义自己的自定义动画来自定义此行为。

你可以从创建自己的Count类开始,该类扩展了 :class:'~.Animation' 来。该类可以有一个带有三个参数的构造函数,一个 :class:'~.DecimalNumber' M对象,start和end。构造函数会将 :class:'~.DecimalNumber' M对象传递给超级构造函数(在本例中为 :class:'~.Animation' 构造函数),并将设置 start 和 end。

您唯一需要做的就是定义您希望它如何看待动画的每一步。Manim 在 :meth:'~ 中为您提供 alpha 值。Animation.interpolate_mobject' 方法基于视频的帧速率、rate 函数和播放动画的运行时间。alpha 参数保存一个介于 0 和 1 之间的值,表示当前播放的动画的步骤。例如,0 表示动画开始,0.5 表示动画进行到一半,1 表示动画结束。

Count动画的情况下,你只需要想出一种方法来确定在给定的 alpha 值处显示的数字,然后在Count动画的 :meth:'~.Animation.interpolate_mobject' 方法中设置该值。假设你从 50 开始,一直递增到 :class:'~.DecimalNumber' 在动画结束时达到 100。

  • 如果 alpha 为 0,则希望值为 50。

  • 如果 alpha 为 0.5,则希望值为 75。

  • 如果 alpha 为 1,则希望值为 100。

通常,你从起始数字开始,只添加值的一部分,根据 alpha 值进行增量。因此,计算每个步骤要显示的数字的逻辑将是 50 + alpha * (100 - 50)。一旦你为 :class:'~.DecimalNumber' 设置了计算值,你就完成了。

一旦你定义了你的Count动画,你就可以在你的 :class:'~ 中播放它。Scene' 的 Scene' 来获得任何 :class:'~ 所需的任何持续时间。DecimalNumber“ 的 IntegerNumber 函数

class Count(Animation):
    def __init__(self, number: DecimalNumber, start: float, end: float, **kwargs) -> None:
        # Pass number as the mobject of the animation
        super().__init__(number,  **kwargs)
        # Set start and end
        self.start = start
        self.end = end

    def interpolate_mobject(self, alpha: float) -> None:
        # Set value of DecimalNumber according to alpha
        value = self.start + (alpha * (self.end - self.start))
        self.mobject.set_value(value)


class CountingScene(Scene):
    def construct(self):
        # Create Decimal Number and add it to scene
        number = DecimalNumber().set_color(WHITE).scale(5)
        # Add an updater to keep the DecimalNumber centered as its value changes
        number.add_updater(lambda number: number.move_to(ORIGIN))

        self.add(number)

        self.wait()

        # Play the Count Animation to count from 0 to 100 in 4 seconds
        self.play(Count(number, 0, 100), run_time=4, rate_func=linear)

        self.wait()

Last updated