一、简介
- 在微信小程序开发中,有时候需要手写签名生成图片上传服务器、制作一个手绘板、画板并支持保存图片等,然后就封装了一下:DZMDrawingBoard。
- DZMDrawingBoard 通过 Canvas 封装,使用简单,导入作为组件使用即可。
二、使用方式
- 下载代码后,将
drawing-board
文件夹放入到项目,在需要使用的页面加入组件配置,也可以直接在app.js
中加入全局组件,这样就不需要每个页面去配置,看是多个页面还是单个页面用到。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8OhamoED-1656556121771)(//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/897e62a2658e4c82848f9454f6caa795~tplv-k3u1fbpfcp-zoom-1.image)] - 在需要用到的页面
.wxml
文件中按正常标签使用即可。
<!-- 原始画板 --> <view class="drawing-board"> <drawing-board></drawing-board> </view>
- 如果需要修改画板数据,或者监听画板笔画变化:
<!-- 使用画板 --> <view class="drawing-board"> <drawing-board // 如果需要在当前页面获取到组件模板,可以通过加上ID,通过 selectComponent 获得到组件,并直接调用内部方法 id="drawing-board" // 线宽 line-width="{{lineWidth}}" // 线颜色 line-color="{{lineColor}}" // 画板背景颜色,也是图片的背景颜色,默认透明 bg-color="{{bgColor}}" // 画板数据变化,目前只有笔画数变化回调出来 bind:change="drawingBoardChange" > </drawing-board> </view>
- 在页面上如果需要获取到画板,就可以通过上面的
id
属性配合selectComponent
获取到组件模板,类似于Vue
的refs
。
/** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { this.data.drawingBoard = this.selectComponent('#drawing-board') }
- 如果是通过
wx:if
判断的动态显示画板,则可以在设置显示的代码之后调用获取组件
showDrawingBoard: function () { // 显示画板 this.setData({ isShow: true }) // 获取画板组件 this.data.drawingBoard = this.selectComponent('#drawing-board') }
- 获得到组件之后则可以在当前使用页面的
.js
文件中调用组件内部方法
// demo1/index.js Page({ /** * 页面的初始数据 */ data: { // 当前画板 drawingBoard: undefined, // 画板生成的图片 imageUrl: '', // 线宽度 lineWidth: 5, // 线颜色 lineColor: '#fff', // 背景颜色: 透明 bgColor: 'rgba(255, 255, 255, 0)' }, // 线宽 lineWidthChange (e) { this.setData({ lineWidth: e.detail.value }) }, // 线颜色 lineColorChange (e) { this.setData({ lineColor: e.currentTarget.dataset.color }) }, // 背景颜色 bgColorChange (e) { this.setData({ bgColor: e.currentTarget.dataset.color }) }, // 清空 touchClear () { // 清空画板 this.data.drawingBoard.clear() }, // 撤销 touchRevoke () { this.data.drawingBoard.revoke() }, // 生成图片 touchCreateImage () { // 记录图片不保存相册 this.data.drawingBoard.createImage((isOK, res) => { // 生成图片成功 if (isOK) { this.setData({ imageUrl: res.tempFilePath || '' }) } }) }, // 保存相册 touchSave () { // 记录图片并保存相册 this.data.drawingBoard.createImage((isOK, res) => { // 生成图片成功 if (isOK) { this.setData({ imageUrl: res.tempFilePath || '' }) } }, true, (isOK, res) => { // 保存相册回调 if (isOK) { wx.showToast({ title: '保存成功', icon:'none' }) } else { wx.showToast({ title: '保存失败', icon:'none' }) } }) }, // 画板变化 drawingBoardChange (e) { console.log('当前画板存在的笔画数:', e.detail.strokesNumber) }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { this.data.drawingBoard = this.selectComponent('#drawing-board') } })
三、可能会遇到的小问题
- 如果画板下面存在存在滚动视图的话,或出现手势冲突,要么禁止当前页面的滚动,要么通过
catchtouchmove
来处理画板与下面滚动视图的事件传递。
.wxml
<!-- 原始画板 --> <view class="drawing-board" catchtouchmove="touchmove"> <drawing-board></drawing-board> </view>
.js
// 拦截触摸事件不要在往下执行 touchmove () { return }