Open In App

Flutter – Wave Animation

Last Updated : 19 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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();
  }
}


Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads