1# Using the Drawing Feature 2 3The drawing feature is provided by the drawing component in the framework, with support for the SVG standard drawing commands. 4 5This section describes how to use the drawing component to draw food composition labels (basic geometric shapes) and apply logos (custom graphics) on the details page. 6 7## Drawing Basic Geometric Shapes 8 9The drawing component encapsulates some common basic geometric shapes, such as rectangles, circles, and ellipses, eliminating the need to calculate routes. 10 11In the food component table on the **FoodDetail** page, each food group is labeled with a round icon. 12 131. Create a **Circle** component and add a round icon before each food group as a label. Set the circle diameter to 6vp. Modify the **IngredientItem** method in the **ContentTable** component on the **FoodDetail** page by adding **Circle** before the food group name. 14 15 ```ts 16 // FoodDetail.ets 17 @Component 18 struct ContentTable { 19 private foodItem: FoodData 20 21 @Builder IngredientItem(title:string, colorValue: string, name: string, value: string) { 22 Flex() { 23 Text(title) 24 .fontSize(17.4) 25 .fontWeight(FontWeight.Bold) 26 .layoutWeight(1) 27 Flex({ alignItems: ItemAlign.Center }) { 28 Circle({width: 6, height: 6}) 29 .margin({right: 12}) 30 .fill(colorValue) 31 Text(name) 32 .fontSize(17.4) 33 .flexGrow(1) 34 Text(value) 35 .fontSize(17.4) 36 } 37 .layoutWeight(2) 38 } 39 } 40 41 build() { 42 ...... 43 } 44 } 45 ``` 46 472. To use different label colors for different food groups, call **IngredientItem** in the **build** method to fill the circles with different colors. 48 49 ```ts 50 // FoodDetail.ets 51 @Component 52 struct ContentTable { 53 private foodItem: FoodData 54 55 @Builder IngredientItem(title:string, colorValue: string, name: string, value: string) { 56 Flex() { 57 Text(title) 58 .fontSize(17.4) 59 .fontWeight(FontWeight.Bold) 60 .layoutWeight(1) 61 Flex({ alignItems: ItemAlign.Center }) { 62 Circle({width: 6, height: 6}) 63 .margin({right: 12}) 64 .fill(colorValue) 65 Text(name) 66 .fontSize(17.4) 67 .flexGrow(1) 68 Text(value) 69 .fontSize(17.4) 70 } 71 .layoutWeight(2) 72 } 73 } 74 75 build() { 76 Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { 77 this.IngredientItem('Calories', '#FFf54040', 'Calories', this.foodItem.calories + 'kcal') 78 this.IngredientItem('Nutrition', '#FFcccccc', 'Protein', this.foodItem.protein + 'g') 79 this.IngredientItem(' ', '#FFf5d640', 'Fat', this.foodItem.fat + 'g') 80 this.IngredientItem(' ', '#FF9e9eff', 'Carbohydrates', this.foodItem.carbohydrates + 'g') 81 this.IngredientItem(' ', '#FF53f540', 'VitaminC', this.foodItem.vitaminC + 'mg') 82 } 83 .height(280) 84 .padding({ top: 30, right: 30, left: 30 }) 85 } 86 } 87 ``` 88 89  90 91## Drawing Custom Graphs 92 93In addition to drawing basic geometric shapes, you can also use the **\<Path>** component to draw a custom path. The following describes how to draw an application logo. 94 951. Create the page **Logo.ets** in the **pages** folder. 96 97  98 992. Delete the template code from **Logo.ets** and create a logo component. 100 101 ```ts 102 @Entry 103 @Component 104 struct Logo { 105 build() { 106 } 107 } 108 ``` 109 1103. Create a **\<Flex>** component as the root node, set the width and height to 100%, set the alignment mode on the main axis and cross axis to **Center**, and create a **\<Shape>** component as a child component of **\<Flex>**. 111 112 The **\<Shape>** component is the parent component of all drawing components. To combine multiple drawing components into a whole, create a **\<Shape>** as their parent component. 113 114 Draw a logo with the size of 630 px x 630 px. The declarative development paradigm supports multiple length units. In the preceding sections, **number** is used as a parameter, which means that the default length unit – virtual pixel (vp) is used. The virtual pixel count is related to the device resolution and screen density. For example, if the device resolution is 1176 x 2400 and the reference screen resolution is 3, with the formula of vp = px/resolution, the width of the device screen is 392 vp. 115 116 The drawing components follow the SVG standard and use px as the unit by default. Therefore, to facilitate consistency, px is also used as the unit of the logo. The declarative development framework also supports the px unit, with the input parameter of the string type. For example, to set the width to 630px (210vp), use **width('*630px*')** or **width(*210*)**. 117 118 ```ts 119 @Entry 120 @Component 121 struct Logo { 122 build() { 123 Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 124 Shape() { 125 126 } 127 .height('630px') 128 .width('630px') 129 } 130 .width('100%') 131 .height('100%') 132 } 133 } 134 ``` 135 1364. Fill the page with gradient colors. Set the gradient mode to linear gradient, the offset angle to 180 degrees, and the color stops to #BDE895 -> 95DE7F -> #7AB967 in the ranges of [0, 0.1], (0.1, 0.6], and (0.6, 1], respectively. 137 138 ```ts 139 .linearGradient( 140 { 141 angle: 180, 142 colors: [['#BDE895', 0.1], ["#95DE7F", 0.6], ["#7AB967", 1]] 143 }) 144 ``` 145 146  147 148 ```ts 149 @Entry 150 @Component 151 struct Logo { 152 build() { 153 Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 154 Shape() { 155 156 } 157 .height('630px') 158 .width('630px') 159 } 160 .width('100%') 161 .height('100%') 162 .linearGradient( 163 { 164 angle: 180, 165 colors: [['#BDE895', 0.1], ["#95DE7F", 0.6], ["#7AB967", 1]] 166 }) 167 } 168 } 169 ``` 170 171  172 1735. Set the drawing command to draw the first path. 174 175 ```ts 176 Path() 177 .commands('M162 128.7 a222 222 0 0 1 100.8 374.4 H198 a36 36 0 0 3 -36 -36') 178 ``` 179 180 The **Path** drawing commands comply with the SVG standard. The preceding command can be divided into the following: 181 182 ```ts 183 M162 128.7 184 ``` 185 186 Start a new subpath at point (162, 128.7). 187 188 ```ts 189 a222 222 0 0 1 100.8 374.4 190 ``` 191 192 Draw an elliptical arc, setting **rx** and **ry** to **222**, **x-axis-rotation** to **0**, **large-arc-flag** to **0**, and **sweep-flag** to **1** (which means to draw the arc counterclockwise). The lowercase **a** indicates a relative position. In this example, the end point coordinate is (162 + 100.8 = 262.8, 128.7 + 374.4 = 503.1). 193 194 ```ts 195 H198 196 ``` 197 198 Draw a horizontal line from point (262.8, 503.1) to point (198, 503.1). 199 200 ```ts 201 a36 36 0 0 3 -36 -36 202 ``` 203 204 Draw a circular arc. The input parameters are the same as those in drawing an elliptical arc. The end point is (198 - 36 = 162, 503.1 - 36 = 467.1). 205 206 ```ts 207 V128.7 208 ``` 209 210 Draw a vertical line from point (162, 467.1) to point (162, 128.7). 211 212 ```ts 213 z 214 ``` 215 216 Close the current subpath. 217 218  219 220 In the sample code, the fill color is white and the stroke is transparent. 221 222 ```ts 223 .fill(Color.White) 224 .stroke(Color.Transparent) 225 ``` 226 227 ```ts 228 @Entry 229 @Component 230 struct Logo { 231 build() { 232 Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 233 Shape() { 234 Path() 235 .commands('M162 128.7 a222 222 0 0 1 100.8 374.4 H198 a36 36 0 0 3 -36 -36') 236 .fill(Color.White) 237 .stroke(Color.Transparent) 238 } 239 .height('630px') 240 .width('630px') 241 } 242 .width('100%') 243 .height('100%') 244 .linearGradient( 245 { 246 angle: 180, 247 colors: [['#BDE895', 0.1], ["#95DE7F", 0.6], ["#7AB967", 1]] 248 }) 249 } 250 } 251 ``` 252 253  254 2556. Draw the second path. Fill the shape background with gradient colors. Because the gradient colors fill the entire box, you must use the **clip** method with the **Shape** as the input parameter so that the path is clipped. 256 257 ```ts 258 Path() 259 .commands('M319.5 128.1 c103.5 0 187.5 84 187.5 187.5 v15 a172.5 172.5 0 0 3 -172.5 172.5 H198 a36 36 0 0 3 -13.8 -1 207 207 0 0 0 87 -372 h48.3 z') 260 .fill('none') 261 .stroke(Corlor.Transparent) 262 .linearGradient( 263 { 264 angle: 30, 265 colors: [["#C4FFA0", 0], ["#ffffff", 1]] 266 }) 267 .clip(new Path().commands('M319.5 128.1 c103.5 0 187.5 84 187.5 187.5 v15 a172.5 172.5 0 0 3 -172.5 172.5 H198 a36 36 0 0 3 -13.8 -1 207 207 0 0 0 87 -372 h48.3 z')) 268 ``` 269 270 The path drawing command is long. You can call the command by using it as a member variable of the component through **this**. 271 272 ```ts 273 @Entry 274 @Component 275 struct Logo { 276 private pathCommands1:string = 'M319.5 128.1 c103.5 0 187.5 84 187.5 187.5 v15 a172.5 172.5 0 0 3 -172.5 172.5 H198 a36 36 0 0 3 -13.8 -1 207 207 0 0 0 87 -372 h48.3 z' 277 build() { 278 ...... 279 Path() 280 .commands(this.pathCommands1) 281 .fill('none') 282 .stroke(Color.Transparent) 283 .linearGradient( 284 { 285 angle: 30, 286 colors: [["#C4FFA0", 0], ["#ffffff", 1]] 287 }) 288 .clip(new Path().commands(this.pathCommands1)) 289 ...... 290 } 291 } 292 ``` 293 294  295 2967. Draw the third path. 297 298 ```ts 299 @Entry 300 @Component 301 struct Logo { 302 private pathCommands1:string = 'M319.5 128.1 c103.5 0 187.5 84 187.5 187.5 v15 a172.5 172.5 0 0 3 -172.5 172.5 H198 a36 36 0 0 3 -13.8 -1 207 207 0 0 0 87 -372 h48.3 z' 303 private pathCommands2:string = 'M270.6 128.1 h48.6 c51.6 0 98.4 21 132.3 54.6 a411 411 0 0 3 -45.6 123 c-25.2 45.6 -56.4 84 -87.6 110.4 a206.1 206.1 0 0 0 -47.7 -288 z' 304 build() { 305 Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 306 Shape() { 307 Path() 308 .commands('M162 128.7 a222 222 0 0 1 100.8 374.4 H198 a36 36 0 0 3 -36 -36') 309 .fill(Color.White) 310 .stroke(Color.Transparent) 311 312 Path() 313 .commands(this.pathCommands1) 314 .fill('none') 315 .stroke(Color.Transparent) 316 .linearGradient( 317 { 318 angle: 30, 319 colors: [["#C4FFA0", 0], ["#ffffff", 1]] 320 }) 321 .clip(new Path().commands(this.pathCommands1)) 322 323 Path() 324 .commands(this.pathCommands2) 325 .fill('none') 326 .stroke(Color.Transparent) 327 .linearGradient( 328 { 329 angle: 50, 330 colors: [['#8CC36A', 0.1], ["#B3EB90", 0.4], ["#ffffff", 0.7]] 331 }) 332 .clip(new Path().commands(this.pathCommands2)) 333 } 334 .height('630px') 335 .width('630px') 336 } 337 .width('100%') 338 .height('100%') 339 .linearGradient( 340 { 341 angle: 180, 342 colors: [['#BDE895', 0.1], ["#95DE7F", 0.6], ["#7AB967", 1]] 343 }) 344 } 345 } 346 ``` 347 348  349 350 The drawing of the application logo is now completed. This logo combines three **\<Path>** components through SVG commands and takes the shape of an artistic leaf. 351 3528. Add the application title and slogan. 353 354 ```ts 355 @Entry 356 @Component 357 struct Logo { 358 private pathCommands1: string = 'M319.5 128.1 c103.5 0 187.5 84 187.5 187.5 v15 a172.5 172.5 0 0 3 -172.5 172.5 H198 a36 36 0 0 3 -13.8 -1 207 207 0 0 0 87 -372 h48.3 z' 359 private pathCommands2: string = 'M270.6 128.1 h48.6 c51.6 0 98.4 21 132.3 54.6 a411 411 0 0 3 -45.6 123 c-25.2 45.6 -56.4 84 -87.6 110.4 a206.1 206.1 0 0 0 -47.7 -288 z' 360 361 build() { 362 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 363 Shape() { 364 Path() 365 .commands('M162 128.7 a222 222 0 0 1 100.8 374.4 H198 a36 36 0 0 3 -36 -36') 366 .fill(Color.White) 367 .stroke(Color.Transparent) 368 369 Path() 370 .commands(this.pathCommands1) 371 .fill('none') 372 .stroke(Color.Transparent) 373 .linearGradient( 374 { 375 angle: 30, 376 colors: [["#C4FFA0", 0], ["#ffffff", 1]] 377 }) 378 .clip(new Path().commands(this.pathCommands1)) 379 380 Path() 381 .commands(this.pathCommands2) 382 .fill('none') 383 .stroke(Color.Transparent) 384 .linearGradient( 385 { 386 angle: 50, 387 colors: [['#8CC36A', 0.1], ["#B3EB90", 0.4], ["#ffffff", 0.7]] 388 }) 389 .clip(new Path().commands(this.pathCommands2)) 390 } 391 .height('630px') 392 .width('630px') 393 394 Text('Healthy Diet') 395 .fontSize(26) 396 .fontColor(Color.White) 397 .margin({ top: 300 }) 398 399 Text('Healthy life comes from a balanced diet') 400 .fontSize(17) 401 .fontColor(Color.White) 402 .margin({ top: 4 }) 403 } 404 .width('100%') 405 .height('100%') 406 .linearGradient( 407 { 408 angle: 180, 409 colors: [['#BDE895', 0.1], ["#95DE7F", 0.6], ["#7AB967", 1]] 410 }) 411 } 412 } 413 ``` 414 415  416