We use essential cookies for the website to function, as well as analytics cookies for analyzing and creating statistics of the website performance. To agree to the use of analytics cookies, click "Accept All". You can manage your preferences at any time by clicking "Cookie Settings" on the footer. More Information.

Only Essential Cookies
Accept All
ReferencesApplication FrameworkArkUIArkTS ComponentsGesture HandlingBasic GesturesPinchGesture

PinchGesture

Phone12+PC/2in113+Tablet12+TV19+Wearable18+

PinchGesture is used to trigger a pinch gesture, which requires two to five fingers with a minimum 5 vp distance between the fingers.

NOTE

This gesture is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version.

To trigger the pinch gesture again after successful recognition, all fingers must be lifted and then make contact again to satisfy the recognition criteria.

APIs

PinchGesture

Phone12+PC/2in113+Tablet12+TV19+Wearable18+

PinchGesture(value?: { fingers?: number; distance?: number })

Sets the parameters for the pinch gesture. Inherits from GestureInterface<T>.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Expand
Name Type Mandatory Description
value { fingers?: number; distance?: number } No

Parameters for the pinch gesture.

- fingers: minimum number of fingers to trigger a pinch. The value ranges from 2 to 5.

Default value: 2

Value range: [2, 5]. Values outside this range are automatically adjusted to the default value.

While more fingers than the minimum number can be pressed to trigger the gesture, only the first fingers of the minimum number participate in gesture calculation.

- distance: minimum recognition distance, in vp. This distance refers to the difference between the current average distance from the multiple finger positions to their center point and the average distance when the fingers first made contact. If this difference meets or exceeds the minimum recognition distance, the pinch gesture is recognized.

Default value: 5

NOTE

Value range: [0, +∞). If the value is less than or equal to 0, it will be converted to the default value.

PinchGesture15+

Phone15+PC/2in115+Tablet15+TV19+Wearable18+

PinchGesture(options?: PinchGestureHandlerOptions)

Sets the parameters for the pinch gesture. Compared with PinchGesture, this API adds the isFingerCountLimited parameter to options, which determines whether to enforce the exact number of fingers touching the screen.

Atomic service API: This API can be used in atomic services since API version 15.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Expand
Name Type Mandatory Description
options PinchGestureHandlerOptions No Parameters of the pinch gesture handler.

Events

NOTE

In fingerList of GestureEvent, the index of a finger corresponds to its position, that is, the ID of a finger in fingerList[index] refers to its index. If a finger is pressed first and does not participate in triggering of the current gesture, its position in fingerList is left empty. You are advised to use fingerInfos.

onActionStart

Phone12+PC/2in113+Tablet12+TV19+Wearable18+

onActionStart(event: (event: GestureEvent) => void)

Triggered after the pinch gesture is recognized.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Expand
Name Type Mandatory Description
event (event: GestureEvent) => void Yes Callback for the pinch event.

onActionUpdate

Phone12+PC/2in113+Tablet12+TV19+Wearable18+

onActionUpdate(event: (event: GestureEvent) => void)

Triggered when the user moves the finger in the pinch gesture on the screen.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Expand
Name Type Mandatory Description
event (event: GestureEvent) => void Yes Callback for the pinch event.

onActionEnd

Phone12+PC/2in113+Tablet12+TV19+Wearable18+

onActionEnd(event: (event: GestureEvent) => void)

Triggered when all fingers are lifted after successful pinch gesture recognition.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Expand
Name Type Mandatory Description
event (event: GestureEvent) => void Yes Callback for the pinch event.

onActionCancel

Phone12+PC/2in113+Tablet12+TV19+Wearable18+

onActionCancel(event: () => void)

Triggered when a touch cancellation event occurs after successful pinch gesture recognition. No gesture event information is returned.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Expand
Name Type Mandatory Description
event () => void Yes Callback for the pinch event.

onActionCancel18+

Phone18+PC/2in118+Tablet18+TV19+Wearable18+

onActionCancel(event: Callback<GestureEvent>)

Triggered when a touch cancellation event occurs after successful pinch gesture recognition. Compared with onActionCancel, this callback returns gesture event information.

Atomic service API: This API can be used in atomic services since API version 18.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Expand
Name Type Mandatory Description
event Callback<GestureEvent> Yes Callback for the pinch event.

Example

Example 1: Implementing Simple Scaling

This example demonstrates the recognition of a three-finger pinch gesture using PinchGesture.

// xxx.ets
@Entry
@Component
struct PinchGestureExample {
  @State scaleValue: number = 1;
  @State pinchValue: number = 1;
  @State pinchX: number = 0;
  @State pinchY: number = 0;

