• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Shape
2
3绘制组件的父组件,父组件中会描述所有绘制组件均支持的通用属性。
4
51、绘制组件使用Shape作为父组件,实现类似SVG的效果。
6
72、绘制组件单独使用,用于在页面上绘制指定的图形。
8
9>  **说明:**
10>
11>  该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
12
13
14## 权限列表
15
1617
18
19## 子组件
20
21可以包含子组件。
22
23
24## 接口
25
26Shape(value?: PixelMap)
27
28**参数:**
29
30| 参数名 | 参数类型 | 必填 | 默认值 | 参数描述 |
31| -------- | -------- | -------- | -------- | -------- |
32| value | [PixelMap](../apis/js-apis-image.md#pixelmap7) | 否 | - | 绘制目标,可将图形绘制在指定的PixelMap对象中,若未设置,则在当前绘制目标中进行绘制。 |
33
34
35## 属性
36
37除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性:
38
39| 名称 | 类型 | 默认值 | 必填 | 描述 |
40| -------- | -------- | -------- | -------- | -------- |
41| viewPort | {<br/>x?:&nbsp;number \| string,<br/>y?:&nbsp;number \| string,<br/>width?:&nbsp;number \| string,<br/>height?:&nbsp;number \| string<br/>} | { x:0, y:0, width:0, height:0 } | 否 | 形状的视口。 |
42| fill | [ResourceColor](ts-types.md#resourcecolor8) | Color.Black | 否 | 设置填充区域颜色。 |
43| fillOpacity | number&nbsp;\|&nbsp;string&nbsp;\|&nbsp;[Resource](ts-types.md#resource) | 1 | 否 | 设置填充区域透明度。 |
44| stroke | [ResourceColor](ts-types.md#resourcecolor8) | - | 否 | 设置边框颜色,不设置时,默认没有边框线条。 |
45| strokeDashArray | Array&lt;Length&gt; | [] | 否 | 设置边框间隙。 |
46| strokeDashOffset | number&nbsp;\|&nbsp;string | 0 | 否 | 边框绘制起点的偏移量。 |
47| strokeLineCap | [LineCapStyle](ts-appendix-enums.md#linecapstyle) | LineCapStyle.Butt | 否 | 设置边框端点绘制样式。 |
48| strokeLineJoin | [LineJoinStyle](ts-appendix-enums.md#linejoinstyle) | LineJoinStyle.Miter | 否 | 设置边框拐角绘制样式。 |
49| strokeMiterLimit | number&nbsp;\|&nbsp;string | 4 | 否 | 设置斜接长度与边框宽度比值的极限值。斜接长度表示外边框外边交点到内边交点的距离,边框宽度即strokeWidth属性的值。<br/>**说明:**<br/>该属性取值需大于等于1,且在strokeLineJoin属性取值LineJoinStyle.Miter时生效。 |
50| strokeOpacity | number&nbsp;\|&nbsp;string&nbsp;\|&nbsp;[Resource](ts-types.md#resource) | 1 | 否 | 设置边框透明度。<br/>**说明:**<br/>该属性的取值范围是[0.0, 1.0],若给定值小于0.0,则取值为0.0;若给定值大于1.0,则取值为1.0。 |
51| strokeWidth | number&nbsp;\|&nbsp;string | 1 | 否 | 设置边框宽度。 |
52| antiAlias | boolean | true | 否 | 是否开启抗锯齿效果。 |
53| mesh<sup>8+</sup> | Array&lt;number&gt;,number,number | [],0,0 | 否 | 设置mesh效果。第一个参数为长度(column + 1)* (row + 1)* 2的数组,它记录了扭曲后的位图各个顶点位置,第二个参数为mesh矩阵列数column,第三个参数为mesh矩阵行数row。 |
54
55## 示例
56
57### 示例1
58
59```ts
60// xxx.ets
61@Entry
62@Component
63struct ShapeExample {
64  build() {
65    Column({ space: 10 }) {
66      Text('basic').fontSize(11).fontColor(0xCCCCCC).width(320)
67      // 在Shape的(-2, -2)点绘制一个 300 * 50 带边框的矩形,颜色0x317AF7,边框颜色黑色,边框宽度4,边框间隙20,向左偏移10,线条两端样式为半圆,拐角样式圆角,抗锯齿(默认开启)
68      // 在Shape的(-2, 58)点绘制一个 300 * 50 带边框的椭圆,颜色0x317AF7,边框颜色黑色,边框宽度4,边框间隙20,向左偏移10,线条两端样式为半圆,拐角样式圆角,抗锯齿(默认开启)
69      // 在Shape的(-2, 118)点绘制一个 300 * 10 直线路径,颜色0x317AF7,边框颜色黑色,宽度4,间隙20,向左偏移10,线条两端样式为半圆,拐角样式圆角,抗锯齿(默认开启)
70      Shape() {
71        Rect().width(300).height(50)
72        Ellipse().width(300).height(50).offset({ x: 0, y: 60 })
73        Path().width(300).height(10).commands('M0 0 L900 0').offset({ x: 0, y: 120 })
74      }
75      .viewPort({ x: -2, y: -2, width: 304, height: 130 })
76      .fill(0x317AF7)
77      .stroke(Color.Black)
78      .strokeWidth(4)
79      .strokeDashArray([20])
80      .strokeDashOffset(10)
81      .strokeLineCap(LineCapStyle.Round)
82      .strokeLineJoin(LineJoinStyle.Round)
83      .antiAlias(true)
84      // 分别在Shape的(0, 0)、(-5, -5)点绘制一个 300 * 50 带边框的矩形,可以看出之所以将视口的起始位置坐标设为负值是因为绘制的起点默认为线宽的中点位置,因此要让边框完全显示则需要让视口偏移半个线宽
85      Shape() {
86        Rect().width(300).height(50)
87      }
88      .viewPort({ x: 0, y: 0, width: 320, height: 70 })
89      .fill(0x317AF7)
90      .stroke(Color.Black)
91      .strokeWidth(10)
92
93      Shape() {
94        Rect().width(300).height(50)
95      }
96      .viewPort({ x: -5, y: -5, width: 320, height: 70 })
97      .fill(0x317AF7)
98      .stroke(Color.Black)
99      .strokeWidth(10)
100
101      Text('path').fontSize(11).fontColor(0xCCCCCC).width(320)
102      // 在Shape的(0, -5)点绘制一条直线路径,颜色0xEE8443,线条宽度10,线条间隙20
103      Shape() {
104        Path().width(300).height(10).commands('M0 0 L900 0')
105      }
106      .viewPort({ x: 0, y: -5, width: 300, height: 20 })
107      .stroke(0xEE8443)
108      .strokeWidth(10)
109      .strokeDashArray([20])
110      // 在Shape的(0, -5)点绘制一条直线路径,颜色0xEE8443,线条宽度10,线条间隙20,向左偏移10
111      Shape() {
112        Path().width(300).height(10).commands('M0 0 L900 0')
113      }
114      .viewPort({ x: 0, y: -5, width: 300, height: 20 })
115      .stroke(0xEE8443)
116      .strokeWidth(10)
117      .strokeDashArray([20])
118      .strokeDashOffset(10)
119      // 在Shape的(0, -5)点绘制一条直线路径,颜色0xEE8443,线条宽度10,透明度0.5
120      Shape() {
121        Path().width(300).height(10).commands('M0 0 L900 0')
122      }
123      .viewPort({ x: 0, y: -5, width: 300, height: 20 })
124      .stroke(0xEE8443)
125      .strokeWidth(10)
126      .strokeOpacity(0.5)
127      // 在Shape的(0, -5)点绘制一条直线路径,颜色0xEE8443,线条宽度10,线条间隙20,线条两端样式为半圆
128      Shape() {
129        Path().width(300).height(10).commands('M0 0 L900 0')
130      }
131      .viewPort({ x: 0, y: -5, width: 300, height: 20 })
132      .stroke(0xEE8443)
133      .strokeWidth(10)
134      .strokeDashArray([20])
135      .strokeLineCap(LineCapStyle.Round)
136      // 在Shape的(-80, -5)点绘制一个封闭路径,颜色0x317AF7,线条宽度10,边框颜色0xEE8443,拐角样式锐角(默认值)
137      Shape() {
138        Path().width(200).height(60).commands('M0 0 L400 0 L400 150 Z')
139      }
140      .viewPort({ x: -80, y: -5, width: 310, height: 90 })
141      .fill(0x317AF7)
142      .stroke(0xEE8443)
143      .strokeWidth(10)
144      .strokeLineJoin(LineJoinStyle.Miter)
145      .strokeMiterLimit(5)
146    }.width('100%').margin({ top: 15 })
147  }
148}
149```
150
151![zh-cn_image_0000001184628104](figures/zh-cn_image_0000001184628104.png)
152
153### 示例2
154
155```ts
156// xxx.ets
157@Entry
158@Component
159struct ShapeMeshExample {
160  @State columnVal: number = 0;
161  @State rowVal: number = 0;
162  @State count: number = 0;
163  @State verts: Array<number> = [];
164  @State shapeWidth: number = 600;
165  @State shapeHeight: number = 600;
166
167  build() {
168    Column() {
169      Shape() {
170        Rect()
171          .width('250px')
172          .height('250px')
173          .radiusWidth('10px')
174          .radiusHeight('10px')
175          .stroke('10px')
176          .margin({ left: '10px', top: '10px' })
177          .strokeWidth('10px')
178          .fill(Color.Blue)
179        Rect()
180          .width('250px')
181          .height('250px')
182          .radiusWidth('10px')
183          .radiusHeight('10px')
184          .stroke('10px')
185          .margin({ left: '270px', top: '10px' })
186          .strokeWidth('10px')
187          .fill(Color.Red)
188      }
189      .mesh(this.verts, this.columnVal, this.rowVal)
190      .width(this.shapeWidth + 'px')
191      .height(this.shapeHeight + 'px')
192      // 手指触摸Shape组件时会显示mesh扭曲效果
193      .onTouch((event: TouchEvent) => {
194        var touchX = event.touches[0].x * 2;
195        var touchY = event.touches[0].y * 2;
196        this.columnVal = 20;
197        this.rowVal = 20;
198        this.count = (this.columnVal + 1) * (this.rowVal + 1);
199        var orig = [this.count * 2];
200        var index = 0;
201        for (var i = 0; i <= this.rowVal; i++) {
202          var fy = this.shapeWidth * i / this.rowVal;
203          for (var j = 0; j <= this.columnVal; j++) {
204            var fx = this.shapeWidth * j / this.columnVal;
205            orig[index * 2 + 0] = this.verts[index * 2 + 0] = fx;
206            orig[index * 2 + 1] = this.verts[index * 2 + 1] = fy;
207            index++;
208          }
209        }
210        for (var k = 0; k < this.count * 2; k += 2) {
211          var dx = touchX - orig[k + 0];
212          var dy = touchY - orig[k + 1];
213          var dd = dx * dx + dy * dy;
214          var d = Math.sqrt(dd);
215          var pull = 80000 / (dd * d);
216          if (pull >= 1) {
217            this.verts[k + 0] = touchX;
218            this.verts[k + 1] = touchY;
219          } else {
220            this.verts[k + 0] = orig[k + 0] + dx * pull;
221            this.verts[k + 1] = orig[k + 1] + dy * pull;
222          }
223        }
224      })
225    }
226    .width('600px')
227    .height('600px')
228    .border({ width: 3, color: Color.Black })
229  }
230}
231```
232
233示意图:
234
235![zh-cn_image1_0000001184628104](figures/zh-cn_image1_0000001184628104.png)
236
237手指触摸Shape组件时会显示mesh扭曲效果:
238
239![zh-cn_image2_0000001184628104](figures/zh-cn_image2_0000001184628104.png)