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

  • If duration is provided, it stretches the time of child animations to make the overall end time consistent with 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 indicates “the percentage of completion of the previous animation at which the next animation starts”

  • offset indicates “the number of seconds after the previous animation starts when the next animation starts”

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
)

In addition, collapse indicates whether to collapse this animation group in the preview interface (default is not collapsed, while for example TransformMatchingShapes is collapsed by default)

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: SupportsAnim, 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

Wait for a specific time, useful in Succession()

(Actually just an empty animation)

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

Bases: Animation

Execute a specified operation at a specific time in the animation progress