In order to draw custom shapes and lines in Flutter, there are basically four things involved:

CustomPaint (It’s the exhibitor who gives you a paper to draw on, and then exhibits what you have drawn) 🖼️ CustomPainter (It’s you! The painter!) 👨‍🎨 Paint (It’s your brush) 🎨🖌️ Canvas (It’s your paper) ⬜

Yes, it’s that simple!

So let’s get started by creating our main file:

The drawing will happen in the DrawingPage class:

As usual, our page starts with Scaffold which has an appBar and a body which is set to an instance of CustomPaint widget.

The canvas is created and provided to you by the CustomPaint widget which has three important properties:

painter : This is an instance of the CustomPainter class which draws the first layer of your painting on the canvas. child : You can set this to any widget you want. After the painter is done with painting, the child widget is shown on top of the painting. foregroundPaint : Finally, this paint is drawn on top of the two previous layers.

As I said, the CustomPaint object creates the canvas and gives it to the painter and foregroundPaint objects so that they can draw on it.

The Size of the Canvas

But what will be the size of the canvas? The same size as the whole of the screen? Half of the screen? or what?

The CustomPaint object creates a canvas the same size as the size of the child parameter. If the child parameter is not provided (yes, that’s optional), the canvas size is determined by the size parameter that you can provide to CustomPaint object when instantiating it.

In our example, the child is a Center widget which is as big as the screen. Therefore, our canvas will be as big as the whole screen too!

If you are wondering why the Center widget is as big as the whole screen, you can read this article I recently wrote about the Center widget: Understanding Center Widget in Flutter

The upper left corner of the canvas is called origin. It’s the point with (0, 0) coordinates. The coordinates of the lower right corner of the canvas are (size.width, size.height) :

The Canvas Coordinates

The Painter

The painter parameter is of type CustomPainter .

This simply means that your painter class (that we are going to create) must extend the CustomPainter class.

You would usually name your CustomPainter class according to what it’s going to paint. If it’s going to paint a sky, name it SkyPainter. If it’s going to draw a face, name it FacePainter. If you are going to draw a gun 🔫 make sure you read this first:

If a person has to engage in gun drawing, one had better be sure that they do so in the right situation. There are circumstances in which it isn’t legal to draw a firearm. Continue reading at: http://gunbelts.com/blog/when-is-drawing-your-gun-legal/

😜

Since I mainly intend to draw a dashed curved line on the canvas, I’d like to name my painter “CurvePainter”:

As you see, my painter has extended the CustomPainter class.

The CustomPainter class has two important functions to override:

paint : The actual painting happens here. Did you notice the two parameters provided to this function? In this function, you have access to the canvas object which is indeed your paper, and also the size of the canvas on which you are going to draw. shouldRepaint : In this function, you should either return true or false . If your painting depends on a variable and that variable changes, you return true here, so that Flutter knows that it has to call the paint method to repaint your painting. Otherwise, return false here to indicate you don’t need a redraw.

Drawing Lines and Shapes

Now everything is ready for you to start drawing. The canvas is ready and we know its size .

The canvas object provided to you has several helper functions that will help you draw something, to name a few:

drawLine(Offset p1, Offset p2, Paint paint)

Draws a line from point 1 to point 2, with the given paint.

drawCircle(Offset c, double radius, Paint paint)

Draws a circle centered at the point given that has the radius given by the second argument, with the paint given in the third argument.

drawPath(Path path, Paint paint)

Draws the given path with the given paint .

moveTo(double x, double y)

Before you start drawing, your pen is by default on the origin point i.e. the top-left corner of the canvas. You can move your pen though, before starting to draw, with this function.