Teach you step by step how to use canvas in ArkTS to implement the signature pad function

1. Screen rotation

● The first function to implement the signature pad is to rotate the screen. There are different ways to rotate the screen in various frameworks. For example: on the H5 side, we generally use the rotate() method in the transform attribute in CSS to force the web page to be horizontally screened, and then implement a series of functions

● In nested third-party APPs, we usually call the method provided by the corresponding SDK to rotate the screen.

● .....

There are many implementation methods, each with its own merits. I believe HarmonyOS will also provide corresponding API methods to set the rotating screen.

I myself use the setPreferredOrientation() method of the Window object to switch between horizontal and vertical screens within the page. Here is the complete code I implemented:

// 在EntryAbility.ts中获取窗口实例并赋值给全局变量,如此所有页面都可以通过全局// 变量去修改窗口信息,不需要重新获取
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage) {
    windowStage.getMainWindow((err, data) => {
      if (err.code) {
        console.error('获取失败' + JSON.stringify(err));
        return;
      }
      console.info('获取主窗口的实例:' + JSON.stringify(data));
      globalThis.windowClass = data // 赋值给全局变量windowClass
    });
  }
}


// 在具体页面中的使用
import window from '@ohos.window';
@Entry
@Componentstruct SignatureBoard {


  onPageShow() {
// 获取旋转的方向,具体可以查看对应文档
    let orientation = window.Orientation.LANDSCAPE_INVERTED;
    try {
      // 设置屏幕旋转
      globalThis.windowClass.setPreferredOrientation(orientation, (err) => {});
    } catch (exception) {
      console.error('设置失败: ' + JSON.stringify(exception));
    }
  }
}

2. canvas canvas

The screen rotation problem is solved, and the signature function is implemented next. Because it has been developed before, just convert the corresponding syntax into ArkTS syntax. The following is code analysis: 2.1 Use canvas component according to official documentation

@Entry@Component
struct SignatureBoard {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)


  build() {
    Column() {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor('#fff')
        .onReady(() => {
        })
    }
    .width('100%')
    .height('100%')
  }
}

2.2 Set the properties of the brush and bind gesture functions. In js, we basically use mouse events to achieve this, but in ArkTS, gesture methods are used to monitor finger operations on the screen. There are many types. You can check the corresponding documents if you need to use them.

build() {
   
       Column() {
   
         Canvas(this.context)        .width('100%')        .height('100%')        .backgroundColor('#fff')        .onReady(() => {
   
             this.context.lineWidth = 3; // 设置画笔的粗细          this.context.strokeStyle = "#000"; // 设置画笔的颜色          // 还可以设置很多,根据自己业务需要        })        .gesture(          PanGesture(this.panOption)            .onActionStart((event: any) => {
   
                  // 手指按下的时候            })            .onActionUpdate((event: any) => {
   
                  // 手指移动的时候            })            .onActionEnd(() => {
   
                  // 手指离开的时候            })        )  }

2.3 By binding the gestures we have implemented, we can realize that the canvas will draw the corresponding trajectory after the finger slides on the screen. Some canvas functions will be used here.

@Entry
@Componentstruct SignatureBoard {
  private lastX: number = 0;
  private lastY: number = 0;
  private isDown: Boolean = false;
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All, distance: 1 })
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)


  draw(startX, startY, endX, endY) {
    // 起点
    this.context.moveTo(startX, startY);
    // 终点
    this.context.lineTo(endX, endY);
    // 调用 stroke,即可看到绘制的线条
    this.context.stroke();
  }
  build() {
    Column() {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor('#fff')
        .onReady(() => {
          this.context.lineWidth = 3;
          this.context.strokeStyle = "#000";
        })
        .gesture(
          PanGesture(this.panOption)
            .onActionStart((event: any) => {
              this.isDown = true;
              // 按下时的点作为起点
              this.lastX = event.localX;
              this.lastY = event.localY;
              // 创建一个新的路径
              this.context.beginPath();
            })
            .onActionUpdate((event: any) => {
              // 没有按下就不管
              if (!this.isDown) return;
              const offsetX = event.localX
              const offsetY = event.localY
              // 调用绘制方法
              this.draw(this.lastX, this.lastY, offsetX, offsetY);
              // 把当前移动时的坐标作为下一次的绘制路径的起点
              this.lastX = offsetX;
              this.lastY = offsetY;
            })
            .onActionEnd(() => {
              this.isDown = false;
              // 关闭路径
              this.context.closePath();
            })
        )
    }
    .width('100%')
    .height('100%')
  }
}

The above is our complete idea and code for implementing the signature board. There are a few points that need to be noted:

1. When creating a new PanGestureOptions instance, you need to set the distance smaller. The smaller the value, the higher the sensitivity.

2. For the event parameter in the callback method of PanGesture, the official default attribute type is GestureEvent. However, when I checked the attribute in the editor source code, we did not define the localX and localY we wanted, but it was actually returned. If I use the editor directly, an error will be reported. Therefore, the event needs to be set to any type, so that it can be obtained without reporting an error.

This time I will share these functions of the Canvas Signature Pad. I hope it can help all developers. We will continue to share more tools that are frequently used in projects in the future.

Guess you like

Origin blog.csdn.net/HarmonyOSDev/article/details/135103743