DEV Community

HarmonyOS
HarmonyOS

Posted on

Using the gyroscope to detect wrist gestures with ArkTS

Read the original article:Using the gyroscope to detect wrist gestures with ArkTS


Photo by Hugöl Hälpingston on Unsplash

Introduction

Welcome all. In this article, we will learn how to use the SensorServiceKit, focusing on the gyroscope to detect wrist gestures.

Please note that this project requires a real device.

User Interface
We will create a basic user interface with a button and open/close state.

@Entry
@Component
struct Index {
  @State isOpen: boolean = false;

  build() {
    RelativeContainer() {
      Button() {
        SymbolGlyph($r(this.isOpen
          ? 'sys.symbol.sun_max_fill_1' 
          : 'sys.symbol.moon_fill'))
          .fontSize(24)
          .fontColor([this.isOpen ? Color.Yellow : Color.White])
      }
      .type(ButtonType.Circle)
      .backgroundColor(this.isOpen ? $r('app.color.sky_blue') : Color.Gray)
      .size({ width: '50%', height: '50%' })
      .onClick(() => {
        this.isOpen = !this.isOpen
      })
      .alignRules({
        middle: { anchor: '__container__', align: HorizontalAlign.Center },
        center: { anchor: '__container__', align: VerticalAlign.Center }
      })
    }
    .size({ width: '100%', height: '100%' })
  }
}
Enter fullscreen mode Exit fullscreen mode

The result should look like this:

Sensor
Before all, add the gyroscope permission to module.json5.

"requestPermissions": [
  {
    "name": "ohos.permission.GYROSCOPE"
  }
]
Enter fullscreen mode Exit fullscreen mode

Start by importing the library.

import { sensor } from '@kit.SensorServiceKit';
Enter fullscreen mode Exit fullscreen mode

Start and stop the sensor.

aboutToAppear(): void {
  sensor.on(sensor.SensorId.GYROSCOPE, async (res) => {
    console.log(JSON.stringify(res))
  })
}

aboutToDisappear(): void {
  sensor.off(sensor.SensorId.GYROSCOPE)
}
Enter fullscreen mode Exit fullscreen mode

You should be able to see the sensor data in the console.

Time to implement the gesture function. We will change the open/close state when users twist their wrist twice in a row.

To achieve this result, we will track the positive and negative movements and create a twist history.

Define parameters:

// store positive movements
private pos_x_history: number[] = new Array(4).fill(0)
// store negative movements
private neg_x_history: number[] = new Array(4).fill(0)
// store twists
private twistHistory: boolean[] = new Array(5).fill(false)

private getPosX() {
  return this.pos_x_history.reduce((a, b) => a + b, 0)
}

private getNegX() {
  return this.neg_x_history.reduce((a, b) => a + b, 0)
}
Enter fullscreen mode Exit fullscreen mode

We will keep the newest data and remove the old ones.

// add data
private _pushToPosX(val: number) {
  this.pos_x_history.shift()
  this.pos_x_history.push(val)
}

private _pushToNegX(val: number) {
  this.neg_x_history.shift()
  this.neg_x_history.push(val)
}

private _pushToHistory(val: boolean) {
  this.twistHistory.shift()
  this.twistHistory.push(val)
}
Enter fullscreen mode Exit fullscreen mode

Finally, modify the sensor listener.

aboutToAppear(): void {
  sensor.on(sensor.SensorId.GYROSCOPE, async (res) => {
    if (res.x >= 0) {
      this._pushToPosX(res.x)
      this._pushToNegX(0)
    } else {
      this._pushToPosX(0)
      this._pushToNegX(res.x)
    }

    if (this.getPosX() >= 13 && this.getNegX() <= -13) {
      this.pos_x_history = new Array(4).fill(0)
      this.neg_x_history = new Array(4).fill(0)
      this._pushToHistory(true)
    } else {
      this._pushToHistory(false)
    }

    if (this.twistHistory.filter((val) => val).length >= 2) {
      this.twistHistory = new Array(5).fill(false)
      this.isOpen = !this.isOpen
    }
  })
}
Enter fullscreen mode Exit fullscreen mode

Final Result

Conclusion

That's all for this article. We have covered how to use the gyroscope sensor. For more details and sensors, check out the official documentation. See you all in new adventures. :)

~ Fortuna Favet Fortibus

Written by Mehmet Karaaslan

Top comments (0)