Ripple Animation in Flutter a Simple app[ Task 6 ]
Well-designed animations make a UI feel more intuitive, contribute to the slick look and feel of a polished app, and improve the user experience. Flutter’s animation support makes it easy to implement a variety of animation types. Many widgets, especially Material widgets, come with the standard motion effects defined in their design spec, but it’s also possible to customize these effects.
Choosing an approach
There are different approaches you can take when creating animations in Flutter. Which approach is right for you?
Animation types
Generally, animations are either ripple- or physics-based. The following sections explain what these terms mean, and point you to resources where you can learn more.
Code Implementation:
First, create a class that will be landing page of the module, also known as RippleAnimation class.
So, let me walk you through the code to give a better understanding of what’s happening here. As you can see, the UI we’re going to achieve so accordingly, I created a class RippleAnimation that contains the code for the UI. There are two main elements, the Custom Paint and the widget button animation.
Let’s declare the core of the App, CirclPainter
class.
import 'package:flutter/material.dart';
import 'dart:math' as math show sin, pi, sqrt;
import 'package:flutter/animation.dart';class CirclePainter extends CustomPainter {
CirclePainter(
this._animation, {
@required this.color,
}) : super(repaint: _animation);
final Color color;
final Animation<double> _animation;
void circle(Canvas canvas, Rect rect, double value) {
final double opacity = (1.0 - (value / 4.0)).clamp(0.0, 1.0);
final Color _color = color.withOpacity(opacity);
final double size = rect.width / 2;
final double area = size * size;
final double radius = math.sqrt(area * value / 4);
final Paint paint = Paint()..color = _color;
canvas.drawCircle(rect.center, radius, paint);
}
@override
void paint(Canvas canvas, Size size) {
final Rect rect = Rect.fromLTRB(0.0, 0.0, size.width, size.height);
for (int wave = 3; wave >= 0; wave--) {
circle(canvas, rect, wave + _animation.value);
}
}
@override
bool shouldRepaint(CirclePainter oldDelegate) => true;
}
CirclePainter
extends the class CustomPainter
and we need to override its paint
method to draw the graphics. To draw, from the start, we need to announce something called Paint, it typifies all the properties that are expected to draw something on the screen.
final Paint paint = Paint()..color = _color;
In this Paint, we will add color, style, stroke width, etc., and you will also add a stroke cap.
final double opacity = (1.0 - (value / 4.0)).clamp(0.0, 1.0);
final Color _color = color.withOpacity(opacity);
final double size = rect.width / 2;
final double area = size * size;
final double radius = math.sqrt(area * value / 4);
In these five lines, we calculate the directions for the center of the circle and the double opacity
, It is 1.0 minus with bracket value was divided by 4. Add color with opacity. We need the center of the circles exactly in the middle. double size
It is half of the width.double area
It is size was multiply by size.double radius
It is the math square of the area multiply by value divided by 4.
canvas.drawCircle(rect.center, radius, paint);
Now we just draw with the drawCircle function called on the provided canvas object, where we go in the center, the radius, and the Paint object.
@override
void paint(Canvas canvas, Size size) {
final Rect rect = Rect.fromLTRB(0.0, 0.0, size.width, size.height);
for (int wave = 3; wave >= 0; wave--) {
circle(canvas, rect, wave + _animation.value);
}
}
In the paint method, we will add the size of the Rect from the left, top, right, and bottom. Then we will add wave
in the form of circle function, where we go in the canvas, the rect, and wave with animation value.
Now, let add the animations.
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 2000),
vsync: this,
)..repeat();
}
We add the animation on the Ripple Animation screen in the initState() method. Then, we have added a AnimationController
which is called at each step of the animation. We will add duration 2000 milliseconds, and we will use the Animationcontroller in the Button widget function.
Widget _button() {
return Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(widget.size),
child: DecoratedBox(
decoration: BoxDecoration(
gradient: RadialGradient(
colors: <Color>[
widget.color,
Color.lerp(widget.color, Colors.black, .05)
],
),
),
child: ScaleTransition(
scale: Tween(begin: 0.95, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: const CurveWave(),
),
),
child: Icon(Icons.speaker_phone, size: 44,)
),
),
),
);
}
In this button widget, we will use RadialGradient and add color with lerp function. In this child property, we will add ScaleTransition
effect for the animation.
scale: Tween(begin: 0.95, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: const CurveWave(),
),
),
The following code makes a tween begin with 0.95 and ends at 1.0 for the scale property. It constructs a CurvedAnimation, determining a CurveWave() curve. See Curves for other accessible pre-characterized animation Curves.
import 'package:flutter/material.dart';
import 'dart:math' as math show sin, pi;
import 'package:flutter/animation.dart';class CurveWave extends Curve {
const PulsateCurve();
@override
double transform(double t) {
if (t == 0 || t == 1) {
return 0.01;
}
return math.sin(t * math.pi);
}
}
CurveWave()
Extends the class Curve
and we will “t” transform the curve with a return value.