# How to Create Custom Manim Animations by Subclassing the Animation Class and Defining Rate Functions

> Learn to create custom Manim animations by subclassing the Animation class. Define custom rate functions for precise control over timing and easing for stunning visuals.

- Repository: [Grant Sanderson/manim](https://github.com/3b1b/manim)
- Tags: how-to-guide
- Published: 2026-02-28

---

**Subclass the `Animation` class from `manimlib.animation.animation`, override `interpolate_submobject` to define frame-by-frame transformations, and pass a custom rate function to control easing and timing.**

To create custom Manim animations that go beyond built-in effects like `FadeIn` or `Transform`, you need to subclass the `Animation` class and define how each submobject changes over time. This approach, implemented in the 3b1b/manim repository, gives you precise control over interpolation logic and timing through custom rate functions.

## Understanding the Animation Base Class

The `Animation` class in [`manimlib/animation/animation.py`](https://github.com/3b1b/manim/blob/main/manimlib/animation/animation.py) provides the lifecycle for every animation. It handles initialization, the start of the animation, frame-by-frame updates, and cleanup. When you subclass `Animation`, you inherit this machinery and only need to specify how the visual state changes.

### Core Lifecycle Methods

The base class defines several key methods that orchestrate the animation:

- **`begin()`**: Captures the starting state of the mobject by creating copies of submobjects.
- **`interpolate(alpha)`**: The main entry point called by `Scene.play`. It converts linear time `alpha` (0 to 1) through the rate function, then calls `interpolate_mobject`.
- **`interpolate_mobject(alpha)`**: Iterates over submobject pairs and calls `interpolate_submobject`.
- **`interpolate_submobject(submobject, starting_submobject, alpha)`**: **This is the method you must override.** It receives the eased alpha value and defines how the submobject transforms from its starting state.

### The Role of Rate Functions

Rate functions control the pacing of the animation. They are callables that map linear time `t ∈ [0, 1]` to eased progress. The `Animation` class stores the rate function and applies it before passing the value to interpolation methods.

Built-in rate functions live in [`manimlib/utils/rate_functions.py`](https://github.com/3b1b/manim/blob/main/manimlib/utils/rate_functions.py) and include:

- **`linear`**: Constant velocity.
- **`smooth`**: S-curve ease-in-out (default).
- **`overshoot`**: Moves past the target and settles back.
- **`there_and_back`**: Moves to target and returns to start.
- **`wiggle`**: Oscillates around the target.

You can pass these to your animation via the `rate_func` parameter or define custom lambdas like `lambda t: t**2` for quadratic ease-in.

## How to Subclass Animation for Custom Effects

To create a custom animation, you create a class inheriting from `Animation` and implement the transformation logic in `interpolate_submobject`.

### Override interpolate_submobject

This method receives three arguments:

1. `submobject`: The current submobject being animated.
2. `starting_submobject`: The copy of the submobject as it existed at the start.
3. `alpha`: The eased time value (already processed by the rate function).

You use `alpha` to interpolate between the starting state and target state. For example, to fade in, you might set `submobject.set_opacity(alpha)`.

### Working with lag_ratio for Staggered Effects

The `lag_ratio` parameter (default 0) controls the delay between submobjects. When `lag_ratio > 0`, each submobject starts animating after the previous one has progressed by that fraction. This is handled automatically by `get_sub_alpha` in the base class, which adjusts the alpha for each submobject based on its index.

## Defining Custom Rate Functions

Custom rate functions are plain Python callables that take a float `t` from 0 to 1 and return a float. You can combine existing functions or write mathematical transformations.

For example, to create a bounce effect:

```python
def bounce(t):
    return t * (1 - t) * 4  # Parabolic arc peaking at t=0.5

```

Pass this to your animation: `MyAnimation(mobj, rate_func=bounce)`.

## Complete Code Examples

### Example 1: Pulse Animation with Overshoot

This custom animation scales a mobject up and back down, using the `overshoot` rate function to create a bouncing effect.

```python
from manimlib.animation.animation import Animation
from manimlib.utils.rate_functions import overshoot

class Pulse(Animation):
    """Scale a mobject up then back to its original size."""
    def __init__(self, mobject, scale_factor=1.5, **kwargs):
        super().__init__(mobject, **kwargs)
        self.scale_factor = scale_factor
        # Store the original dimensions for reference

        self.original_width = mobject.width
        self.original_height = mobject.height

    def interpolate_submobject(self, mob, start_mob, alpha):
        # alpha is already eased by the chosen rate function

        # Interpolate between 1 and the target scale_factor

        new_scale = 1 + (self.scale_factor - 1) * alpha
        mob.scale_to_fit_width(self.original_width * new_scale)
        mob.scale_to_fit_height(self.original_height * new_scale)

# Usage in a scene

class Demo(Scene):
    def construct(self):
        circle = Circle()
        self.play(Pulse(circle, rate_func=overshoot, run_time=2))

```

*Source references:* `Animation` class – [`manimlib/animation/animation.py`](https://github.com/3b1b/manim/blob/main/manimlib/animation/animation.py); `overshoot` rate function – [`manimlib/utils/rate_functions.py`](https://github.com/3b1b/manim/blob/main/manimlib/utils/rate_functions.py).

### Example 2: Wiggle Animation with Custom Rate Function

This example defines a custom rate function that combines `there_and_back` with a sine wave to create a wiggling motion.

```python
import numpy as np
from manimlib.animation.animation import Animation
from manimlib.utils.rate_functions import there_and_back

def wiggle_rate(t, wiggles=3):
    """Wiggle back-and-forth `wiggles` times over the interval."""
    return there_and_back(t) * np.sin(wiggles * np.pi * t)

class Wiggle(Animation):
    def __init__(self, mobject, amplitude=0.2, **kwargs):
        super().__init__(mobject, **kwargs)
        self.amplitude = amplitude

    def interpolate_submobject(self, mob, start_mob, alpha):
        # Apply a sinusoidal horizontal shift based on the eased alpha

        shift = self.amplitude * np.sin(alpha * np.pi * 2)
        mob.shift(shift * RIGHT)

# In a scene

class WiggleDemo(Scene):
    def construct(self):
        square = Square()
        self.play(Wiggle(square, rate_func=lambda t: wiggle_rate(t, wiggles=5),
                         run_time=3))

```

### Example 3: Staggered Fade-In with Lag Ratio

This animation demonstrates how to use `lag_ratio` to create a staggered entrance effect where submobjects fade in sequentially.

```python
class StaggeredFadeIn(Animation):
    def __init__(self, mobject, **kwargs):
        super().__init__(mobject, lag_ratio=0.2, **kwargs)

    def interpolate_submobject(self, mob, start_mob, alpha):
        mob.set_opacity(alpha)   # Fade each sub-mobject according to its lagged alpha

# Use on a VGroup

class StaggerDemo(Scene):
    def construct(self):
        dots = VGroup(*[Dot() for _ in range(8)]).arrange(RIGHT, buff=0.5)
        self.play(StaggeredFadeIn(dots, run_time=2))

```

## Summary

- **Subclass `Animation`** from [`manimlib/animation/animation.py`](https://github.com/3b1b/manim/blob/main/manimlib/animation/animation.py) to create custom visual effects.
- **Override `interpolate_submobject`** to define how individual submobjects transform from their starting state to target state using the eased `alpha` parameter.
- **Use rate functions** from [`manimlib/utils/rate_functions.py`](https://github.com/3b1b/manim/blob/main/manimlib/utils/rate_functions.py) or define custom callables to control easing, acceleration, and deceleration.
- **Leverage `lag_ratio`** to create staggered animations where submobjects animate sequentially rather than simultaneously.
- **Store initial state** in `__init__` or `begin()` to ensure smooth interpolation during the animation lifecycle.

## Frequently Asked Questions

### What is the difference between `interpolate` and `interpolate_submobject` in Manim?

The `interpolate` method is the high-level entry point called by `Scene.play` with a linear time value. It applies the rate function to convert that time to an eased alpha value, then calls `interpolate_mobject`. The `interpolate_submobject` method is the specific hook you override to define how a single submobject changes given that eased alpha. According to the source in [`manimlib/animation/animation.py`](https://github.com/3b1b/manim/blob/main/manimlib/animation/animation.py), `interpolate_submobject` receives the current submobject, its starting copy, and the eased alpha value.

### How do I make a custom animation work with VGroups and submobjects?

When animating a `VGroup` or any compound mobject, Manim automatically iterates over submobjects and calls your `interpolate_submobject` for each one. To handle this properly, ensure your interpolation logic operates on the individual `mob` parameter rather than assuming a single mobject. If you need to access the original group structure, store references in `__init__` before the base class initialization copies the starting mobject. The `lag_ratio` parameter in [`manimlib/animation/animation.py`](https://github.com/3b1b/manim/blob/main/manimlib/animation/animation.py) controls the delay between submobjects, creating staggered effects automatically.

### Can I combine multiple custom animations to play simultaneously?

Yes, you can play multiple custom animations at once by passing them as separate arguments to `self.play()` in your scene, or by using `AnimationGroup` from [`manimlib/animation/composition.py`](https://github.com/3b1b/manim/blob/main/manimlib/animation/composition.py). When passing multiple animations to `Scene.play`, Manim synchronizes their timing so they start together. If you need more complex coordination, wrap your custom animations in an `AnimationGroup` with `lag_ratio` to stagger them, or use `Succession` to play them sequentially. Each animation maintains its own rate function and duration independently within the group.

### Where are the built-in rate functions defined in the Manim source code?

The built-in rate functions are defined in [`manimlib/utils/rate_functions.py`](https://github.com/3b1b/manim/blob/main/manimlib/utils/rate_functions.py). This module contains standard easing functions including `linear`, `smooth`, `overshoot`, `there_and_back`, and `wiggle`. Each function accepts a float `t` in the range [0, 1] and returns an eased float. You can import these directly or use them as templates for creating custom rate functions. The `smooth` function is the default used by the `Animation` class when no `rate_func` is specified.