• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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