更新记录
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 导入(推荐)
- 在 DCloud 插件市场找到本插件
- 点击右侧的
使用 HBuilderX 导入插件或下载插件ZIP - 导入到项目的
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 | 支持自定义角度 |
注意事项
- 组件占满父容器 100% 宽高,需设置父容器尺寸
- 在弹窗中使用时,确保弹窗已完全显示后再渲染组件
- 旋转角度必须是 90 的倍数(0、90、180、270)
- 组件使用动态缩放系统,所有尺寸会根据画布高度自动适配,初始值为基准高度(747px)
- 水印文字会根据画布大小和文字长度自动调整字体大小,防止超出画布
常见问题
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>
关键点:
- 使用
v-if而不是v-show,确保组件完全重新初始化 - 监听弹窗的
@change事件 - 弹窗打开后延迟 100ms 再渲染组件
- 弹窗关闭时销毁组件,下次打开重新初始化
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
};
代码逻辑说明
核心流程
-
初始化阶段(onMounted)
- 创建 Canvas 上下文
- 获取容器尺寸
- 初始化旋转 Canvas 尺寸
- 绘制白色背景
-
签名阶段
- touchstart:记录起点坐标
- touchmove:绘制线条
- touchend:结束绘制
-
确认阶段
- 检查是否已签名
- 检查 Canvas 尺寸有效性(失败则重试)
- 导出签名图片
- 根据平台执行不同的旋转逻辑
- 输出最终结果
平台差异处理
微信小程序
签名Canvas → canvasToTempFilePath → rotateImageInWx →
动态设置旋转Canvas尺寸 → Canvas旋转绘制 →
导出临时文件 → FileSystemManager读取 → base64输出
H5
签名Canvas → canvasToTempFilePath → rotateBase64Img →
DOM Canvas旋转 → toDataURL → base64输出
关键技术点
- Canvas 尺寸重试机制:检测到尺寸为 0 时自动重新初始化并重试
- 动态 Canvas 尺寸:旋转 Canvas 根据旋转角度动态调整宽高
- 异步等待:微信小程序需要等待 DOM 更新和绘制完成
- 条件编译:使用
#ifdef实现平台差异化处理
更新日志
查看 changelog.md
许可证
MIT License

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 31
赞赏 0
下载 11247247
赞赏 1860
赞赏
京公网安备:11010802035340号