最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
uni-app实现电子签名画布 uni-app用canvas导出图片
时间:2026-06-15 09:47:52 编辑:袖梨 来源:一聚教程网
Canvas签名不响应触摸事件,主因是未正确绑定事件或未设宽高;图片模糊因未适配dpr;导出失败因上下文不匹配或绘制未完成;背景异常因未清空填充。
uni-app里Canvas画布签名不响应触摸事件
真机调试时签名区域完全没反应,或者只在部分区域生效——大概率是 canvas 组件没正确绑定触摸事件或未设置宽高。uni-app 的 canvas(尤其是 2D 上下文)在不同平台行为差异大,H5 和小程序对 touchstart/touchmove 的处理逻辑也不同。
实操建议:
- 必须用
canvas-id+type="2d"声明 canvas,并在onReady后通过uni.createCanvasContext获取上下文,不要用querySelector或直接操作 DOM - H5 端需手动监听
touchstart/touchmove事件并调用ctx.moveTo/ctx.lineTo;小程序端可直接用bindtouchstart/bindtouchmove属性,但要确保事件对象里能拿到touches[0].x/y - canvas 宽高必须用 rpx 或 px 显式设置,不能靠父容器撑开;同时在
style中加touch-action: none防止 iOS Safari 默认滚动拦截
导出的签名图片模糊、边缘锯齿严重
导出的 PNG 图片在手机上看起来发虚、线条断续,不是因为分辨率低,而是 canvas 像素比(dpr)没适配。uni-app 的 canvas 默认以 1:1 渲染,而 iPhone 和安卓高端机 dpr 多为 2 或 3,导致绘制点被拉伸模糊。
实操建议:
- 创建 canvas 上下文前,先用
uni.getSystemInfoSync().pixelRatio获取设备 dpr,再将 canvas 的width和height属性设为「设计宽高 × dpr」,同时用 CSS 将 canvas 样式宽高设为原始设计尺寸(如 375×200px) - 绘图前调用
ctx.scale(dpr, dpr),让所有坐标和线宽自动按比例缩放 - 避免使用
ctx.lineWidth = 1这类固定值,应设为1 / dpr,否则高 dpr 下线条会过粗
uni.canvasToTempFilePath 导出失败或返回空路径
调用 uni.canvasToTempFilePath 后回调不触发、报错 canvas is not found,或生成的临时文件路径为空——这是最常踩的坑,核心原因是 canvas 实例与导出 API 不在同一上下文,或 canvas 尚未完成绘制就调用了导出。
实操建议:
- 必须等 canvas 内容绘制完毕(比如最后一次
ctx.stroke()执行完),再调用uni.canvasToTempFilePath;可在setTimeout中延后 16ms(一帧)再执行,避免渲染队列未 flush - 小程序端务必传入
canvasId和当前页面的this实例(即success回调里的res.tempFilePath才有效),H5 端则要用canvas.toDataURL('image/png')替代 - 导出前检查 canvas 是否已挂载:
uni.createSelectorQuery().select('#myCanvas').fields({ node: true, size: true }),确保 node 存在且 width/height > 0
签名图片导出后背景为黑色或透明异常
导出的图片本该是白底黑线,结果全是黑底,或关键线条消失——这是因为 canvas 默认背景透明,而某些平台(尤其 Android 微信)在导出时把 alpha 通道当成了黑底合成。
实操建议:
- 绘制前先清空画布并填充白色:
ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, width, height);,注意这个width/height是 canvas 元素的逻辑宽高(非像素宽高) - 如果需要透明背景,导出前不要 fill,但得确认目标平台支持 PNG alpha;微信小程序中,
canvasToTempFilePath的fileType必须显式设为'png',jpg 不支持透明 - 导出后若仍异常,可用
uni.getImageInfo检查临时文件是否加载成功,再用uni.uploadFile上传前做一次校验
真正麻烦的是多端 dpr 适配和 canvas 生命周期管理——很多问题不是代码写错了,而是 canvas 被重建了两次,或者导出时机卡在 draw call 还没提交到 GPU。动手前先 console.log 出 dpr、canvas node、ctx 对象,比盲调快得多。
相关文章
- 伊莫星骑士支线任务如何完成 06-16
- 逆战未来深渊狂潮怎么玩 06-16
- 银河灰暗角落结局彩蛋触发方法分享 06-16
- 异能重组护盾流玩法攻略介绍说明 06-16
- 别拽了烤串师傅气味炸弹成就解锁攻略 06-16
- 银河灰暗角落暴击流玩法构筑分享 06-16