JavaScript使用Canvas实现移动端与PC端通用签字功能
在Web应用中集成电子签字功能,通常依赖于HTML5 Canvas元素与JavaScript的事件监听机制。该方案兼容移动端触摸屏和桌面端鼠标操作,通过计算相对坐标实现流畅的线条绘制,并支持将签名结果导出为图片格式。
签字区域布局结构
签字功能的基础是定义一个可交互的画布区域。建议使用 canvas 标签作为签字板,并为后续的操作(如清空、重置)预留控制按钮或容器。
<!-- 签字提示区域 -->
<div class="mui-content-padded">
<font style="font-family: '微软雅黑'; font-size: 1.2rem;">验收人签字:</font>
</div>
<!-- 签字画布容器 -->
<div class="mui-content-canvasDiv" style="overflow: hidden;">
<!-- 指定ID以便JS获取上下文 -->
<canvas id="myCanvas" width="660" height="360"
style="border:1px solid #f2f2f2; background:#fff;">
</canvas>
<!-- 用于存放回显或保存后的图片 -->
<div class="saveimgs" id="saveImgDiv"></div>
</div>
初始化签字交互逻辑
核心难点在于统一移动端触摸(Touch)与PC端鼠标(Mouse)的事件处理,并正确计算相对于Canvas的坐标。以下代码封装了初始化函数 InitThis() 和绘图函数 Draw()。
第1步:定义全局变量与上下文
// 状态标记:是否正在书写
var mousePressed = false;
// 记录上一个坐标点,用于绘制平滑线段
var lastX, lastY;
// 获取Canvas绘图上下文
var ctx = document.getElementById('myCanvas').getContext("2d");
var c = document.getElementById("myCanvas");
// 可选:笔触粗细、颜色配置
var selected1 = 2; // 线宽
var selected2 = "#000"; // 颜色
第2步:绑定触摸屏事件(Mobile Touch)
移动端需重点处理 touchstart, touchmove, touchend。关键点是调用 event.preventDefault() 防止页面滚动,并使用 offsetLeft/Top 修正坐标。
function InitThis() {
// --- 触摸屏事件 ---
// 手指按下:开始绘制,记录起始点
c.addEventListener('touchstart', function(event) {
if(event.targetTouches.length == 1) {
event.preventDefault(); // 阻止浏览器默认滚动行为
mousePressed = true;
// 计算相对Canvas左上角的坐标
var touch = event.touches[0];
Draw(touch.pageX - this.offsetLeft, touch.pageY - this.offsetTop, false);
}
}, false);
// 手指移动:持续绘制
c.addEventListener('touchmove', function(event) {
if(event.targetTouches.length == 1) {
event.preventDefault();
if(mousePressed) {
var touch = event.touches[0];
Draw(touch.pageX - this.offsetLeft, touch.pageY - this.offsetTop, true);
}
}
}, false);
// 手指抬起:停止绘制
c.addEventListener('touchend', function(event) {
if(event.targetTouches.length == 1) {
event.preventDefault();
mousePressed = false;
}
}, false);
// --- PC端鼠标事件(向下兼容) ---
c.onmousedown = function(event) {
mousePressed = true;
Draw(event.pageX - this.offsetLeft, event.pageY - this.offsetTop, false);
};
c.onmousemove = function(event) {
if(mousePressed) {
Draw(event.pageX - this.offsetLeft, event.pageY - this.offsetTop, true);
}
};
c.onmouseup = function(event) {
mousePressed = false;
};
}
第3步:实现绘图算法
Draw(x, y, isDown) 函数负责实际绘制。当 isDown 为 true 时,连接上一帧坐标与当前坐标;为 false 时仅更新坐标点。
function Draw(x, y, isDown) {
if(isDown) {
ctx.beginPath();
ctx.strokeStyle = selected2;
ctx.lineWidth = selected1;
ctx.lineJoin = "round"; // 线条转折处圆角处理
ctx.moveTo(lastX, lastY); // 从上一个点开始
ctx.lineTo(x, y); // 画到当前点
ctx.closePath();
ctx.stroke();
}
// 无论是否正在绘制,都要更新lastX/lastY,以追踪最新的笔尖位置
lastX = x;
lastY = y;
}
获取签字图片数据
完成签字后,需要将画布内容转换为图片以便展示或上传。使用 toDataURL() 可将Canvas导出为 Base64 格式的 PNG 图片。
第1步:导出图片Base64字符串
// 获取Canvas元素
var c = document.getElementById("myCanvas");
// 导出为PNG格式的Base64数据
var image = c.toDataURL("image/png");
第2步:回显或保存图片
将生成的图片URL插入到指定的容器中,方便用户查看签字效果。
var saveimgs = document.getElementsByClassName("saveimgs")[0];
// 创建图片DOM元素
var imgEl = document.createElement("img");
imgEl.src = image;
imgEl.style.width = "100%"; // 适配容器宽度
// 如果已有旧签名,先替换;否则追加
if(saveimgs.getElementsByTagName('img').length > 0) {
saveimgs.removeChild(saveimgs.getElementsByTagName('img')[0]);
}
saveimgs.appendChild(imgEl);
常见注意事项与排错
- 坐标偏移问题: 如果签出来的字偏离画布边缘,通常是因为没有减去父容器的
offsetLeft和offsetTop,或者CSS设置了margin/padding未计算在内。图: 
- 移动端点击穿透/滚动: 必须监听
touchstart并执行event.preventDefault(),否则在快速划线时会导致整个页面滑动。 - 高分屏清晰度: 如果需要在Retina屏幕上显示清晰,Canvas的宽高应设为视觉大小的2倍,并通过CSS缩放至实际尺寸,同时调整Context缩放比例。
以上就是基于JavaScript和HTML5 Canvas实现移动端与PC端通用签字功能的详细内容,更多关于前端Canvas绘图技巧的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