  build() {
    Column() {
      Column() {
        Text('PinchGesture scale:\n' + this.scaleValue)
        Text('PinchGesture center:\n(' + this.pinchX + ',' + this.pinchY + ')')
      }
      .height(200)
      .width(300)
      .padding(20)
      .border({ width: 3 })
      .margin({ top: 100 })
      .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 })
      // The gesture event is triggered by pinching three fingers together.
      .gesture(
      PinchGesture({ fingers: 3 }) // Three-finger pinch gesture for zooming in or out.
        .onActionStart((event: GestureEvent) => {
          console.info('Pinch start')
        })
        .onActionUpdate((event: GestureEvent) => {
          if (event) {
            this.scaleValue = this.pinchValue * event.scale
            this.pinchX = event.pinchCenterX
            this.pinchY = event.pinchCenterY
          }
        })
        .onActionEnd((event: GestureEvent) => {
          this.pinchValue = this.scaleValue
          console.info('Pinch end')
        })
      )
    }.width('100%')
  }
}

Example 2: Implementing Image Scaling with Finger Tracking

This example demonstrates how to implement image scaling with finger tracking by configuring PinchGesture.

// xxx.ets
import { UIContext, display, matrix4 } from '@kit.ArkUI';

@Entry
@Component
struct PinchGestureExample {
  private uiContext: UIContext = new UIContext();
  private contentWidth: number = 0;
  private contentHeight: number = 0;
  private scaleMin: number = 0.3;
  private scaleMax: number = 30.0;
  private screenWidth: number = 0;
  private screenHeight: number = 0;
  @State pntX: number = 0;
  @State pntY: number = 0;
  @State curScale: number = 1;
  @State preScale: number = 1;
  @State offsetX: number = 0;
  @State offsetY: number = 0;
  @State matrix: matrix4.Matrix4Transit = matrix4.identity()
    .translate({ x: this.offsetX, y: this.offsetY })
    .scale({ x: this.curScale, y: this.curScale });

  public updateMatrix(): void {
    this.matrix = matrix4.identity()
      .scale({ x: this.curScale, y: this.curScale })
      .translate({ x: this.uiContext.vp2px(this.offsetX), y: this.uiContext.vp2px(this.offsetY) });
  }

  aboutToAppear(): void {
    this.uiContext = this.getUIContext();
    let screenSize = display.getDefaultDisplaySync();
    this.screenWidth = this.uiContext.px2vp(screenSize.width);
    this.screenHeight = this.uiContext.px2vp(screenSize.height);
  }

  build() {
    Column() {
      // Replace $r('app.media.img') with the image resource file you use.
      Image($r('app.media.img'))
        .objectFit(ImageFit.Contain)
        .draggable(false)
        .onComplete((event) => {
          this.contentWidth = this.uiContext.px2vp(event!.contentWidth);
          this.contentHeight = this.uiContext.px2vp(event!.contentHeight);
        })
        .transform(this.matrix)
    }
    // The gesture event is triggered by a two-finger pinch.
    .gesture(
      PinchGesture({ fingers: 2 }) // Two-finger pinch gesture for zooming in or out.
        .onActionStart((event: GestureEvent) => {
          // Displayed size of the image before scaling
          const displayWidth = this.contentWidth * this.curScale;
          const displayHeight = this.contentHeight * this.curScale;
          // Upper left corner coordinates before scaling
          const left = (this.screenWidth - displayWidth) / 2 + this.offsetX;
          const top = (this.screenHeight - displayHeight) / 2 + this.offsetY;
          // Pinch center position (as a percentage) relative to the upper left corner of the displayed image
          this.pntX = (event.pinchCenterX - left) / displayWidth;
          this.pntY = (event.pinchCenterY - top) / displayHeight;
          // Scale factor before the current operation
          this.preScale = this.curScale;
        })
        .onActionUpdate((event: GestureEvent) => {
          // Target scale factor
          this.curScale = this.preScale * event.scale;
          let targetDisplayWidth = this.contentWidth * this.curScale;
          let targetDisplayHeight = this.contentHeight * this.curScale;
          // Coordinates of the pinch center after scaling
          const pointX = (this.screenWidth - targetDisplayWidth) / 2 + targetDisplayWidth * this.pntX;
          const pointY = (this.screenHeight - targetDisplayHeight) / 2 + targetDisplayHeight * this.pntY;
          // Offset required to align the calculated point (pointX, pointY) with the actual pinch center after scaling
          this.offsetX = event.pinchCenterX - pointX;
          this.offsetY = event.pinchCenterY - pointY;
          this.updateMatrix();
        })
        .onActionEnd((event: GestureEvent) => {
          if (this.curScale < this.scaleMin || this.curScale > this.scaleMax) {
            this.curScale = 1;
            this.offsetX = 0;
            this.offsetY = 0;
            this.updateMatrix();
          }
        })
    )
  }
}

Search in References
Enter a keyword.