1# Drawing Geometric Shapes 2 3 4The drawing components are used to draw graphs on the page. The **\<Shape>** component is the parent component of the drawing components. The attributes of **\<Shape>** are universal attributes supported by all the drawing components. For details, see [Shape](../reference/arkui-ts/ts-drawing-components-shape.md). 5 6 7## Creating a Drawing Component 8 9A drawing component can be created in either of the following ways: 10 11- Drawing components use **\<Shape>** as their parent to implement the effect similar to SVG. The API is called in the following format: 12 13 ```ts 14 Shape(value?: PixelMap) 15 ``` 16 17 Create a drawing component with a parent component. The **value** parameter is used to set the drawing target. You can draw a graph in the specified **PixelMap** object. If the **value** parameter is not set, the graph is drawn in the current drawing target. 18 19 ```ts 20 Shape() { 21 Rect().width(300).height(50) 22 } 23 ``` 24 25 26- The **\<Shape>** component is used independently to draw a specific shape. Seven shapes are supported: [Circle](../reference/arkui-ts/ts-drawing-components-circle.md), [Ellipse](../reference/arkui-ts/ts-drawing-components-ellipse.md), [Line](../reference/arkui-ts/ts-drawing-components-line.md), [Polyine](../reference/arkui-ts/ts-drawing-components-polyline.md), [Polygon](../reference/arkui-ts/ts-drawing-components-polygon.md), [Path](../reference/arkui-ts/ts-drawing-components-path.md), and [Rect](../reference/arkui-ts/ts-drawing-components-rect.md). The following uses the **Circle** API as an example: 27 28 ```ts 29 Circle(options?: {width?: string | number, height?: string | number} 30 ``` 31 32 Draws a circle on a page. The **width** parameter indicates the width of the circle, and the **height** parameter indicates the height of the circle. The diameter of the circle is determined by the minimum width and height. 33 34 ```ts 35 Circle({ width: 150, height: 150 }) 36 ``` 37 38 ![creation-2](figures/creation-2.jpg) 39 40 41## Viewport 42 43 44```ts 45viewPort{ x?: number | string, y?: number | string, width?: number | string, height?: number | string } 46``` 47 48Creates a viewport, which is a rectangle in the user space that maps to the view boundary established for the associated SVG element. The value of the **viewport** attribute contains four optional parameters: **x**, **y**, **width**, and **height**. **x** and **y** indicate the coordinates of the upper left corner of the viewport, and **width** and **height** indicate the size of the viewport. 49 50The following three examples describe how to use the viewport: 51 52- Zoom in or zoom out a graph through the shape viewport. 53 54 ```ts 55 // Draw a circle whose width and height are both 150. 56 Text ('Original Size Circle') 57 Circle({width: 75, height: 75}).fill('#E87361') 58 59 Row({space:10}) { 60 Column() { 61 // Create a shape component whose width and height are both 150, the background color is yellow, and a viewport whose width and height are both 75. Fill the viewport with a blue rectangle and draw a circle with a diameter of 75 in the viewport. 62 // The drawing is complete. The viewport is zoomed in twice based on the width and height of the component. 63 Text ('Enlarged Circle') 64 Shape() { 65 Rect().width('100%').height('100%').fill('#0097D4') 66 Circle({width: 75, height: 75}).fill('#E87361') 67 } 68 .viewPort({x: 0, y: 0, width: 75, height: 75}) 69 .width(150) 70 .height(150) 71 .backgroundColor('#F5DC62') 72 } 73 Column() { 74 // Create a shape component whose width and height are both 150, the background color is yellow, and a viewport whose width and height are both 300. Fill the viewport with a green rectangle and draw a circle with a diameter of 75 in the viewport. 75 // After the drawing is complete, the viewport is zoomed out by twice based on the width and height of the component. 76 Text ('Shrunk Circle') 77 Shape() { 78 Rect().width('100%').height('100%').fill('#BDDB69') 79 Circle({width: 75, height: 75}).fill('#E87361') 80 } 81 .viewPort({x: 0, y: 0, width: 300, height: 300}) 82 .width(150) 83 .height(150) 84 .backgroundColor('#F5DC62') 85 } 86 } 87 ``` 88 89 ![2023032401632](figures/2023032401632.jpg) 90 91- Create a shape component whose width and height are both 300, with a yellow background and a viewport whose width and height are both 300. Fill the viewport with a blue rectangle and draw a circle with a radius of 75 in the viewport. 92 93 ```ts 94 Shape() { 95 Rect().width("100%").height("100%").fill("#0097D4") 96 Circle({ width: 150, height: 150 }).fill("#E87361") 97 } 98 .viewPort({ x: 0, y: 0, width: 300, height: 300 }) 99 .width(300) 100 .height(300) 101 .backgroundColor("#F5DC62") 102 ``` 103 104 ![viewport (2) ](figures/viewport (2) .jpg) 105 106- Create a shape component whose width and height are both 300, with a yellow background and a viewport whose width and height are both 300. Fill the viewport with a blue rectangle, draw a circle with a radius of 75 in the viewport, and move the viewport 150 to the right and below respectively. 107 108 ```ts 109 Shape() { 110 Rect().width("100%").height("100%").fill("#0097D4") 111 Circle({ width: 150, height: 150 }).fill("#E87361") 112 } 113 .viewPort({ x: -150, y: -150, width: 300, height: 300 }) 114 .width(300) 115 .height(300) 116 .backgroundColor("#F5DC62") 117 118 ``` 119 120 ![viewport (3) ](figures/viewport (3) .jpg) 121 122 123## Setting Styles 124 125The drawing component allows you to change the component style through various attributes. 126 127- You can use **fill** to set the color of the filling area of the component. 128 129 ```ts 130 Path() 131 .width(100) 132 .height(100) 133 .commands('M150 0 L300 300 L0 300 Z') 134 .fill("#E87361") 135 ``` 136 137 ![2023022792216(1)](figures/2023022792216(1).jpg) 138 139- You can use **stroke** to set the stroke color of a component. 140 141 ```ts 142 Path() 143 .width(100) 144 .height(100) 145 .fillOpacity(0) 146 .commands('M150 0 L300 300 L0 300 Z') 147 .stroke(Color.Red) 148 ``` 149 150 ![stroke](figures/stroke.jpg) 151 152- You can use **strokeOpacity** to set the stroke opacity. 153 154 ```ts 155 Path() 156 .width(100) 157 .height(100) 158 .fillOpacity(0) 159 .commands('M150 0 L300 300 L0 300 Z') 160 .stroke(Color.Red) 161 .strokeWidth(10) 162 .strokeOpacity(0.2) 163 ``` 164 165 ![strokeopacity](figures/strokeopacity.jpg) 166 167- You can use **strokeLineJoin** to set the join style of the stroke. Options include **Bevel**, **Miter**, and **Round**. 168 169 ```ts 170 Polyline() 171 .width(100) 172 .height(100) 173 .fillOpacity(0) 174 .stroke(Color.Red) 175 .strokeWidth(8) 176 .points([[20, 0], [0, 100], [100, 90]]) 177 // Set the join style of the stroke to Round. 178 .strokeLineJoin(LineJoinStyle.Round) 179 ``` 180 181 ![strokeLineJoin](figures/strokeLineJoin.jpg) 182 183- **strokeMiterLimit** places a limit on the ratio of the miter length to the value of **strokeWidth** used to draw a miter join. 184 The miter length indicates the distance from the outer tip to the inner corner of the miter. This attribute must be set to a value greater than or equal to 1 and takes effect when **strokeLineJoin** is set to **LineJoinStyle.Miter**. 185 186 ```ts 187 Polyline() 188 .width(100) 189 .height(100) 190 .fillOpacity(0) 191 .stroke(Color.Red) 192 .strokeWidth(10) 193 .points([[20, 0], [20, 100], [100, 100]]) 194 // Set the join style of the stroke to Miter. 195 .strokeLineJoin(LineJoinStyle.Miter) 196 // Set the limit on the ratio of the miter length to the value of strokeWidth used to draw a miter join. 197 .strokeMiterLimit(1/Math.sin(45)) 198 Polyline() 199 .width(100) 200 .height(100) 201 .fillOpacity(0) 202 .stroke(Color.Red) 203 .strokeWidth(10) 204 .points([[20, 0], [20, 100], [100, 100]]) 205 .strokeLineJoin(LineJoinStyle.Miter) 206 .strokeMiterLimit(1.42) 207 ``` 208 209 ![2023032405917](figures/2023032405917.jpg) 210 211- Use the **antiAlias** attribute to set whether to enable anti-aliasing. The default value is true, indicating that anti-aliasing is enabled. 212 213 ```ts 214 // Enable anti-aliasing. 215 Circle() 216 .width(150) 217 .height(200) 218 .fillOpacity(0) 219 .strokeWidth(5) 220 .stroke(Color.Black) 221 ``` 222 223 ![untitled](figures/untitled.png) 224 225 ```ts 226 // Disable anti-aliasing. 227 Circle() 228 .width(150) 229 .height(200) 230 .fillOpacity(0) 231 .strokeWidth(5) 232 .stroke(Color.Black) 233 .antiAlias(false) 234 ``` 235 236 ![2023032411518](figures/2023032411518.jpg) 237 238 239## Example Scenario 240 241- Draw a closed path at (-80, -5). The fill color is 0x317AF7, the stroke width is 10, the stroke color is red, and the Join style of the stroke is miter (default value). 242 243 ```ts 244 @Entry 245 @Component 246 struct ShapeExample { 247 build() { 248 Column({ space: 10 }) { 249 Shape() { 250 Path().width(200).height(60).commands('M0 0 L400 0 L400 150 Z') 251 } 252 .viewPort({ x: -80, y: -5, width: 500, height: 300 }) 253 .fill(0x317AF7) 254 .stroke(Color.Red) 255 .strokeWidth(3) 256 .strokeLineJoin(LineJoinStyle.Miter) 257 .strokeMiterLimit(5) 258 }.width('100%').margin({ top: 15 }) 259 } 260 } 261 ``` 262 263 ![scenario-1](figures/scenario-1.jpg) 264 265- Draw a circle with a diameter of 150 mm and a ring with a diameter of 150 mm and a red dotted line (use the shorter side as the diameter if the width and height are different). 266 267 ```ts 268 @Entry 269 @Component 270 struct CircleExample { 271 build() { 272 Column({ space: 10 }) { 273 // Draw a circle whose diameter is 150. 274 Circle({ width: 150, height: 150 }) 275 // Draw a ring with a diameter of 150 mm and a red dotted line. 276 Circle() 277 .width(150) 278 .height(200) 279 .fillOpacity(0) 280 .strokeWidth(3) 281 .stroke(Color.Red) 282 .strokeDashArray([1, 2]) 283 }.width('100%') 284 } 285 } 286 ``` 287 288 ![scenario-2](figures/scenario-2.jpg) 289