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