Docs
Guides
How to create animation using Mix

How to Create Animations Using Mix

In this guide, we will learn how to create animations using Mix. First, we need to understand how Mix styles work. All stylizations begin with the Style class.

Style Class

The Style class is a container for all the stylizations you want to apply to a widget. You can add multiple stylizations to a Style object and then apply it to a widget. For example, we will create a red, rounded container.

Box(
    style: Style(
        $box.height(50),
        $box.width(50),
        $box.color(Colors.red),
        $box.borderRadius(10),
    ),
);

At this point, we have a red, rounded container. If you have any experience with Mix, this concept is not new to you. Now, let's see how we can animate this container.

AnimatedStyle Class

The AnimatedStyle class is a subclass of Style that allows you to animate the stylizations based on differences between two Style objects, applied using variants. To show how it works, let's create a simple animation that changes the color and size of the container when the user taps on it.

PressableBox(
    onPress: () => {
        // This function will be triggered when the box is pressed.
    },
    child: Box(
        style: AnimatedStyle(
            Style(
                $box.height(50),
                $box.width(50),
                $box.color(Colors.blue),
                $box.borderRadius(10),
                $on.hover(
                    $box.height(100),
                    $box.width(100),
                    $box.color(Colors.red),
                ),
            ),
            duration: Durations.long1,
            curve: Curves.decelerate,
        ),
    ),
);

Simplifying Animation with animate()

The Style class provides a method animate() that simplifies the creation of animations by returning an AnimatedStyle from the current Style with specified duration and curve. This method allows for more concise and readable code when animating widgets.

Example of animate()

Let's modify our initial red, rounded container example to animate its size on press using the animate() method:

PressableBox(
    onPress: () => {
        // Action to perform when the box is pressed.
    },
    child: Box(
        style: Style(
            $box.height(100),
            $box.width(100),
            $box.color(Colors.red),
            $box.borderRadius(20),
        ).animate(
            duration: Durations.long1,
            curve: Curves.linear,
        )
    ),
);

Note that, different from the Style class, the AnimatedStyle class receives, besides the style, the duration and curve parameters. The duration parameter specifies the time the animation will take to complete, and the curve parameter determines the path the animation will follow.

Start Point and End Point

An important thing to keep in mind is that animations will only work if you define a start point for each attribute. Without a start point, the animation will not proceed.

Don't

In the example below, the animation will not work because we didn't define a start point for the $box.color attribute.

PressableBox(
    onPress: () => {
        // Intended action when the box is pressed.
    },
    child: Box(
        style: AnimatedStyle(
            Style(
                $box.height(50),
                $box.width(50),
                $on.hover(
                    $box.color(Colors.blue),
                ),
            ),
            duration: Durations.long1,
            curve: Curves.decelerate,
        ),
    ),
);

Do

Unlike the previous example, the animation will work because we defined a start point for the $box.color attribute.

PressableBox(
    onPress: () => {
        // Action to perform when the box is pressed.
    },
    child: Box(
        style: AnimatedStyle(
            Style(
                $box.height(50),
                $box.width(50),
                $box.color(Colors.red),
                $on.hover(
                    $box.color(Colors.blue),
                ),
            ),
            duration: Durations.long1,
            curve: Curves.decelerate,
        ),
    ),
);