Drawing Rectangles on Canvas in Flutter

The canvas API in Flutter provides great freedom for drawing shapes, text, and images directly on the screen when creating bespoke user interfaces. The rectangle is one of the most typical shapes you’ll come across in a lot of applications. This blog post will cover every aspect of drawing rectangles on a canvas with Flutter, from the fundamentals to more complex applications.

With Flutter’s canvas, developers have total control over the rendering of their widgets thanks to a low-level interface for drawing directly on the screen. We will dissect how to create a rectangle, work with its properties, and include it into a Flutter application in this tutorial.

1. Introduction to Flutter Canvas

Canvas in Flutter is a versatile drawing surface that can handle all kinds of shapes and paths. The Canvas class provides a set of methods that allow developers to draw primitives such as lines, rectangles, circles, arcs, images, and even custom paths. This makes it perfect for highly customized UI elements or dynamic, programmatic drawing. We can also create circle canvas in flutter details.

The CustomPaint widget is Flutter’s tool for drawing on the canvas. It requires the creation of a CustomPainter, which is responsible for defining the painting logic. For drawing a rectangle, we’ll leverage the drawRect method provided by the Canvas class.

2. Setting up the Canvas in Flutter

Before you start drawing rectangles, it’s important to know how to set up a basic canvas. The following steps outline how to get started with drawing on the canvas in Flutter:

  • First, you need to create a new Flutter project, or add a custom drawing functionality to an existing one.
  • Next, use the CustomPaint widget to draw on the canvas.

Basic Structure of a CustomPainter:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Canvas Draw Rectangle')),
        body: Center(
          child: CustomPaint(
            size: Size(300, 300),
            painter: RectanglePainter(),
          ),
        ),
      ),
    );
  }
}

class RectanglePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // This is where we’ll draw the rectangle
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

3. Drawing a Simple Rectangle

The Canvas class in Flutter has a method called drawRect, which takes two parameters:

  1. A Rect object that defines the coordinates and size of the rectangle.
  2. A Paint object that defines how the rectangle should be rendered, including its color, stroke width, style (fill or stroke), and more.

Drawing a Basic Rectangle:

class RectanglePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue // The color of the rectangle
      ..style = PaintingStyle.fill; // Fill the rectangle

    // Define the rectangle's bounds (x, y, width, height)
    final rect = Rect.fromLTWH(50, 50, 200, 100);

    // Draw the rectangle on the canvas
    canvas.drawRect(rect, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

In the above code, we created a simple blue rectangle located at (50, 50) with a width of 200 and a height of 100. The PaintingStyle.fill style ensures that the rectangle is filled with the specified color.

4. Customizing the Rectangle

Now that you can draw a basic rectangle, it’s time to explore how to customize it to suit your design needs.

a. Changing the Color

To change the rectangle’s color, modify the color property in the Paint object. You can choose any color from the Colors class or define your own custom colors.

paint.color = Colors.red; // Change rectangle color to red

b. Adding a Border (Stroke Style)

You can also draw the rectangle’s border using PaintingStyle.stroke instead of PaintingStyle.fill. You can combine both styles to have a filled rectangle with a border.

final paint = Paint()
  ..color = Colors.green
  ..style = PaintingStyle.stroke // Draw the rectangle border
  ..strokeWidth = 4.0; // Thickness of the border

c. Drawing Rounded Corners

If you want your rectangle to have rounded corners, you’ll need to use RRect, which stands for rounded rectangle. The RRect.fromRectAndRadius method allows you to specify the corner radius for each corner.

final roundedRect = RRect.fromRectAndRadius(
  Rect.fromLTWH(50, 50, 200, 100),
  Radius.circular(16),
);

canvas.drawRRect(roundedRect, paint);

In this example, the rectangle has rounded corners with a radius of 16 units.

5. Animating the Rectangle

Flutter makes it easy to add animations to your drawings. Using the AnimationController and Tween, you can animate the size, position, or color of your rectangle.

Here’s an example of how you could animate the size of the rectangle:

class AnimatedRectanglePainter extends CustomPainter {
  final double width;

  AnimatedRectanglePainter(this.width);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;

    final rect = Rect.fromLTWH(50, 50, width, 100);
    canvas.drawRect(rect, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

class AnimatedRectangle extends StatefulWidget {
  @override
  _AnimatedRectangleState createState() => _AnimatedRectangleState();
}

class _AnimatedRectangleState extends State<AnimatedRectangle> with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );

    _animation = Tween<double>(begin: 0, end: 200).animate(_controller)
      ..addListener(() {
        setState(() {});
      });

    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(300, 300),
      painter: AnimatedRectanglePainter(_animation.value),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

In this example, we animate the width of the rectangle from 0 to 200 units over two seconds.

6. Real-world Examples and Use Cases

Rectangles are fundamental in many UI elements. Here are a few examples of how they can be used in real-world applications:

  • Progress bars: A rectangle can be used to represent the progress in a progress bar.
  • Custom buttons: You can draw rectangles to create custom buttons with various styles, including rounded corners or gradient fills.
  • Chart bars: Rectangles are perfect for drawing bar charts where each bar represents data.
  • Background decorations: Rectangles can be used as background shapes in custom UI designs, such as cards or container decorations.

7. Conclusion

Drawing rectangles on a canvas in Flutter offers you immense flexibility and creativity when building custom UIs. From simple filled rectangles to advanced animations and real-world use cases, rectangles form the building blocks of many applications. With the knowledge from this tutorial, you can start creating rich, interactive UIs by leveraging Flutter’s canvas drawing capabilities.