Implementing Motion Design with Flutter

Most of the time implementing motion design is a bit cumbersome on mobile application. This article illustrates how motion design can be achieved with flutter in more pragmatic way. We’ll take on a simple motion design from dribble as a reference and start building it step by step. All copyright is reserved to the respective author and full source code for the implementation is available at github.

Original Design

For now we’ll focus on login/signup interaction and try to break it down into multiple scenes so we can have a clear overall idea and chain those scenes together.

Scene 1 : Initial State Screen

In this scene, we have a bouncing image and text at the bottom, a curved white background, a branding title surrounded by image in the center and amoeba shapes in the background. Upon dragging the bottom content till a certain distance is covered, a reveal animation is played and the scene transits to next scene.

Reveal Animation (Intermediate Scene)

In this intermediate scene, the curve background height is animated. Also during this animation, the control point of the cubic bezier curve is also translated and reverted back to give accelerated effect. The side icons and amoeba background are also translated up in the vertical direction in response to the reveal animation.

Scene 2: Post Reveal Animation State Screen

After reveal animation is competed, the brand title is replaced by a circular icon, a tab indicator flies in from the left side of the screen and corresponding tabs are loaded.

Now we have overview of related scenes involved in the design. Next step, we try to map these ideas into implementation detail. So let’s get started.

We’ll be using stack as top level container to host all our scenes and depending on current scene state, we’ll add respective widgets to the stack and animate their geometry.

For scene 1, all corresponding widgets are positioned and added to the stack. The bouncing effect for the bottom “Swipe up to start” widget is also started immediately.

To achieve dragging behavior of this widget, a scrollable widget is also placed on top, covering bottom half of the screen. The “Swipe up to start” is also translated on the basis of the drag distance and upon crossing the threshold (70% of the height of scrollable widget), the reveal animation is played.

In reveal animation, a CustomPainter is used to draw the curved background and amoeba background. While animating, both the height as well as the mid control point of curved background is interpolated to cover almost 75% of the screen height. Similarly the amoeba which is also drawn using bezier curve is translated up vertically.

After completing the reveal animation, the scene 2 is set. In this scene the brand title is replaced by icon and the tab indicator flies in from the left side of the screen.

The tab indicator is also drawn using Bezier curve and positioned just above the curved background from scene 1 but in separate CustomPainter. To achieve the tab selection effect, clip path is used while drawing the tab selection curve.

In addition to that, two containers are positioned on top of each other with respective tab color. On the basis of selected tab, corresponding container is kept and other one is discarded by translating to the opposite end in the x axis.

Since I couldn’t get the exact images and assets, I used the closest one that I could find online.

So overall we get the result as below.

Do checkout the source code and give a star if you like it. :)

Software Engineer from Kathmandu