sign-canvas 一个基于canvas开发,封装于Vue组件的通用手写签名板(电子签名板),支持pc端和移动端;

mac2025-05-29  2

写在前面 :

在项目的开发过程中可能会涉及到手写签名(电子签名)那些,在前端的思路是使用canvas 来签名,导出成图片进行保存。

此轮子是继 https://blog.csdn.net/qq_33270001/article/details/81809535之后,用于vue项目中,为了方便自己与众人和复用而开发;

相比以前:

1. 增加npm 包,可直接安装并使用,

2. 增加v-model 动态绑定,有人可能觉得有点鸡肋了,但是如果有哪种场景,也是可以适用的.

3. 增加图片一键下载的方法.可以直接导出为png 或者 jpeg的图片.

这是以前的 "注意:在移动端使用的时候, 写竖的时候, 页面会被往下拉, 手写板动了, 写字不顺畅. 建议在移动端的touchmove事件里, 加一行防止页的滑动事件, 代码是: event.preventDefault(); " 现在已经处理了.

废话不多说,上项目和代码

 vue-sign-canvas项目地址: https://github.com/langyuxiansheng/vue-sign-canvas

在线演示: https://langyuxiansheng.github.io/vue-sign-canvas/

基础用法

┭┮﹏┭┮ 因为 vue-sign-canvas 的包名被占用了,只好去掉一个前缀了....假如此轮子对你有帮助,请顺手star一下吧.o(* ̄︶ ̄*)o

开始使用! 下载安装npm包

npm i sign-canvas --save //全局注册 main.js import SignCanvas from 'sign-canvas'; Vue.use(SignCanvas);

你可以这样使用: 

组件模板使用

