vue-sign-canvas 最初是一个面向 Vue 2 的手写签名板组件,核心目标很直接:让用户可以在 PC 或移动端完成签名,并导出 base64 图片。随着使用场景变多,旧版本逐渐暴露出一些维护和能力边界上的问题,例如移动端触点偏移、空签名校验不够明确、回显后继续编辑不稳定、导出格式处理不完整,以及组件内部逻辑越来越难维护。
v2 版本选择直接做一次不兼容升级:基于 Vue 3、TypeScript 和 Vite 重新整理组件结构,同时把签名板常见的业务能力补齐。
为什么要做一次不兼容升级
签名板看起来只是一个 canvas 组件,但真实业务里经常会遇到这些要求:
- 表单提交前必须判断用户是否真的签名。
- 后端返回已有签名后,需要回显到画布,并允许继续补签。
- 移动端和 PC 端都要可用,触点位置不能偏。
- 高清屏导出不能模糊。
- 用户误操作后需要撤销、重做。
- 合同、确认单、练字等场景需要背景图或临摹稿。
- JPEG 导出不能出现透明区域黑底。
- TypeScript 项目需要完整类型提示。
这些能力如果继续堆在旧组件里,会让组件越来越难维护。v2 的目标不是只把 Vue 2 代码改到 Vue 3 能跑,而是重新定义组件的内部边界,让绘制、状态、导出、图层和对外 API 各自清晰。
技术栈升级
v2 使用了新的基础栈:
- Vue 3
- TypeScript
- Vite
- Pointer Events
- ESM / UMD 构建产物
.d.ts类型声明输出
这也意味着 v2 不再兼容 Vue 2 项目。如果项目仍然使用 Vue 2,可以继续安装旧版本:
bash
npm i sign-canvas@1
组件结构调整
v2 将核心逻辑拆成了更容易维护的几部分:
constants.ts:集中维护配置项、默认值和类型。useSignCanvas.ts:管理组件状态、事件、笔迹历史和对外 API。utils/canvas.ts:处理 canvas 绘制、图片加载、导出、旋转和图层绘制。index.vue:保留组件模板和事件绑定,避免把所有逻辑塞进单文件组件。
这样的拆分让新增功能更直接。例如背景图、临摹图和导出旋转都属于 canvas 能力,放在 utils/canvas.ts;撤销、重做、回显和签名状态属于组件状态,放在 useSignCanvas.ts。
输入事件:统一 PC 和移动端
旧版本常见的问题之一是移动端触摸坐标容易出现偏移。v2 改为使用 Pointer Events 统一鼠标、触摸和触控笔输入。
组件会通过 canvas 的 getBoundingClientRect() 计算真实的 CSS 像素坐标,再结合 DPR 绘制到真实像素画布上。这样可以同时保证输入位置准确和高分屏清晰。
空签名判断
业务里经常需要判断"用户是否真的签名"。v2 明确区分真实签名内容和辅助图层:
- 用户绘制的笔迹会计入签名状态。
fromDataURL()回显的已有签名会计入签名状态。- 背景色、边框、辅助线、背景图和临摹层不会计入签名状态。
因此可以直接使用:
ts
if (signCanvasRef.value?.isEmpty()) {
return;
}
也可以获取更完整的状态:
ts
const status = signCanvasRef.value?.getSignatureStatus();
回显后继续编辑
v2 新增了 fromDataURL(),支持把已有签名图片回显到画布:
ts
await signCanvasRef.value?.fromDataURL(base64);
回显图片会作为签名内容的一部分参与导出,用户也可以在回显图上继续绘制。这个能力适合"草稿签名""补签""编辑已有签名"等场景。
同时组件也支持通过 v-model 或 image 传入已有图片,完成自动回显。
撤销和重做
v2 增加了笔迹历史。历史记录按"每次下笔"保存,而不是按每一个线段保存。这样用户连续写一笔时,撤销会更符合直觉。
ts
signCanvasRef.value?.undo();
signCanvasRef.value?.redo();
默认也支持快捷键:
Ctrl / Command + Z:撤销Ctrl / Command + Y:重做Ctrl / Command + Shift + Z:重做
如果页面中有多个签名板,快捷键只作用于当前获得焦点的画布,避免互相干扰。
背景图合成
一些业务需要在固定模板上签名,例如合同、确认单、授权书。v2 新增了背景图配置:
ts
const options = {
backgroundImage: contractBase64,
backgroundImageFit: 'cover',
backgroundImageOpacity: 1
};
背景图会显示在画布上,并合成进最终导出的图片,但不会被视为用户已经签名。
描写和临摹
v2 增加了独立的临摹引导层,可以通过 guideEnabled 开启或关闭。
文字临摹:
ts
const options = {
guideEnabled: true,
guideText: '张三',
guideFont: '700 96px serif',
guideTextColor: '#101010',
guideTextOpacity: 0.16
};
图片临摹:
ts
const options = {
guideEnabled: true,
guideImage: '/trace-template.png',
guideImageFit: 'contain',
guideImageOpacity: 0.24
};
临摹层同样只是一层辅助图层,不会影响空签名判断,也不会进入撤销历史。
导出旋转
部分移动端业务会要求横向签名后导出竖图,或者反过来。v2 新增了 exportRotate:
ts
const options = {
exportRotate: 90
};
支持的角度为:
090180270
这个配置只影响导出的图片方向,不改变页面上正在绘制的画布方向。
JPEG 白底导出
JPEG 不支持透明通道。如果直接把透明 canvas 导出为 JPEG,部分环境会出现黑底。v2 在 JPEG 导出时会自动铺底色:
ts
const options = {
imgType: 'jpeg',
jpegBgColor: '#fff'
};
这样可以避免透明区域在导出后变黑。
Demo 工作台
v2 也重写了 demo 页面。新的 demo 不只是展示一个签名框,而是一个完整的调试工作台:
- 桌面端预览
- 移动端预览
- 画布参数调节
- 画笔参数调节
- 背景图配置
- 描写/临摹配置
- 导出格式配置
- 撤销和重做
- 导出结果预览
在线预览地址:
text
https://langyuxiansheng.github.io/vue-sign-canvas/
桌面端预览:

移动端预览:

完整参数和导出预览:

迁移建议
如果你正在从 1.x 升级到 2.x,需要重点关注:
- Vue 2 项目不能直接升级到 v2,需要先升级到 Vue 3。
- 组件使用方式推荐改为 Vue 3
v-model。 - 如果项目里使用旧方法名,v2 保留了部分兼容别名,例如
canvasClear()、saveAsImg()、dealImage()。 - 新项目建议优先使用语义更清晰的方法:
clear()、toDataURL()、fromDataURL()。 - 如果依赖 uni-app 小程序或 App 端,不建议直接使用 Web 主包,应单独做平台适配。
总结
v2 的重点不是"能跑在 Vue 3",而是把签名板从一个简单 canvas 示例升级为更稳定的 Vue 3 组件库。它补齐了签名业务里常见的能力:空签名校验、回显编辑、撤销重做、背景合成、临摹引导、导出旋转和 TypeScript 类型支持。
后续如果继续扩展,可以围绕两个方向推进:
- 更强的笔迹数据持久化和回放能力。
- 面向 uni-app 或小程序环境的独立适配包。