• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# PinchGesture
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @jiangtao92-->
5<!--Designer: @piggyguy-->
6<!--Tester: @songyanhong-->
7<!--Adviser: @HelloCrease-->
8
9用于触发捏合手势,触发捏合手势的最少手指为2指,最大为5指,最小识别距离为5vp。
10
11>  **说明:**
12>
13>  从API version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
14>
15>  在捏合手势触发成功后,需要抬起所有手指,重新按下进行捏合才能再次触发捏合手势。
16
17
18## 接口
19
20### PinchGesture
21
22PinchGesture(value?: { fingers?: number; distance?: number })
23
24继承自[GestureInterface\<T>](ts-gesture-common.md#gestureinterfacet11),设置捏合手势事件。
25
26**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
27
28**系统能力:** SystemCapability.ArkUI.ArkUI.Full
29
30**参数:**
31
32| 参数名 | 类型 | 必填 | 说明 |
33| -------- | -------- | -------- | -------- |
34| value | { fingers?: number; distance?: number } | 否 | 设置捏合手势事件参数。<br> - fingers:触发捏合的最少手指数,&nbsp;最小为2指,最大为5指。<br/>默认值:2 <br/>触发手势手指可以多于fingers数目,但只有先落下的与fingers相同数目的手指参与手势计算。<br> - distance:最小识别距离,单位为vp。<br/>默认值:5 <br/>**说明:** <br/>取值范围:[0, +∞)。当识别距离的值小于等于0时,会被转化为默认值。 |
35
36### PinchGesture<sup>15+</sup>
37
38PinchGesture(options?: PinchGestureHandlerOptions)
39
40设置捏合手势事件。与[PinchGesture](#pinchgesture-1)相比,options参数新增了对isFingerCountLimited参数,表示是否检查触摸屏幕的手指数量。
41
42**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。
43
44**系统能力:** SystemCapability.ArkUI.ArkUI.Full
45
46**参数:**
47
48| 参数名 | 类型 | 必填 | 说明 |
49| -------- | -------- | -------- | -------- |
50| options | [PinchGestureHandlerOptions](./ts-gesturehandler.md#pinchgesturehandleroptions) | 否 | 捏合手势处理器配置参数。 |
51
52
53## 事件
54
55>  **说明:**
56>
57>  在[GestureEvent](ts-gesture-common.md#gestureevent对象说明)的fingerList元素中,手指索引编号与位置相对应,即fingerList[index]的id为index。对于先按下但未参与当前手势触发的手指,fingerList中对应的位置为空。建议优先使用fingerInfos。
58
59### onActionStart
60
61onActionStart(event: (event: GestureEvent) => void)
62
63Pinch手势识别成功回调。
64
65**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
66
67**系统能力:** SystemCapability.ArkUI.ArkUI.Full
68
69**参数:**
70
71| 参数名 | 类型                                       | 必填 | 说明                         |
72| ------ | ------------------------------------------ | ---- | ---------------------------- |
73| event  | (event: [GestureEvent](ts-gesture-common.md#gestureevent对象说明)) => void | 是   | 手势事件回调函数。 |
74
75### onActionUpdate
76
77onActionUpdate(event: (event: GestureEvent) => void)
78
79Pinch手势移动过程中回调。
80
81**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
82
83**系统能力:** SystemCapability.ArkUI.ArkUI.Full
84
85**参数:**
86
87| 参数名 | 类型                                       | 必填 | 说明                         |
88| ------ | ------------------------------------------ | ---- | ---------------------------- |
89| event  |  (event: [GestureEvent](ts-gesture-common.md#gestureevent对象说明)) => void | 是   | 手势事件回调函数。 |
90
91### onActionEnd
92
93onActionEnd(event: (event: GestureEvent) => void)
94
95Pinch手势识别成功,手指抬起后触发回调。
96
97**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
98
99**系统能力:** SystemCapability.ArkUI.ArkUI.Full
100
101**参数:**
102
103| 参数名 | 类型                                       | 必填 | 说明                      |
104| ------ | ------------------------------------------ | ---- | ---------------------------- |
105| event  |  (event: [GestureEvent](ts-gesture-common.md#gestureevent对象说明)) => void | 是   | 手势事件回调函数。 |
106
107### onActionCancel
108
109onActionCancel(event: () => void)
110
111Pinch手势识别成功,接收到触摸取消事件触发回调。返回手势事件信息。
112
113**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
114
115**系统能力:** SystemCapability.ArkUI.ArkUI.Full
116
117**参数:**
118
119| 参数名 | 类型                                       | 必填 | 说明                      |
120| ------ | ------------------------------------------ | ---- | ---------------------------- |
121| event  |  () => void | 是   | 手势事件回调函数。 |
122
123### onActionCancel<sup>18+</sup>
124
125onActionCancel(event: Callback\<GestureEvent\>)
126
127Pinch手势识别成功,接收到触摸取消事件触发回调。返回手势事件信息。
128
129**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
130
131**系统能力:** SystemCapability.ArkUI.ArkUI.Full
132
133**参数:**
134
135| 参数名 | 类型                                       | 必填 | 说明                         |
136| ------ | ------------------------------------------ | ---- | ---------------------------- |
137| event  |  Callback\<[GestureEvent](ts-gesture-common.md#gestureevent对象说明)> | 是   | 手势事件回调函数。 |
138
139## 示例
140
141### 示例1(实现简单缩放)
142
143该示例通过配置PinchGesture实现了三指捏合手势的识别。
144
145```ts
146// xxx.ets
147@Entry
148@Component
149struct PinchGestureExample {
150  @State scaleValue: number = 1;
151  @State pinchValue: number = 1;
152  @State pinchX: number = 0;
153  @State pinchY: number = 0;
154
155  build() {
156    Column() {
157      Column() {
158        Text('PinchGesture scale:\n' + this.scaleValue)
159        Text('PinchGesture center:\n(' + this.pinchX + ',' + this.pinchY + ')')
160      }
161      .height(200)
162      .width(300)
163      .padding(20)
164      .border({ width: 3 })
165      .margin({ top: 100 })
166      .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 })
167      // 三指捏合触发该手势事件
168      .gesture(
169      PinchGesture({ fingers: 3 })
170        .onActionStart((event: GestureEvent) => {
171          console.info('Pinch start')
172        })
173        .onActionUpdate((event: GestureEvent) => {
174          if (event) {
175            this.scaleValue = this.pinchValue * event.scale
176            this.pinchX = event.pinchCenterX
177            this.pinchY = event.pinchCenterY
178          }
179        })
180        .onActionEnd((event: GestureEvent) => {
181          this.pinchValue = this.scaleValue
182          console.info('Pinch end')
183        })
184      )
185    }.width('100%')
186  }
187}
188```
189
190 ![zh-cn_image_0000001174582848](figures/zh-cn_image_0000001174582848.png)
191
192### 示例2(实现图片跟手缩放)
193
194该示例通过配置PinchGesture实现了图片的跟手缩放效果。
195
196```ts
197// xxx.ets
198import { UIContext, display, matrix4 } from '@kit.ArkUI';
199
200@Entry
201@Component
202struct PinchGestureExample {
203  private uiContext: UIContext = new UIContext();
204  private contentWidth: number = 0;
205  private contentHeight: number = 0;
206  private scaleMin: number = 0.3;
207  private scaleMax: number = 30.0;
208  private screenWidth: number = 0;
209  private screenHeight: number = 0;
210  @State pntX: number = 0;
211  @State pntY: number = 0;
212  @State curScale: number = 1;
213  @State preScale: number = 1;
214  @State offsetX: number = 0;
215  @State offsetY: number = 0;
216  @State matrix: matrix4.Matrix4Transit = matrix4.identity()
217    .translate({ x: this.offsetX, y: this.offsetY })
218    .scale({ x: this.curScale, y: this.curScale });
219
220  public updateMatrix(): void {
221    this.matrix = matrix4.identity()
222      .scale({ x: this.curScale, y: this.curScale })
223      .translate({ x: this.uiContext.vp2px(this.offsetX), y: this.uiContext.vp2px(this.offsetY) });
224  }
225
226  aboutToAppear(): void {
227    this.uiContext = this.getUIContext();
228    let screenSize = display.getDefaultDisplaySync();
229    this.screenWidth = this.uiContext.px2vp(screenSize.width);
230    this.screenHeight = this.uiContext.px2vp(screenSize.height);
231  }
232
233  build() {
234    Column() {
235      // $r('app.media.img')需要替换为开发者所需的图像资源文件。
236      Image($r('app.media.img'))
237        .objectFit(ImageFit.Contain)
238        .draggable(false)
239        .onComplete((event) => {
240          this.contentWidth = this.uiContext.px2vp(event!.contentWidth);
241          this.contentHeight = this.uiContext.px2vp(event!.contentHeight);
242        })
243        .transform(this.matrix)
244    }
245    // 双指捏合触发该手势事件
246    .gesture(
247      PinchGesture({ fingers: 2 })
248        .onActionStart((event: GestureEvent) => {
249          // 图片本次缩放前展示大小
250          const displayWidth = this.contentWidth * this.curScale;
251          const displayHeight = this.contentHeight * this.curScale;
252          // 图片本次缩放前左上角顶点
253          const left = (this.screenWidth - displayWidth) / 2 + this.offsetX;
254          const top = (this.screenHeight - displayHeight) / 2 + this.offsetY;
255          // 本次缩放前手指终点相对图片左上角顶点尺寸占图片展示尺寸的百分比
256          this.pntX = (event.pinchCenterX - left) / displayWidth;
257          this.pntY = (event.pinchCenterY - top) / displayHeight;
258          // 图片本次缩放前的缩放比例
259          this.preScale = this.curScale;
260        })
261        .onActionUpdate((event: GestureEvent) => {
262          // 目标缩放比
263          this.curScale = this.preScale * event.scale;
264          let targetDisplayWidth = this.contentWidth * this.curScale;
265          let targetDisplayHeight = this.contentHeight * this.curScale;
266          // 本次缩放前手指中点在本次缩放后的坐标
267          const pointX = (this.screenWidth - targetDisplayWidth) / 2 + targetDisplayWidth * this.pntX;
268          const pointY = (this.screenHeight - targetDisplayHeight) / 2 + targetDisplayHeight * this.pntY;
269          // 将pointX、pointY移动到缩放后的手指中点,需要移动的距离
270          this.offsetX = event.pinchCenterX - pointX;
271          this.offsetY = event.pinchCenterY - pointY;
272          this.updateMatrix();
273        })
274        .onActionEnd((event: GestureEvent) => {
275          if (this.curScale < this.scaleMin || this.curScale > this.scaleMax) {
276            this.curScale = 1;
277            this.offsetX = 0;
278            this.offsetY = 0;
279            this.updateMatrix();
280          }
281        })
282    )
283  }
284}
285```
286
287 ![image_pinch](figures/image_pinch.gif)
288