更新记录

1.0.9(2026-02-09) 下载此版本

修复

  • 修复画布高度初始值为 0 导致的循环依赖问题,设置默认值为基准高度避免样式异常

1.0.8(2026-02-06) 下载此版本

优化

  • 优化水印自适应,根据画布高度和文字长度动态计算字体大小,防止超出画布
  • 移除所有 rpx 单位,改用 px 配合动态缩放,适配不同屏幕尺寸

1.0.7(2026-02-05) 下载此版本

新增

  • 新增水印提示功能

优化

  • 修复 H5 端旋转两次的问题

移除

  • 移除 APP 端支持
查看更多

平台兼容性

uni-app(4.62)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× - - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - -

其他

多语言 暗黑模式 宽屏模式
× ×

signature-board 手写签名板

简介

横屏手写签名组件,H5 和微信小程序输出 base64 格式。

特性

  • ✅ 横屏签名
  • ✅ H5/微信小程序输出 base64
  • ✅ 自定义线条颜色、粗细、按钮样式
  • ✅ 支持自适应水印提示
  • ✅ 动态缩放系统,适配不同屏幕尺寸
  • ✅ 支持 Vue2/Vue3
  • ✅ 无第三方依赖

安装

方式一:通过 uni_modules 导入(推荐)

  1. 在 DCloud 插件市场找到本插件
  2. 点击右侧的 使用 HBuilderX 导入插件下载插件ZIP
  3. 导入到项目的 uni_modules 目录

方式二:手动导入

signature-board 文件夹复制到项目的 uni_modules 目录下。

使用方法

基础使用

<template>
  <view style="width: 100vw; height: 100vh;">
    <signature-board @confirm="handleConfirm" />
  </view>
</template>

<script setup>
const handleConfirm = (result) => {
  console.log('签名 base64:', result.tempFilePath);
};
</script>

在弹窗中使用

<template>
  <uni-popup ref="popup" type="center">
    <view style="width: 90vw; height: 70vh;">
      <signature-board @cancel="popup.close()" @confirm="handleConfirm" />
    </view>
  </uni-popup>
</template>

<script setup>
import { ref } from 'vue';
const popup = ref(null);

const handleConfirm = (result) => {
  console.log('签名 base64:', result.tempFilePath);
  popup.value.close();
};
</script>

自定义样式和水印

<signature-board
  :lineWidth="5"
  lineColor="#FF0000"
  primaryColor="#007AFF"
  :rotateAngle="180"
  watermark="请签名"
  @confirm="handleConfirm"
/>

说明

  • rotateAngle 支持 0、90、180、270 度
  • watermark 设置水印提示文字,组件会根据画布大小和文字长度自动调整字体大小

API

Props

参数 说明 类型 默认值
lineWidth 签名线条粗细 Number 3
lineColor 签名线条颜色 String #000000
bgColor 画布背景颜色 String #FFFFFF
rotateAngle 旋转角度 Number 90
watermark 水印提示文字 String ''
cancelText 取消按钮文字 String 取消
resetText 重写按钮文字 String 重写
confirmText 确认按钮文字 String 确认
emptyTip 未签名提示文字 String 请先签名
errorTip 生成失败提示文字 String 生成签名失败
primaryColor 主题颜色 String #784E23
resetBgColor 重写按钮背景颜色 String #CCCCCC

Events

事件名 说明 回调参数
cancel 点击取消按钮时触发 -
reset 点击重写按钮时触发 -
confirm 点击确认按钮时触发 { tempFilePath: string }

返回值

{
  tempFilePath: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...'
}

平台差异

平台 输出格式 旋转
H5 base64 支持自定义角度
微信小程序 base64 支持自定义角度

注意事项

  1. 组件占满父容器 100% 宽高,需设置父容器尺寸
  2. 在弹窗中使用时,确保弹窗已完全显示后再渲染组件
  3. 旋转角度必须是 90 的倍数(0、90、180、270)
  4. 组件使用动态缩放系统,所有尺寸会根据画布高度自动适配,初始值为基准高度(747px)
  5. 水印文字会根据画布大小和文字长度自动调整字体大小,防止超出画布

常见问题

