跳至主要內容

根据canvas的手写签名组件

init-qy前端开发小程序钉钉大约 3 分钟

背景

由于业务需求,需要在钉钉小程序上实现一个手写签名的组件,参考了网上微信小程序实现手写签名的写法,结合自身实际需求,将其包装成一个 popup 弹出框的样式,同时参考了钉钉审批的手写签名样式。使用到的依赖有mini-ali-ui的 popup 和 button 组件。同时还有一个本地的图标。

{
  "component": true,
  "usingComponents": {
    "popup": "mini-ali-ui-rpx/es/popup/index",
    "button": "mini-ali-ui-rpx/es/button/index"
  }
}

思路

具体实现是根据 canvas 来实现的,小程序端的 canvas 具体 api 大同小异,因此这个组件稍改一下应该在微信侧也能使用。

一些问题

  1. canvas 的宽高必须固定,所以实现是根据实际拿到的宽 width,乘以一个固定比值为高。在组件中直接传递即可。
  2. 必传参数 dpr,参考
    如何解决画布模糊问题open in new window
  3. 或许是我理解错误,save 和 restore 没有实现我想要的效果,所以撤回功能可能需要换一种方式实现。这里去掉了这个功能。
  4. clearRect 不能清除,需要在之前加上一行content.beginPath(),无法理解这个问题如何产生。

附:clearRect 不生效对比图

clearRect不生效
clearRect不生效

实现

<popup
  show="{{show}}"
  animation="{{animation}}"
  position="{{position}}"
  onClose="onCancel"
  zIndex="{{zIndex}}"
>
  <view class="box">
    <slot name="toolbar"
      ><view class="toolbar">
        <button type="text" onTap="onCancel">{{cancelButtonText}}</button>
        <text a:if="{{title}}" class="title">{{title}}</text>
        <button type="text" onTap="onConfirm">{{confirmButtonText}}</button>
      </view></slot
    >
    <canvas
      width="{{width*dpr}}"
      height="{{height*dpr}}"
      style="{{'width:'+(width-4)+'px;height:'+(height-4)+'px;'}}"
      class="sign"
      id="sign"
      onTouchMove="move"
      onTouchStart="start"
      onTouchEnd="end"
      onTouchCancel="cancel"
      onLongTap="tap"
      disable-scroll="{{true}}"
      onTap="tap"
    >
    </canvas>
    <image
      class="clear-icon"
      src="/icon/icon_clear.svg"
      onTap="clearClick"
    ></image>
    <!--适应底部-->
    <view style="height: 24rpx"></view>
  </view>
</popup>