How To Draw Vietnam Flag
Problem
"What are we studying Math for. You have been working in IT for a long time, have you ever needed to use sin cos tan?" . My brother in grade 12 asked. Know how to answer it now. Honestly, I was also very stupid math, thinking about it until I came up with a little easy lesson that I learned in computer graphics to demo it to see. A very familiar topic in computer graphics is: Drawing the Vietnamese flag with Flutter.
Always, in order to draw a complex shape, we should start from the smallest things, draw the simplest one.
1. Draw a simple shape in Flutter
To draw a simple Circle in Flutter. We use the CustomPaint
and CustomPainter
Widgets very simply with only 2 steps:
Step 1 : Create a CustomPainter
Create a class named MyCustomPainter
that inherits the CustomPainter
class, it will force you to override the paint
and shouldRepaint
return the bool
type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | < span class = "token keyword" > class < / span > < span class = "token class-name" > MyCustomPainter < / span > < span class = "token keyword" > extends < / span > < span class = "token class-name" > CustomPainter < / span > < span class = "token punctuation" > { < / span > < span class = "token function" > MyCustomPainter < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > { < / span > < span class = "token keyword" > this < / span > < span class = "token punctuation" > . < / span > banKinh < span class = "token punctuation" > } < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // bán kính đường tròn</span> < span class = "token keyword" > final < / span > double banKinh < span class = "token punctuation" > ; < / span > < span class = "token metadata symbol" > @ override < / span > < span class = "token keyword" > void < / span > < span class = "token function" > paint < / span > < span class = "token punctuation" > ( < / span > Canvas canvas < span class = "token punctuation" > , < / span > Size size < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > { < / span > < span class = "token comment" > // tọa độ tâm đường tròn cũng chính là tâm của Widget (size.width / 2, size.height / 2)</span> < span class = "token keyword" > final < / span > toaDoTamDuongTron < span class = "token operator" >= < / span > < span class = "token function" > Offset < / span > < span class = "token punctuation" > ( < / span > size < span class = "token punctuation" > . < / span > width < span class = "token operator" > / < / span > < span class = "token number" > 2 < / span > < span class = "token punctuation" > , < / span > size < span class = "token punctuation" > . < / span > height < span class = "token operator" > / < / span > < span class = "token number" > 2 < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // paint: giống như chọn style cho cái hình mình vẽ: nó màu gì,...</span> < span class = "token keyword" > final < / span > paint < span class = "token operator" >= < / span > < span class = "token function" > Paint < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > color < span class = "token operator" >= < / span > Colors < span class = "token punctuation" > . < / span > pink < span class = "token comment" > // vẽ màu hồng</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > style < span class = "token operator" >= < / span > PaintingStyle < span class = "token punctuation" > . < / span > stroke < span class = "token comment" > // chỉ vẽ viền</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > strokeWidth < span class = "token operator" >= < / span > < span class = "token number" > 2 < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // độ dày viền bằng 2</span> < span class = "token comment" > // vẽ đường tròn</span> canvas < span class = "token punctuation" > . < / span > < span class = "token function" > drawCircle < / span > < span class = "token punctuation" > ( < / span > toaDoTamDuongTron < span class = "token punctuation" > , < / span > banKinh < span class = "token punctuation" > , < / span > paint < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token punctuation" > } < / span > < span class = "token metadata symbol" > @ override < / span > bool < span class = "token function" > shouldRepaint < / span > < span class = "token punctuation" > ( < / span > MyCustomPainter oldDelegate < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > { < / span > < span class = "token keyword" > return < / span > banKinh < span class = "token operator" > != < / span > oldDelegate < span class = "token punctuation" > . < / span > banKinh < span class = "token punctuation" > ; < / span > < span class = "token comment" > // nếu bán kính truyền vào bị thay đổi thì mới cho vẽ lại.</span> < span class = "token punctuation" > } < / span > < span class = "token punctuation" > } < / span > |
-
Canvas
is a pure white drawing board where we can draw all kinds of things in the world. ThisCanvas
class provides us the functions for drawing. As in the above example I use itsdrawCircle
function to draw that circle. -
Size
is the size of the Widget I intend to draw. For example: ForSize(300.0, 200.0)
, the Widget haswidth = 300.0
andheight = 200.0
. -
Paint
as a stylist, create styles for drawings such as what color, line thickness, bla bla - The
shouldRepaint
function helps us decide whether to redraw this CustomView or not. When it redraws it will run thepaint
function again. If returntrue
it will re-draw, returnfalse
will not re-draw -
Offset
passes to the x, the y coordinate. AnOffset
object represents a point in the Cartesian coordinate system (Cartesian – s) that you learned in Mathematics. In addition, it can also represent the coordinates of avector
in Math. - Unlike the Cartesian coordinate system that we learned in the past, the coordinate system in Flutter, it conventionally that the positive direction of the vertical axis is downward and the origin we named point A (0, 0) will be referred to wish in that position. From that point A (0, 0) , we easily deduce the remaining 3 points are B (size.width, 0) , C (size.width, size.height) and D (0, size.height) . These are 4 extremely important points to help us determine the coordinates of the points, the shapes to be drawn in the canvas
Step 2 : Create a CustomPaint
widget passed MyCustomPainter
just created.
< span class = "token keyword" > class < / span > < span class = "token class-name" > MyCircleWidget < / span > < span class = "token keyword" > extends < / span > < span class = "token class-name" > StatelessWidget < / span > < span class = "token punctuation" > { < / span > < span class = "token metadata symbol" > @ override < / span > Widget < span class = "token function" > build < / span > < span class = "token punctuation" > ( < / span > BuildContext context < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > { < / span > < span class = "token keyword" > return < / span > < span class = "token function" > CustomPaint < / span > < span class = "token punctuation" > ( < / span > painter < span class = "token punctuation" > : < / span > < span class = "token function" > MyCustomPainter < / span > < span class = "token punctuation" > ( < / span > banKinh < span class = "token punctuation" > : < / span > < span class = "token number" > 100 < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > , < / span > size < span class = "token punctuation" > : < / span > < span class = "token function" > Size < / span > < span class = "token punctuation" > ( < / span > < span class = "token number" > 300 < / span > < span class = "token punctuation" > , < / span > < span class = "token number" > 300 < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > , < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token punctuation" > } < / span > < span class = "token punctuation" > } < / span > |
The CustomPaint
widget has 3 important properties:
-
painter
: pass in aCustomPainter
as created above -
child
: pass a child widget of thisCustomPaint
Widget -
size
: When passing theSize
object to thesize
MyCustomPainter
, theMyCustomPainter
object will be received in thevoid paint(Canvas canvas, Size size)
functionvoid paint(Canvas canvas, Size size)
. Note that if thisCustomPaint
Widget has achild
, thisSize
object becomes meaningless because Flutter will use the size of the Widgetchild
instead of theSize
object we pass in thesize
variable.
Full source code: https://dartpad.dev/0605bed20c6410a25f5d91120c865d1c
Bonus picture, this picture enough to explain the above theory
With only 2 classes CustomPaint
and CustomPainter
, we have created a custom shape. It's easy, right. If you just shut it down, the million words above are only encapsulated in this picture. Remember this is the weight
To draw a more complex shape, we need to use Path
. Now we will learn the Path
through our main problem today: Drawing the Vietnamese flag
2. Drawing the Vietnamese flag
Search on Wiki, get the standard scale image of the Vietnamese flag
Okay, so the problem is: the flag length is 3a , the width is 2a , the radius of the circumcircle of the golden star is 3a / 5 (that is 1/5 of length). Let's start
Job
First thing to do is create a CustomPainter
and declare variables like width
, height
and r
(radius) in the paint
function.
< span class = "token keyword" > class < / span > < span class = "token class-name" > VietNamFlagPainter < / span > < span class = "token keyword" > extends < / span > < span class = "token class-name" > CustomPainter < / span > < span class = "token punctuation" > { < / span > < span class = "token metadata symbol" > @ override < / span > < span class = "token keyword" > void < / span > < span class = "token function" > paint < / span > < span class = "token punctuation" > ( < / span > Canvas canvas < span class = "token punctuation" > , < / span > Size size < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > { < / span > < span class = "token keyword" > final < / span > double width < span class = "token operator" >= < / span > size < span class = "token punctuation" > . < / span > width < span class = "token punctuation" > ; < / span > < span class = "token comment" > // chiều rộng của lá cờ</span> < span class = "token keyword" > final < / span > double height < span class = "token operator" >= < / span > < span class = "token number" > 2 < / span > < span class = "token operator" > * < / span > width < span class = "token operator" > / < / span > < span class = "token number" > 3 < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // chiều cao của lá cờ bằng 2 / 3 chiều rộng</span> < span class = "token keyword" > final < / span > double r < span class = "token operator" >= < / span > width < span class = "token operator" > / < / span > < span class = "token number" > 5 < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // bán kính đường tròn ngoại tiếp ngôi sao</span> < span class = "token punctuation" > } < / span > < span class = "token metadata symbol" > @ override < / span > bool < span class = "token function" > shouldRepaint < / span > < span class = "token punctuation" > ( < / span > CustomPainter oldDelegate < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > { < / span > < span class = "token keyword" > return < / span > < span class = "token boolean" > true < / span > < span class = "token punctuation" > ; < / span > < span class = "token punctuation" > } < / span > < span class = "token punctuation" > } < / span > |
Next, we will need to draw the red flag. Create a redPaint
and use the drawRect
function to draw the red rectangle. The drawRect
function needs to pass a Rect
object (rectangular). To create a Rect
object we use the Rect.fromLTRB(double left, double top, double right, double bottom)
function Rect.fromLTRB(double left, double top, double right, double bottom)
. In which left
, top
, right
, bottom
are the distances calculated from the horizontal or vertical axis like this:
< span class = "token keyword" > final < / span > Paint redPaint < span class = "token operator" >= < / span > < span class = "token function" > Paint < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token comment" > // tạo paint màu đỏ để vẽ cờ đỏ</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > color < span class = "token operator" >= < / span > Colors < span class = "token punctuation" > . < / span > red < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > style < span class = "token operator" >= < / span > PaintingStyle < span class = "token punctuation" > . < / span > fill < span class = "token punctuation" > ; < / span > < span class = "token comment" > // tô màu hết cả shape</span> < span class = "token comment" > // vẽ hình chữ nhật full cái Widget CustomPaint luôn</span> canvas < span class = "token punctuation" > . < / span > < span class = "token function" > drawRect < / span > < span class = "token punctuation" > ( < / span > Rect < span class = "token punctuation" > . < / span > < span class = "token function" > fromLTRB < / span > < span class = "token punctuation" > ( < / span > < span class = "token number" > 0 < / span > < span class = "token punctuation" > , < / span > < span class = "token number" > 0 < / span > < span class = "token punctuation" > , < / span > width < span class = "token punctuation" > , < / span > height < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > , < / span > redPaint < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > |
Next, to draw a star, we need to find the coordinates of 5 vertices A, B, C, D, E. You will know why you need to find the coordinates.
Although the coordinate system in Flutter is different from the Cartesian coordinate system – slightly, I just attach the Cartesian coordinate system – the familiar, ie the origin is the point O (0, 0)
and the positive direction of the vertical axis so that it will become more familiar with the Mathematics that you have learned, solving it faster and easier. In a little bit, I will use the offsets to bring back the Flutter coordinate system later.
We have: OA = OB = OC = OD = OE = r so we can find the point coordinate immediately A ( 0 , r ) A (0, r) A ( 0 , r )
5 points A, B, C, D, E create 5 equal chord so create 5 angle at equal center. So we can calculate it A O B ^ = 360 ° / 5 = 72 ° widehat {AOB} = 360 ° / 5 = 72 ° A O B = 3 6 0 ° / 5 = 7 2 ° . From there we can calculate ∣ x B ∣ | x_B | | X B ∣ = FB = OB * sin (72 °) and ∣ y B ∣ | y_B | | Y B ∣ = OF = OB * cos (72 °). Since point B is in the first quadrant (positive direction Ox and positive direction Oy), the coordinate point B ( r ∗ S i n ( 72 ° ) , r ∗ c o S ( 72 ° ) ) B (r * sin (72 °), r * cos (72 °)) B ( r ∗ s i n ( 7 2 ° ) , r ∗ c o s ( 7 2 ° ) )
Since point E is symmetrical with point B through Oy, we always find the coordinate of the point E ( – x B , y B ) E (-x_B, y_B) E (- x B , Y B )
With just a few simple calculations, we have found the coordinates of 3 points A, B and E. Now we continue to find the coordinates of points C and D:
Draw OG perpendicular to CD => OG is both the height and the bisector of C O D ^ widehat {COD} C O D => C O G ^ widehat {COG} C O G = 72 ° / 2 = 36 °. From there we can calculate ∣ x C ∣ | x_C | | X C ∣ = GC = OC * sin (36 °) and ∣ y C ∣ | y_C | | Y C ∣ = OG = OC * cos (36 °). Since point C is in the fourth quadrant (positive direction Ox, negative direction Oy), the coordinate point C ( r ∗ S i n ( 36 ° ) , – r ∗ c o S ( 36 ° ) ) C (r * sin (36 °), -r * cos (36 °)) C ( r ∗ s i n ( 3 6 ° ) , – r ∗ c o s ( 3 6 ° ) )
Since point D is symmetrical with point C through Oy, we find the point coordinate D ( – x C , y C ) D (-x_C, y_C) D (- x C , Y C )
Well, so we have found the coordinates of 5 points. Now let's put them in code. Since the sin
and cos
functions in Dart's dart:math
library use radians, we first need to write an extension function that converts degrees to radians.
< span class = "token keyword" > import < / span > < span class = "token string" > 'dart:math' < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // cần phải import thư viện dart:math</span> extension NumberUtil on num < span class = "token punctuation" > { < / span > num < span class = "token function" > toRadian < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > { < / span > < span class = "token keyword" > return < / span > < span class = "token keyword" > this < / span > < span class = "token operator" > * < / span > pi < span class = "token operator" > / < / span > < span class = "token number" > 180 < / span > < span class = "token punctuation" > ; < / span > < span class = "token punctuation" > } < / span > < span class = "token punctuation" > } < / span > |
Now create 5 Offset
objects representing 5 points A, B, C, D, E only. Note that at the moment we compute using the positive coordinate system of the vertical axis going up and the coordinate system in Flutter has the positive direction, the vertical axis is facing down so in the code we need to get the points of symmetry with A, B, C. , D, E cross the Ox axis according to the formula: x F l u t t e r = x C a l c u l a t e xFlutter = xCalculate x F l u t t e r = x C a l c u l a t e and y F l u t t e r = – y C a l c u l a t e y Flutter = -y Calculate y F l u t t e r = – y C a l c u l a t e in it x C a l c u l a t e xCalculate x C a l c u l a t e and y C a l c u l a t e yCalculate y C a l c u l a t e is the coordinates we just found in the calculation x F l u t t e r xFlutter x F l u t t e r and y F l u t t e r yFlutter y F l u t t e r is the coordinate I write code in Flutter.
< span class = "token keyword" > final < / span > pointA < span class = "token operator" >= < / span > < span class = "token function" > Offset < / span > < span class = "token punctuation" > ( < / span > < span class = "token number" > 0 < / span > < span class = "token punctuation" > , < / span > < span class = "token operator" > - < / span > r < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // vì lúc nảy mình tính được tọa độ A (0, r)</span> < span class = "token comment" > // Tọa độ B tính toán được là B (r * sin(72°), r * cos(72°)) nên trong code là</span> < span class = "token keyword" > final < / span > pointB < span class = "token operator" >= < / span > < span class = "token function" > Offset < / span > < span class = "token punctuation" > ( < / span > r < span class = "token operator" > * < / span > < span class = "token function" > sin < / span > < span class = "token punctuation" > ( < / span > < span class = "token number" > 72. < / span > < span class = "token function" > toRadian < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > , < / span > < span class = "token operator" > - < / span > r < span class = "token operator" > * < / span > < span class = "token function" > cos < / span > < span class = "token punctuation" > ( < / span > < span class = "token number" > 72. < / span > < span class = "token function" > toRadian < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // Tọa độ C tính toán được là C (r * sin(36°), -r * cos(36°)) nên trong code là</span> < span class = "token keyword" > final < / span > pointC < span class = "token operator" >= < / span > < span class = "token function" > Offset < / span > < span class = "token punctuation" > ( < / span > r < span class = "token operator" > * < / span > < span class = "token function" > sin < / span > < span class = "token punctuation" > ( < / span > < span class = "token number" > 36. < / span > < span class = "token function" > toRadian < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > , < / span > r < span class = "token operator" > * < / span > < span class = "token function" > cos < / span > < span class = "token punctuation" > ( < / span > < span class = "token number" > 36. < / span > < span class = "token function" > toRadian < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token keyword" > final < / span > pointD < span class = "token operator" >= < / span > < span class = "token function" > Offset < / span > < span class = "token punctuation" > ( < / span > < span class = "token operator" > - < / span > pointC < span class = "token punctuation" > . < / span > dx < span class = "token punctuation" > , < / span > pointC < span class = "token punctuation" > . < / span > dy < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // đối xứng với C qua trục tung</span> < span class = "token keyword" > final < / span > pointE < span class = "token operator" >= < / span > < span class = "token function" > Offset < / span > < span class = "token punctuation" > ( < / span > < span class = "token operator" > - < / span > pointB < span class = "token punctuation" > . < / span > dx < span class = "token punctuation" > , < / span > pointB < span class = "token punctuation" > . < / span > dy < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // đối xứng với B qua trục tung</span> |
We usually draw a star by connecting A → C, C → E, E → B, from B → D and D reconnecting A, right?
Path
will help us to do just that.
< span class = "token keyword" > final < / span > Path path < span class = "token operator" >= < / span > < span class = "token function" > Path < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > < span class = "token function" > moveTo < / span > < span class = "token punctuation" > ( < / span > pointA < span class = "token punctuation" > . < / span > dx < span class = "token punctuation" > , < / span > pointA < span class = "token punctuation" > . < / span > dy < span class = "token punctuation" > ) < / span > < span class = "token comment" > // đưa ngòi bút đến điểm A</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > < span class = "token function" > lineTo < / span > < span class = "token punctuation" > ( < / span > pointC < span class = "token punctuation" > . < / span > dx < span class = "token punctuation" > , < / span > pointC < span class = "token punctuation" > . < / span > dy < span class = "token punctuation" > ) < / span > < span class = "token comment" > // vẽ 1 line từ A đến C</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > < span class = "token function" > lineTo < / span > < span class = "token punctuation" > ( < / span > pointE < span class = "token punctuation" > . < / span > dx < span class = "token punctuation" > , < / span > pointE < span class = "token punctuation" > . < / span > dy < span class = "token punctuation" > ) < / span > < span class = "token comment" > // vẽ 1 line từ C đến E</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > < span class = "token function" > lineTo < / span > < span class = "token punctuation" > ( < / span > pointB < span class = "token punctuation" > . < / span > dx < span class = "token punctuation" > , < / span > pointB < span class = "token punctuation" > . < / span > dy < span class = "token punctuation" > ) < / span > < span class = "token comment" > // vẽ 1 line từ E đến B</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > < span class = "token function" > lineTo < / span > < span class = "token punctuation" > ( < / span > pointD < span class = "token punctuation" > . < / span > dx < span class = "token punctuation" > , < / span > pointD < span class = "token punctuation" > . < / span > dy < span class = "token punctuation" > ) < / span > < span class = "token comment" > // vẽ 1 line từ B đến D</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > < span class = "token function" > close < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // vẽ 1 line từ D đến A tạo thành 1 hình khép kín</span> |
Initially the Path
will start at point M (0, 0)
as shown in the image below. The moveTo(xA, yA)
, lineTo(xC, yC)
all pass in the coordinate and latitude of a point, but the moveTo
function only moves the pen from the current point to the point it was passed in (which is point A ) rather than connecting the 2 points together and lineTo
is performing connecting those 2 points together. As shown in the figure lineTo(xC, yC)
will join the pen's current point A with point C.
Canvas
has a drawPath
function to draw any Path
, as long as we find the coordinates of the points on the Path
it can be drawn. Let's draw.
< span class = "token keyword" > final < / span > Paint yellowPaint < span class = "token operator" >= < / span > < span class = "token function" > Paint < / span > < span class = "token punctuation" > ( < / span > < span class = "token punctuation" > ) < / span > < span class = "token comment" > // tạo paint màu vàng để vẽ sao vàng</span> < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > color < span class = "token operator" >= < / span > Colors < span class = "token punctuation" > . < / span > yellow < span class = "token punctuation" > . < / span > < span class = "token punctuation" > . < / span > style < span class = "token operator" >= < / span > PaintingStyle < span class = "token punctuation" > . < / span > fill < span class = "token punctuation" > ; < / span > canvas < span class = "token punctuation" > . < / span > < span class = "token function" > drawPath < / span > < span class = "token punctuation" > ( < / span > path < span class = "token punctuation" > , < / span > yellowPaint < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // vẽ ngôi sao vàng theo path</span> |
Yeah, now run the app, we will get an image like this =))
Forget, at the moment we calculated that the center of the star coincides with the origin of the coordinate O (0, 0)
, but in fact the center of the star must be point I (width / 2, height / 2)
. We need to perform vector translations O I → overrightarrow {OI} O I by the shift
function:
< span class = "token comment" > // toạ độ tính toán của tâm ngôi sao</span> < span class = "token keyword" > final < / span > pointO < span class = "token operator" >= < / span > < span class = "token function" > Offset < / span > < span class = "token punctuation" > ( < / span > < span class = "token number" > 0 < / span > < span class = "token punctuation" > , < / span > < span class = "token number" > 0 < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // toạ độ thật của tâm ngôi sao</span> < span class = "token keyword" > final < / span > pointI < span class = "token operator" >= < / span > < span class = "token function" > Offset < / span > < span class = "token punctuation" > ( < / span > width < span class = "token operator" > / < / span > < span class = "token number" > 2 < / span > < span class = "token punctuation" > , < / span > height < span class = "token operator" > / < / span > < span class = "token number" > 2 < / span > < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // vector tịnh tiến OI</span> < span class = "token keyword" > final < / span > translationVector < span class = "token operator" >= < / span > pointI < span class = "token operator" > - < / span > pointO < span class = "token punctuation" > ; < / span > < span class = "token comment" > // thực hiện phép tịnh tiến cả Path bằng hàm shift</span> < span class = "token keyword" > final < / span > realPath < span class = "token operator" >= < / span > path < span class = "token punctuation" > . < / span > < span class = "token function" > shift < / span > < span class = "token punctuation" > ( < / span > translationVector < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > < span class = "token comment" > // vẽ realPath</span> canvas < span class = "token punctuation" > . < / span > < span class = "token function" > drawPath < / span > < span class = "token punctuation" > ( < / span > realPath < span class = "token punctuation" > , < / span > yellowPaint < span class = "token punctuation" > ) < / span > < span class = "token punctuation" > ; < / span > |
Here are the results:
Full source code: https://dartpad.dev/9f75935302a6e4fb20073cbc3ae95507
Conclude
Well, the theory behind "Draw custom shapes" in Flutter is that much. To be able to draw the complex shapes required by the project, the most important thing is still our thinking applied to the lines of code inside the paint(Canvas canvas, Size size)
function paint(Canvas canvas, Size size)
of CustomPainter
. In the next post, I will increase the level of drawing a more difficult, practical, closer shape to the actual project so that Flutter programming becomes less boring. See you in the next post. If you see that my share is valuable, then click up and vote for me. Thank you
How To Draw Vietnam Flag
Source: https://itzone.com.vn/en/article/drawing-the-vietnam-flag-with-flutter/
Posted by: lopezdresse.blogspot.com
0 Response to "How To Draw Vietnam Flag"
Post a Comment