Q1: 微信小程序报错 "Canvas 尺寸无效"

问题原因: 在弹窗(uni-popup)中使用时,组件可能在弹窗完全打开前就开始初始化,导致无法正确获取 Canvas 容器尺寸。

解决方案

使用 v-if 控制组件渲染时机,确保弹窗完全打开后再渲染组件:

<template>
  <uni-popup ref="popup" @change="handlePopupChange">
    <view class="popup-container">
      <!-- 使用 v-if 控制渲染时机 -->
      <signature-board v-if="showSignature" @cancel="handleCancel" @confirm="handleConfirm" />
    </view>
  </uni-popup>
</template>

<script setup>
import { ref } from 'vue';

const popup = ref(null);
const showSignature = ref(false);

const handlePopupChange = (e) => {
  if (e.show) {
    // 弹窗打开后延迟渲染组件
    setTimeout(() => {
      showSignature.value = true;
    }, 100);
  } else {
    // 弹窗关闭时销毁组件
    showSignature.value = false;
  }
};

const handleCancel = () => {
  popup.value.close();
};

const handleConfirm = (result) => {
  console.log('签名完成:', result.tempFilePath);
  popup.value.close();
};
</script>

关键点

  1. 使用 v-if 而不是 v-show,确保组件完全重新初始化
  2. 监听弹窗的 @change 事件
  3. 弹窗打开后延迟 100ms 再渲染组件
  4. 弹窗关闭时销毁组件,下次打开重新初始化

Q2: 签名图片方向不对

问题原因: 不同平台的旋转实现方式不同,默认旋转角度为 90 度。

解决方案

使用 rotateAngle 属性自定义旋转角度:

<signature-board :rotateAngle="180" @confirm="handleConfirm" />

支持的角度:0、90、180、270

Q3: 如何获取签名图片的宽高

解决方案

使用 uni.getImageInfo 获取图片信息:

const handleConfirm = (result) => {
  uni.getImageInfo({
    src: result.tempFilePath,
    success: (info) => {
      console.log('图片宽度:', info.width);
      console.log('图片高度:', info.height);
    }
  });
};

Q4: 如何上传签名图片到服务器

解决方案

H5 和微信小程序返回的是 base64 格式,可以直接传给后端:

const handleConfirm = (result) => {
  // 方式1: 直接传 base64
  uni.request({
    url: 'https://your-api.com/upload',
    method: 'POST',
    data: {
      signature: result.tempFilePath // base64 字符串
    }
  });

  // 方式2: 转成 Blob 上传(H5)
  // #ifdef H5
  fetch(result.tempFilePath)
    .then(res => res.blob())
    .then(blob => {
      const formData = new FormData();
      formData.append('file', blob, 'signature.png');
      // 使用 fetch 或 axios 上传
    });
  // #endif
};

代码逻辑说明

核心流程

  1. 初始化阶段(onMounted)

    • 创建 Canvas 上下文
    • 获取容器尺寸
    • 初始化旋转 Canvas 尺寸
    • 绘制白色背景
  2. 签名阶段

    • touchstart:记录起点坐标
    • touchmove:绘制线条
    • touchend:结束绘制
  3. 确认阶段

    • 检查是否已签名
    • 检查 Canvas 尺寸有效性(失败则重试)
    • 导出签名图片
    • 根据平台执行不同的旋转逻辑
    • 输出最终结果

平台差异处理

微信小程序

签名Canvas → canvasToTempFilePath → rotateImageInWx →
动态设置旋转Canvas尺寸 → Canvas旋转绘制 →
导出临时文件 → FileSystemManager读取 → base64输出

H5

签名Canvas → canvasToTempFilePath → rotateBase64Img →
DOM Canvas旋转 → toDataURL → base64输出

关键技术点

  1. Canvas 尺寸重试机制:检测到尺寸为 0 时自动重新初始化并重试
  2. 动态 Canvas 尺寸:旋转 Canvas 根据旋转角度动态调整宽高
  3. 异步等待:微信小程序需要等待 DOM 更新和绘制完成
  4. 条件编译:使用 #ifdef 实现平台差异化处理

更新日志

查看 changelog.md

许可证

MIT License

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT License

Copyright (c) 2025

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.