Directory portal:A Guide to The Quick Start to Flutter

Through the previous 3:

  • 25.Flutter: Become a Canvas Master (I)

  • 26.Flutter: Become a Canvas Master (II)

  • 27.Flutter: Become a Canvas Master (III)

Now that you have mastered the basic drawing operations of Flutter, this section will cover Canvas transformations.

Save (), saveLayer(), and restore()

To get started on Canvas transformation operations, take a look at Canvas save(), saveLayer(), and restore().

You’re going to need them a lot when you’re doing transformations.

save()

The save() operation saves all the previously drawn content and Canvas state.

The draw and transform operations after the call are re-recorded.

When you call restore(), it merges what happened between save() and restore() with what happened before.

โš ๏ธ Note that save() does not create a new layer, unlike saveLayer().

saveLayer()

SaveLayer () looks about the same as save() in most cases.

The difference is that saveLayer() creates a new layer.

The operations between saveLayer() and restore() are performed on a new layer, although eventually they will be combined.

Take a look at the two arguments to saveLayer() :

  • rect

    Rect, used to set the scope area of the new layer.

    Your drawing operation will only work within this area, and anything beyond this area will be ignored.

    ๐ŸŒฐ e.g. :

    canvas.saveLayer(Rect.fromCircle( center: Offset(size.width / 2, size.height / 2), radius: 100), paint); DrawPaint (Paint().. // Fill the entire canvas area with color. color = Colors.blue); DrawRect (rect.fromltwh (0, 0, 100, 100), Paint().. drawRect(rect.fromltwh (0, 0, 100, 100), Paint()... color = Colors.red); canvas.restore();Copy the code

    ๐Ÿ–ผ effect:

    From this example, you can see that the new layer is drawn within the recT range.

  • paint

    Paint, with its ColorFilters and BlendMode Settings, takes effect when the layers are compositing.

    The preceding layer is DST and this layer is SRC.

    ๐ŸŒฐ e.g. :

    canvas.saveLayer(Rect.fromCircle( center: Offset(size.width / 2, size.height / 2), radius: 60), Paint().. color = Colors.red); canvas.drawPaint(Paint().. color = Colors.amber); canvas.restore();Copy the code

    ๐Ÿ–ผ effect:

    The previous layer draws an image. On the new layer, a rectangle is drawn.

    If Paint does not set the blending parameters, the new layer will simply be on top of the previous layer.

    โš ๏ธ Note that the color must be set in the incoming Paint, otherwise the recT limits you set will be invalid!

    If Paint is set to BlendMode, see how it looks.

    canvas.saveLayer(Rect.fromCircle( center: Offset(size.width / 2, size.height / 2), radius: 60), Paint() .. color=Colors.red .. blendMode=BlendMode.exclusion);Copy the code

    ๐Ÿ–ผ effect:

    As you can see, the new layer is mixed with the pixels of the previous content.

    ๐Ÿ’ก note that BlendMode supports all the blending effects, can refer to the BlendMode API.

restore()

Reading this, you’ll be familiar with Restore ().

Save () or saveLayer() must be synthesized by calling restore(), otherwise Flutter will throw an exception.

It is worth noting that each save() or saveLayer() must have a corresponding restore().

๐ŸŒฐ e.g. :

// save-1 canvas.save(); . // save-2 canvas.saveLayer(dstRect, paint); . // save-3 canvas.saveLayer(dstRect, paint); . // restore-3 canvas.restore(); // restore-2 canvas.restore(); // restore-1 canvas.restore();Copy the code

Restore () is synthesized from its nearest save() or saveLayer() operation.

โš ๏ธ Note that Canvas changes need to be placed between save() or saveLayer() and restore(), otherwise you won’t get the desired effect.

Translate ()

Translate () is used to translate the canvas a specified distance relative to its original position.

Let’s look at an example ๐ŸŒฐ.

Start by drawing a picture on the canvas:

canvas.drawImage(background, Offset.zero, paint);
Copy the code

๐Ÿ–ผ effect:

Now, pan the canvas:

canvas.save(); // Translate the canvas. Translate (100, 100); canvas.drawImage(background, Offset.zero, paint); canvas.restore();Copy the code

๐Ÿ–ผ effect:

The logic of drawing the picture remains the same, but after translation, the position of the picture changes.

Scale canvas ()

Scale () is used to scale the canvas.

Look directly at the example ๐ŸŒฐ.

Start by drawing a rectangle that fills the canvas:

canvas.drawRect(Offset.zero & size, Paint().. color=Colors.pinkAccent);Copy the code

๐Ÿ–ผ effect:

Now, scale the canvas:

canvas.save(); Canvas. Scale (0.5); canvas.drawRect(Offset.zero & size, Paint().. color=Colors.pinkAccent); canvas.restore();Copy the code

๐Ÿ–ผ effect:

By reducing the canvas in half, you can see that the rectangle has been reduced in half.

Rotate canvas rotate()

Rotate () rotates the canvas.

Look at the example ๐ŸŒฐ to understand its use.

Start by drawing a rectangle in the center of the canvas:

canvas.drawRect(Rect.fromCircle( center: Offset(size.width / 2, size.height / 2), radius: 100), Paint().. color = Colors.amber);Copy the code

๐Ÿ–ผ effect:

Now, rotate 45 degrees:

canvas.save(); canvas.rotate(pi/4); canvas.drawRect(Rect.fromCircle( center: Offset(size.width / 2, size.height / 2), radius: 100), Paint().. color = Colors.amber); canvas.restore();Copy the code

๐Ÿ–ผ effect:

Look at the renderings, you will find that the rectangle is indeed rotated, but the rotation is a little strange ๐Ÿ˜.

This is because the Canvas’s rotation center is in the top left corner of the Canvas, so the result is not what you want.

How to get the desired center rotation effect?

You need to move the canvas so that the canvas rotated around the top left corner looks like a center rotation.

So the point is, how do you determine how much offset the canvas needs to move?

First, take a look at how the center of the canvas changes during rotation:

๐Ÿ’ก prompts that the forward rotation direction of Canvas is clockwise, and 0 radian is in the positive direction of X-axis in the figure.

As you can see from the figure, as the canvas rotates around the top left corner, the center point of the canvas always moves on a circle with the top left corner as the center and half the radius of the diagonal of the canvas.

The offset the canvas needs to move is actually half the distance from each point on the circle (the rotated center of the canvas) to the original center of the canvas.

This problem is then transformed into a problem of finding the distance between two points on a circle.

Now, to solve it ๐Ÿคจ!

The only thing we know is the size of the canvas.

But that’s enough.

1. Calculate the coordinates of the canvas’s initial center point.

To find the coordinates of a point on a circle, you can use the following formula:

X = x0 + r * cos(๐’ถ) y = y0 + r * sin(๐’ถ)Copy the code

Since the center of the circle is the top left corner of the canvas, i.e. (0, 0), it can be simplified as:

X = r * cos(๐’ถ) y = r * sin(๐’ถ)Copy the code

Obviously, to calculate the coordinates of the initial center point of the canvas, the radius of the track circle of the center point and the radian of the point should be calculated.

According to the Pythagorean theorem, it is easy to calculate the radius of the center point trajectory circle:

double r = sqrt(pow(size.width, 2) + pow(size.height, 2));
Copy the code

According to the arcsine function, the radian of the initial center point can be calculated:

double startAngle = atan(size.height / size.width);
Copy the code

Now, we can easily solve for the coordinates of the canvas’s initial center point:

double x0 = r * cos(startAngle);
double y0 = r * sin(startAngle);
Point p0 = Point(x0, y0);
Copy the code

2. Calculate the center point coordinates of the rotated canvas

Reviewing the above figure, when the canvas is rotated ๐’ถ radians, the radian of its center point is ๐’ถ + the radian of the original center point of the canvas, then:

double realAngle = xAngle + startAngle;
Copy the code

Given the Angle of the central point, it is easy to calculate its coordinates:

Point px = Point(r * cos(realAngle), r * sin(realAngle));  
Copy the code

3. Pan the canvas

Now that we have the coordinates of the original center point of the canvas and the rotated center point of the canvas, we know how much the canvas should be shifted:

canvas.translate((p0.x - px.x)/2, (p0.y - px.y)/2);
Copy the code

4. Complete code

Put the above code into the rotation operation we just did:

canvas.save(); Double r = SQRT (pow(size.width, 2) + pow(size.height, 2)); double r = SQRT (pow(size.width, 2) + pow(size.height, 2)); Double startAngle = atan(size.height/size.width); double startAngle = atan(size.height/size.width); Point p0 = Point(r * cos(startAngle), r * sin(startAngle)); // double xAngle = PI / 4; Point px = Point(r * cos(xAngle + startAngle), r * sin(xAngle + startAngle)); // Canvas. Translate ((p0.x-px.x) / 2, (P0.y-px.y) / 2); // Rotate canvas. Rotate (xAngle); canvas.drawRect(Rect.fromCircle( center: Offset(size.width / 2, size.height / 2), radius: 100), Paint() .. color = Colors.amber); canvas.restore();Copy the code

๐Ÿ–ผ effect:

๐Ÿ’ก tip, rotate() is in radians.

Skew ()

Skew () is used to cut a canvas diagonally. It takes two parameters, the first representing the horizontal tangent and the second representing the vertical tangent. The tangent value is the sine function tan.

For example, if you cut it by 45 degrees, you get tan PI /4 = 1.

Look at the example ๐ŸŒฐ.

Start by drawing an image in the center of the canvas:

canvas.drawImageRect(background, Offset.zero & imgSize,
        Alignment.center.inscribe(imgSize, Offset.zero & size), paint);
Copy the code

๐Ÿ–ผ effect:

To perform the bevel cutting operation:

canvas.save(); Canvas. Skew (0.2 0); canvas.drawImageRect(background, Offset.zero & imgSize, Alignment.center.inscribe(imgSize, Offset.zero & size), paint); canvas.restore();Copy the code

๐Ÿ–ผ effect:

The effect is more obvious ๐Ÿ˜€.

Directory Portals: A Guide to The Quick Start To Flutter

How can I be found?

Portal:CoorChice homepage

Portal:Lot of CoorChice