For today’s article I prepared a stunning animation that gives your Flutter app a lot attention. Moreover I want to to show how easy it to implement with the Flutter and the package simple_animations.
The animation consists of a background gradient with a smooth transition. Below there are multiple waves sliding from right to left. On top there is some content. In this case a text that’s greeting you. Hello!
Let’s start with the background gradient. We use Flutter’s build-in BoxDecoration to apply a LinearGradient like this:
colors: [color1, color2])),
We just need to animate it. And that’s very simple thanks to the simple_animations Flutter package. We use MultiTrackTween (an Animatable to arrange the tweening of multiple properties at once) in combination with ControlledAnimation (a widget to very simple run tween-based animations without overhead).
We define two tracks for color1 and color2 and use them in a mirrored animation. Look how simple it is, we don’t even touched any StatefulWidgets or AnimationControllers. You can take this code as a template and extend it with more complex color transitions. :-)
Now we have a smoothly fading background. Let’s add some beautiful waves that animates really awesome. Take a look how we achieve this:
These are actually three single waves that are overlaying each other. We need to assure that they differ from each other to create the wave illusion. So we need properties for a WaveAnimation widget:
- speed: to control the animation duration of a wave pass
- height: to set the area in which the wave acts
- offset: a shift in the x-axis to give a wave different “start position”
Next we need to cover some math. Every time you like to have something periodical in combination circular there should one answer: trigonometric functions.
For our animation we animate a value from 0.0 to 2*pi and put that value into a sine function. We sample y-values on three positions: the left side, the middle and the end. From left to right we cover an interval of one pi, so we can always see the half of one whole sine wave.
Why do we sample three positions? We will draw a path! And I made a visualization for you:
We start our path top left (purple) and line a quadratic bézier function to the right top (red). It’s a build in path-method of Flutter’s Canvas. It expects us to specify a “control point” (green). Then we go straight down to bottom right (orange) and straight to left bottom (yellow). Finally we close the path so it connects with the start point (purple).
When you just focus on the purple, green and red dots, you can see our sampled positions and it’s sine wave magic behind it.
Quadratic bézier functions might seem spooky at first moment. But he just tries to draw a straight line (blue) from purple to red. And the more it reaches the green dot, some kind of gravity effects the actual line (grey shape). As the result, the line getting softly bend over. That’s all.
Now that we have solved the math, we can put it inside a widget:
For the widget part we need a LayoutBuilder to retrieve the available width to paint on. Then we utilize a ControlledAnimation (from flutter_animation) with
Playback.LOOP and a simple tween from 0.0 to 2*pi. We animate a Canvas that passes the current animation value to a CustomPainter.
The CustomPainter simply draws our path, that we discussed earlier. Note that we use a color with reduced opacity, so the multiple waves are always visible.
Quite less code for a cool animation, ain’t?
Finally we put everything together. I am using a Stack widget and first put in the gradient background, followed by multiple wave animations. Last the content of the app: a text in my example.
Now we have our fancy background animation ready for production. ;-)