<template> <div id="app"> <h2 class="title">Vue Sign Canvas 电子签名板</h2> <sign-canvas class="sign-canvas" ref="SignCanvas" :options="options" v-model="value"/> <img v-if="value" class="view-image" :src="value" width="150" height="150"> <div class="config"> <ul class="ul-config"> <li class="li-c"> <span class="item-label">书写速度:</span> <span class="item-content"> <select name="isSign" v-model="options.isSign"> <option :value="true">签名</option> <option :value="false">写字</option> </select> </span> </li> <li class="li-c"> <span class="item-label">显示边框/网格:</span> <span class="item-content"> <select name="isSign" v-model="options.isShowBorder"> <option :value="true">显示</option> <option :value="false">不显示</option> </select> </span> </li> <li class="li-c"> <span class="item-label">下笔宽度:</span> <span class="item-content"> <input v-model="options.writeWidth" type="number"> </span> </li> <li class="li-c"> <span class="item-label">线条的边缘类型:</span> <span class="item-content"> <select name="lineCap" v-model="options.lineCap"> <option value="butt">平直的边缘</option> <option value="round">圆形线帽</option> <option value="square">正方形线帽</option> </select> </span> </li> <li class="li-c"> <span class="item-label">线条交汇时边角的类型:</span> <span class="item-content"> <select name="lineCap" v-model="options.lineJoin"> <option value="bevel">创建斜角</option> <option value="round">创建圆角</option> <option value="miter">创建尖角</option> </select> </span> </li> <li class="li-c"> <span class="item-label">画笔颜色:</span> <span class="item-content"> <input type="color" v-model="options.writeColor"> </span> </li> <li class="li-c"> <span class="item-label">背景色:</span> <span class="item-content"> <input type="color" v-model="options.bgColor"> </span> </li> </ul> </div> <div class="sign-btns"> <span id="clear" @click="canvasClear()">清空</span> <span id="save" @click="saveAsImg()">保存</span> <span id="save" @click="downloadSignImg()">下载</span> </div> </div> </template> <script> export default { data(){ return { value: null, options:{ lastWriteSpeed: 1, //书写速度 [Number] 可选 lastWriteWidth: 2, //下笔的宽度 [Number] 可选 lineCap: 'round', //线条的边缘类型 [butt]平直的边缘 [round]圆形线帽 [square] 正方形线帽 lineJoin: 'round', //线条交汇时边角的类型 [bevel]创建斜角 [round]创建圆角 [miter]创建尖角。 canvasWidth: 600, //canvas宽高 [Number] 可选 canvasHeight: 600, //高度 [Number] 可选 isShowBorder: true, //是否显示边框 [可选] bgColor: '#fcc', //背景色 [String] 可选 注:这背景色仅仅只是canvas背景,保存的图片仍然是透明的 borderWidth: 1, // 网格线宽度 [Number] 可选 borderColor: "#ff787f", //网格颜色 [String] 可选 writeWidth: 5, //基础轨迹宽度 [Number] 可选 maxWriteWidth: 30, // 写字模式最大线宽 [Number] 可选 minWriteWidth: 5, // 写字模式最小线宽 [Number] 可选 writeColor: '#101010', // 轨迹颜色 [String] 可选 isSign: false, //签名模式 [Boolean] 默认为非签名模式,有线框, 当设置为true的时候没有任何线框 imgType:'png' //下载的图片格式 [String] 可选为 jpeg canvas本是透明背景的 } } }, methods:{ /** * 清除画板 */ canvasClear(){ this.$refs.SignCanvas.canvasClear(); }, /** * 保存图片 */ saveAsImg(){ const img = this.$refs.SignCanvas.saveAsImg(); alert(`image 的base64:${img}`); }, /** * 下载图片 */ downloadSignImg(){ this.$refs.SignCanvas.downloadSignImg(); }, } } </script> <style lang="less"> * { margin: 0; padding: 0; } .title{ padding: 20px; text-align: center; } .sign-canvas{ display: block; margin: 20px auto; } .view-image{ display: block; margin: 20px auto; } .config{ width: 350px; margin: 20px auto; .ul-config{ .li-c{ display: flex; align-items: center; padding: 4px 10px; .item-label{ font-size: 14px; } .item-content{ margin-left: 10px; } } } } .sign-btns{ display: flex; justify-content: space-between; #clear, #clear1, #save { display: inline-block; padding: 5px 10px; width: 76px; height: 40px; line-height: 40px; border: 1px solid #eee; background: #e1e1e1; border-radius: 10px; text-align: center; margin: 20px auto; cursor: pointer; } } </style>

功能与配置

props:{ options: { //配置项 required: false, type: [Object], default: () => null } } // 1. options [Object] 可选,非必传 // 2. v-model [String] 可选,非必传 配置项 options 属性 { lastWriteSpeed: 1, //书写速度 [Number] 可选 lastWriteWidth: 2, //下笔的宽度 [Number] 可选 lineCap: 'round', //线条的边缘类型 [butt]平直的边缘 [round]圆形线帽 [square] 正方形线帽 lineJoin: 'round', //线条交汇时边角的类型 [bevel]创建斜角 [round]创建圆角 [miter]创建尖角。 canvasWidth: 600, //canvas宽高 [Number] 可选 canvasHeight: 600, //高度 [Number] 可选 isShowBorder: true, //是否显示边框 [可选] 当签名模式处于false的时候此选项才生效 bgColor: '#fcc', //背景色 [String] 可选 borderWidth: 1, // 网格线宽度 [Number] 可选 borderColor: "#ff787f", //网格颜色 [String] 可选 writeWidth: 5, //基础轨迹宽度 [Number] 可选 maxWriteWidth: 30, // 写字模式最大线宽 [Number] 可选 minWriteWidth: 5, // 写字模式最小线宽 [Number] 可选 writeColor: '#101010', // 轨迹颜色 [String] 可选 isSign: false, //签名模式 [Boolean] 默认为非签名模式,有线框, 当设置为true的时候没有任何线框 imgType:'png' //下载的图片格式 [String] 可选为 jpeg canvas本是透明背景的 } 内置方法 //清除画布 无返回值 [Void] this.$refs.SignCanvas.canvasClear(); //清除画布 返回图片的base64编码 [String] this.$refs.SignCanvas.saveAsImg(); //调用内置的下载图片方法,默认将图片保存为png格式 this.$refs.SignCanvas.downloadSignImg();

二次开发 下载项目

git clone https://github.com/langyuxiansheng/vue-sign-canvas.git

Project setup

cd vue-sign-canvas npm install

Compiles and hot-reloads for development

npm run dev

Compiles and minifies for production

npm run build

Lints and fixes files

npm run lint

缺陷 & 后期计划

目前还没有撤销回到上一步的操作,一旦输入错了就只有清除重写了(这个是之前去银行的时候,那个签名板是这样设计的); 如果有需要还是可以考虑加上回到上一步的方法.

 

如果您有什么好的建议请留言

项目截图展示:

初始化的非签名模式,

书写展示

保存的base64展示 

 导出的图片展示

 签名模式下的展示

 

 

最新回复(0)