Flutter – Wave Animation
In this article, we are going to make a Flutter application that demonstrates the creation of a dynamic wave animation. This animation simulates the motion of water waves, creating an engaging visual effect that can be used in various Flutter applications to add styling effects. A sample video is given below to get an idea about what we are going to do in this article.
Step By Step Implementation
Step 1: Create a New Project in Android Studio
To set up Flutter Development on Android Studio please refer to Android Studio Setup for Flutter Development, and then create a new project in Android Studio please refer to Creating a Simple Application in Flutter.
Step 2: Import the Package
First of all import material.dart file.
import 'dart:math';
import 'package:flutter/material.dart';
Step 3: Execute the main Method
Here the execution of our app starts.
Dart
void main() { runApp(MyApp()); } |
Step 4: Create MyApp Class
In this class we are going to implement the MaterialApp and the Scaffold , here we are also set the Theme of our App.
Dart
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( primarySwatch: Colors.green, // Set the app's primary theme color ), debugShowCheckedModeBanner: false , home: Scaffold( appBar: AppBar( title: Text( 'Wave Animation Example' ), // Title for the app bar ), body: WaveAnimation(), ), ); } } |
Step 5: Create WaveAnimation Class
The WaveAnimation class sets up and controls a wave-like animation that continuously moves back and forth across the screen. Comments are added for better understanding.
Dart
class WaveAnimation extends StatefulWidget { @override _WaveAnimationState createState() => _WaveAnimationState(); } class _WaveAnimationState extends State<WaveAnimation> with SingleTickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( vsync: this , // Synchronize animation with this widget duration: Duration(seconds: 2), // Animation duration )..repeat(reverse: true ); // Repeat the animation back and forth } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, child) { return CustomPaint( size: Size( MediaQuery.of(context).size.width, MediaQuery.of(context) .size .height), // Set the size of the custom paint painter: WavePainter( _controller.value), // Use the WavePainter to paint the wave ); }, ); } @override void dispose() { _controller.dispose(); // Dispose of the animation controller super.dispose(); } } |
Step 6: Create WavePainter Class
The WavePainter class is responsible for defining how the wave animation is drawn on the canvas.Comments are added for better understanding.
Dart
class WavePainter extends CustomPainter { final double animationValue; // Animation value to control the wave height WavePainter( this .animationValue); @override void paint(Canvas canvas, Size size) { final paintGreen = Paint() ..color = Colors.green // Green color for the wave ..style = PaintingStyle.fill; // Filling the wave final pathGreen = Path(); pathGreen.moveTo(0, size.height); pathGreen.lineTo(0, size.height * 0.6); // Starting point for the wave for (var i = 0; i < size.width; i++) { final x = i.toDouble(); final y = size.height * 0.56 + animationValue * 30 * sin ((i / size.width) * 3 * pi); // Calculate wave shape pathGreen.lineTo(x, y); // Define wave path } pathGreen.lineTo(size.width, size.height); // Complete the wave path pathGreen.close(); canvas.drawPath(pathGreen, paintGreen); // Draw the green wave } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true ; // Repaint the wave continuously } } |
Here is the full Code of main.dart file
Dart
import 'dart:math' ; import 'package:flutter/material.dart' ; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( primarySwatch: Colors.green, // Set the app's primary theme color ), debugShowCheckedModeBanner: false , home: Scaffold( appBar: AppBar( title: Text( 'Wave Animation Example' ), // Title for the app bar ), body: WaveAnimation(), ), ); } } class WavePainter extends CustomPainter { final double animationValue; // Animation value to control the wave height WavePainter( this .animationValue); @override void paint(Canvas canvas, Size size) { final paintGreen = Paint() ..color = Colors.green // Green color for the wave ..style = PaintingStyle.fill; // Filling the wave final pathGreen = Path(); pathGreen.moveTo(0, size.height); pathGreen.lineTo(0, size.height * 0.6); // Starting point for the wave for (var i = 0; i < size.width; i++) { final x = i.toDouble(); final y = size.height * 0.56 + animationValue * 30 * sin ((i / size.width) * 3 * pi); // Calculate wave shape pathGreen.lineTo(x, y); // Define wave path } pathGreen.lineTo(size.width, size.height); // Complete the wave path pathGreen.close(); canvas.drawPath(pathGreen, paintGreen); // Draw the green wave } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true ; // Repaint the wave continuously } } class WaveAnimation extends StatefulWidget { @override _WaveAnimationState createState() => _WaveAnimationState(); } class _WaveAnimationState extends State<WaveAnimation> with SingleTickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( vsync: this , // Synchronize animation with this widget duration: Duration(seconds: 2), // Animation duration )..repeat(reverse: true ); // Repeat the animation back and forth } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, child) { return CustomPaint( size: Size( MediaQuery.of(context).size.width, MediaQuery.of(context) .size .height), // Set the size of the custom paint painter: WavePainter( _controller.value), // Use the WavePainter to paint the wave ); }, ); } @override void dispose() { _controller.dispose(); // Dispose of the animation controller super.dispose(); } } |