composition

class janim.anims.composition.AnimGroup(*anims: ~janim.typing.SupportsAnim, at: float = 0, duration: float | None = None, lag_ratio: float = 0, offset: float = 0, rate_func: RateFunc = <function linear>, name: str | None = None, collapse: bool = False)

Bases: Animation

Collection of animations (executed in parallel)

  • If duration is not provided, it takes the termination time (the maximum end time of child animations) as the duration of this animation group

  • 若传入 duration,则会将子动画的生效时间进行拉伸,使得总终止时间与 duration 一致

  • You can also use at for an overall offset (e.g., if at=1, it delays the entire animation by 1s)

You can use lag_ratio and offset to control the timing position of each sub-animation relative to the previous one:

  • lag_ratio 表示 “前一个进行到百分之多少时,进行下一个”

  • offset 表示 “前一个进行多少秒后,进行下一个”

Time Examples:

AnimGroup(
    Anim1(duration=3),  # 0~3s
    Anim2(duration=4)   # 0~4s
)

AnimGroup(
    Anim1(duration=3),  # 0~4.5s
    Anim2(duration=4),  # 0~6s
    duration=6
)

AnimGroup(
    Anim1(duration=3),  # 1~5.5s
    Anim2(duration=4),  # 1~7s
    at=1,
    duration=6
)

另外,collapse 表示在预览界面中是否折叠该动画组(默认不折叠,而例如 TransfromMatchingShapes 默认是折叠的)

An interactive example of lag_ratio and offset:

0
0
Anim1 1s
Anim2 1s
Anim3 2s
Anim4 1s
AnimGroupExample
from janim.imports import *

class AnimGroupExample(Timeline):
    def construct(self):
        group = Group(
            Circle(fill_alpha=0.5),
            Square(fill_alpha=0.5),
            Text('Text', font_size=48),
            color=BLUE
        )
        group.points.arrange(buff=LARGE_BUFF)

        self.forward()
        self.play(
            FadeIn(group[0]),
            AnimGroup(
                FadeIn(group[1]),
                FadeIn(group[2]),
                duration=2
            )
        )
        self.forward()

        self.hide(group)
        self.play(
            FadeIn(group[0], duration=2),
            AnimGroup(
                FadeIn(group[1]),
                FadeIn(group[2]),
                at=1,
                duration=2
            )
        )
        self.forward()

Note

For better understanding the effect of these animation compositions, you can copy these code into your file and execute, so you can see the ranges of animations on the GUI.

class janim.anims.composition.Succession(*anims: Animation, lag_ratio: float = 1, offset: float = 0, **kwargs)

Bases: AnimGroup

Collection of animations (executed sequentially)

  • Executes the passed animations in sequence

  • Equivalent to AnimGroup with the default value lag_ratio=1

Time Examples:

Succession(
    Anim1(duration=3),  # 0~3s
    Anim2(duration=4)   # 3~7s
)

Succession(
    Anim1(duration=2),          # 0~2s
    Anim2(at=1, duration=2),    # 3~5s
    Anim3(at=0.5, duration=2)   # 5.5~7.5s
)

Succession(
    Anim1(duration=2),  # 0~2s
    Anim2(duration=2),  # 2.5~4.5s
    Anim3(duration=2),  # 5~7s
    offset=0.5
)

An interactive example of lag_ratio and offset:

0
0
Anim1 1s
Anim2 1s
Anim3 2s
Anim4 1s
SuccessionExample
from janim.imports import *

class SuccessionExample(Timeline):
    def construct(self):
        group = Group(
            Circle(fill_alpha=0.5),
            Square(fill_alpha=0.5),
            Text('Text', font_size=48),
            color=BLUE
        )
        group.points.arrange(buff=LARGE_BUFF)

        self.forward()
        self.play(
            Succession(
                *map(FadeIn, group)
            )
        )
        self.forward()

        self.hide(group)
        self.play(
            Succession(
                *map(FadeIn, group),
                offset=1
            )
        )
        self.forward()

        self.hide(group)
        self.play(
            Succession(
                *map(FadeIn, group),
                offset=-0.7
            )
        )
        self.forward()
class janim.anims.composition.Aligned(*anims: ~janim.typing.SupportsAnim, at: float = 0, duration: float | None = None, rate_func: RateFunc = <function linear>, name: str | None = None, collapse: bool = False)

Bases: AnimGroup

Collection of animations (executed in parallel and aligned)

In other words, it ignores the at and duration of sub-animations, causing all sub-animations to start and end together.

Time Examples:

Aligned(
    Anim1(duration=1),
    Anim2(duration=2)
)
# Anim1 & Anim2: 0~2s

Aligned(
    Anim1(at=1, duration=1),
    Anim2(duration=2),
    duration=4
)
# Anim1 & Anim2: 0~4s

Warning

The code of video example is the code below, not the code of time example above.

AlignedExample
from janim.imports import *

class AlignedExample(Timeline):
    def construct(self):
        group = Group(
            Circle(fill_alpha=0.5),
            Square(fill_alpha=0.5),
            Text('Text', font_size=48),
            color=BLUE
        )
        group.points.arrange(buff=LARGE_BUFF)

        self.forward()
        self.play(
            Aligned(
                FadeIn(group[0], duration=2),
                FadeIn(group[1], duration=3),
                FadeIn(group[2], at=0.5, duration=0.5)
            )
        )
        self.forward()
class janim.anims.composition.Wait(duration: float = 1, **kwargs)

Bases: Animation

等待特定时间,在 Succession() 中比较有用

(其实就是一个空动画)

class janim.anims.composition.Do(func, *args, at: float = 0, detect_changes: bool = True, **kwargs)

Bases: Animation

在动画的特定时间执行指定操作