Files
calesthioandHanzo Dev 7ffb943132 Initial release — OpenMontage: the first open-source agentic video production system
11 production pipelines, 47 tools, 124 agent skills.
Supports cloud APIs (fal.ai, OpenAI, ElevenLabs, Suno, HeyGen, Runway) and
free local providers (diffusers, Piper TTS, WAN 2.1, Hunyuan, CogVideo).

Co-authored-by: Hanzo Dev <[email protected]>
2026-03-29 08:25:17 -07:00

5.1 KiB

name, description, metadata
name description metadata
animation-groups AnimationGroup, LaggedStart, Succession for complex animation sequences
tags
animationgroup, laggedstart, succession, lag_ratio, sequence

Animation Groups

Control how multiple animations play together.

AnimationGroup

Play multiple animations with controlled timing.

from manim import *

class AnimationGroupExample(Scene):
    def construct(self):
        circles = VGroup(*[Circle() for _ in range(5)]).arrange(RIGHT)

        # All animations play simultaneously (lag_ratio=0)
        self.play(AnimationGroup(
            *[Create(c) for c in circles],
            lag_ratio=0
        ))

lag_ratio Parameter

Controls the delay between animation starts:

  • lag_ratio=0: All start simultaneously
  • lag_ratio=0.5: Each starts when previous is 50% complete
  • lag_ratio=1: Each starts when previous finishes (sequential)
class LagRatioDemo(Scene):
    def construct(self):
        squares = VGroup(*[Square() for _ in range(4)]).arrange(RIGHT)

        # Staggered start - each begins when previous is 25% done
        self.play(AnimationGroup(
            *[FadeIn(s) for s in squares],
            lag_ratio=0.25,
            run_time=2
        ))

LaggedStart

Convenience class with default lag_ratio=0.05 (5% overlap).

class LaggedStartExample(Scene):
    def construct(self):
        dots = VGroup(*[Dot() for _ in range(10)]).arrange(RIGHT)

        # Rapid staggered animation
        self.play(LaggedStart(
            *[GrowFromCenter(d) for d in dots],
            lag_ratio=0.1
        ))

Common LaggedStart Patterns

# Staggered fade in
self.play(LaggedStart(*[FadeIn(m) for m in mobjects], lag_ratio=0.2))

# Wave effect
self.play(LaggedStart(
    *[m.animate.shift(UP * 0.5) for m in mobjects],
    lag_ratio=0.1
))

# Staggered color change
self.play(LaggedStart(
    *[m.animate.set_color(RED) for m in mobjects],
    lag_ratio=0.15
))

Succession

Play animations one after another (equivalent to lag_ratio=1).

class SuccessionExample(Scene):
    def construct(self):
        circle = Circle().shift(LEFT * 2)
        square = Square()
        triangle = Triangle().shift(RIGHT * 2)

        # Animations play in sequence
        self.play(Succession(
            Create(circle),
            Create(square),
            Create(triangle)
        ))

Succession vs Multiple play() Calls

# These are equivalent:

# Using Succession
self.play(Succession(
    Create(circle),
    Create(square)
))

# Using separate play calls
self.play(Create(circle))
self.play(Create(square))

Succession is useful when you want to treat sequential animations as a single unit.

Combining Group Types

class CombinedExample(Scene):
    def construct(self):
        group1 = VGroup(*[Circle() for _ in range(3)]).arrange(RIGHT).shift(UP)
        group2 = VGroup(*[Square() for _ in range(3)]).arrange(RIGHT).shift(DOWN)

        # First group appears with stagger, then second group
        self.play(Succession(
            LaggedStart(*[Create(c) for c in group1], lag_ratio=0.2),
            LaggedStart(*[Create(s) for s in group2], lag_ratio=0.2)
        ))

LaggedStartMap

Apply an animation to all submobjects of a mobject with staggered timing.

class LaggedStartMapExample(Scene):
    def construct(self):
        dots = VGroup(*[Dot(radius=0.16) for _ in range(35)]).arrange_in_grid(rows=5, cols=7)

        # Apply FadeIn to all dots with stagger
        self.play(LaggedStartMap(FadeIn, dots, lag_ratio=0.1))
        self.wait(0.5)

        # Change color with stagger using LaggedStart
        self.play(LaggedStart(
            *[dot.animate.set_color(YELLOW) for dot in dots],
            lag_ratio=0.05
        ))

LaggedStartMap is cleaner for applying the same animation to each submobject. For property changes, use LaggedStart with .animate.

AnimationGroup with run_time

The total run_time is distributed among animations based on lag_ratio.

self.play(AnimationGroup(
    *[Create(c) for c in circles],
    lag_ratio=0.5,
    run_time=4  # Total duration is 4 seconds
))

Practical Examples

Text Appearing Word by Word

class WordByWord(Scene):
    def construct(self):
        words = VGroup(
            Text("Hello"),
            Text("World"),
            Text("!")
        ).arrange(RIGHT)

        self.play(LaggedStart(
            *[Write(w) for w in words],
            lag_ratio=0.5
        ))

Grid Animation

class GridAnimation(Scene):
    def construct(self):
        grid = VGroup(*[
            Square().scale(0.3)
            for _ in range(25)
        ]).arrange_in_grid(5, 5)

        # Diagonal wave effect
        self.play(LaggedStart(
            *[GrowFromCenter(s) for s in grid],
            lag_ratio=0.05
        ))

Best Practices

  1. Use LaggedStart for visual polish - Staggered animations look more dynamic
  2. Keep lag_ratio small (0.05-0.2) - Too high feels slow
  3. Use Succession for distinct steps - When animations are conceptually separate
  4. Adjust run_time with lag_ratio - More items may need longer total time