【HarmonyOS NEXT】使用Canvas实现手写签名

  1. 封装SignatureBoard组件
import { image } from '@kit.ImageKit';

@Component
export struct SignatureBoard {
  private boardWidth: number = 300
  private boardHeight: number = 200
  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)
  onConfirm: (pixelMap: image.PixelMap) => void = () => {
  }

  draw(startX: number, startY: number, endX: number, endY: number) {
    // 起点
    this.context.moveTo(startX, startY);
    // 终点
    this.context.lineTo(endX, endY);
    // 调用 stroke,即可看到绘制的线条
    this.context.stroke();
  }

  build() {
    Column({ space: 10 }) {
      Canvas(this.context)
        .width(this.boardWidth)
        .height(this.boardHeight)
        .backgroundColor('#fff')
        .borderRadius(6)
        .border({ width: 1, color: Color.Gray })
        .onReady(() => {
          this.context.lineWidth = 3; // 设置画笔的粗细
          this.context.strokeStyle = "#000"; // 设置画笔的颜色
        })
        .gesture(
          PanGesture(this.panOption)
            .onActionStart((event) => {
              this.isDown = true;
              // 按下时的点作为起点
              this.lastX = event.fingerList[0].localX
              this.lastY = event.fingerList[0].localY
              // 创建一个新的路径
              this.context.beginPath();
            })
            .onActionUpdate((event) => {
              // 没有按下就不管
              if (!this.isDown) return
              const offsetX = event.fingerList[0].localX
              const offsetY = event.fingerList[0].localY
              // 调用绘制方法
              this.draw(this.lastX, this.lastY, offsetX, offsetY)
              // 把当前移动时的坐标作为下一次的绘制路径的起点
              this.lastX = offsetX
              this.lastY = offsetY
            })
            .onActionEnd(() => {
              this.isDown = false;
              // 关闭路径
              this.context.closePath();
            })
        )

      Row({ space: 10 }) {
        Button('重签')
          .onClick(() => {
            this.context.clearRect(0, 0, this.boardWidth, this.boardHeight)
          })

        Button('确认')
          .onClick(() => {
            const img = this.context.getPixelMap(0, 0, this.boardWidth, this.boardHeight)
            this.onConfirm(img)
          })
      }
    }
  }
}
  1. 引入SignatureBoard组件
import { image } from '@kit.ImageKit'
import { SignatureBoard } from './components'

@Entry
@Component
struct SignatureBoardPage {
  @State img: image.PixelMap | null = null

  build() {
    Column({ space: 10 }) {
      SignatureBoard({
        onConfirm: (pixelMap) => {
          this.img = pixelMap
        }
      })
    }
    .padding({ top: 80 })
    .width('100%')
    .height('100%')
  }
}
  1. 使用Image组件测试
Image(this.img)
    .width(300)
    .height(200)
    .objectFit(ImageFit.Auto)
    .borderRadius(6)
    .border({
      width: 1,
      color: Color.Gray
    })
  1. 效果图
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值