微信小程序实现简单手写签名组件的方法实例
时间:2022-06-20 10:25:34|栏目:JavaScript代码|点击: 次
背景:
在做项目过程中,需要在微信小程序中实现手写签名组件。在网上找了微信小程序手写签名实现,但是都是不太理想。在实际运用中,会因为实时计算较多的贝塞尔曲线而产生卡顿。效果不理想。所以退一步,不需要笔锋以及笔迹模拟效果。只需要简单的手写签名实现。
需求:
可以实现用户在微信小程序上手写签名。
需要组件化。
效果
一、思路
在微信小程序中,我们使用canvas组件实现。将用户的输入想象成为一只笔。我们要画的签名是由很多点构成的。但是单纯的点是不能很好地构成线。点与点之间还要由线连接。下面是实现过程代码。
二、实现
1. 页面与样式
wxml
这里的canvas组件是最新的用法。
<view class="dashbox"> <view class="btnList"> <van-button size="small" bind:click="clearCanvas">清空</van-button> </view> <view class="handCenter"> <canvas class="handWriting" disable-scroll="{{true}}" id="handWriting" bindtouchstart="scaleStart" bindtouchmove="scaleMove" bindtouchend="scaleEnd" bindtap="mouseDown" type="2d" > </canvas> </view> </view>
wxss
.btnList{ width: 95%; margin:0 auto; } .handWriting{ background: #fff; width: 95%; height: 80vh; margin:0 auto }
2. 初始化
由于是在自定义组件中使用,所以要注意获取canvas的时候的this指向问题。如果不调用SelectorQuery的In方法,那么就在自定义组件获取不到canvas,因为这个时候指向的父组件。
Component({ /** * 组件的初始数据 */ data: { canvasName:'#handWriting', ctx:'', canvasWidth:0, canvasHeight:0, startPoint:{ x:0, y:0, }, selectColor: 'black', lineColor: '#1A1A1A', // 颜色 lineSize: 1.5, // 笔记倍数 radius:5,//画圆的半径 }, ready(){ let canvasName = this.data.canvasName; let query = wx.createSelectorQuery().in(this);//获取自定义组件的SelectQuery对象 query.select(canvasName) .fields({ node: true, size: true }) .exec((res) => { const canvas = res[0].node; const ctx = canvas.getContext('2d'); //获取设备像素比 const dpr = wx.getSystemInfoSync().pixelRatio; //缩放设置canvas画布大小,防止笔迹错位 canvas.width = res[0].width * dpr; canvas.height = res[0].height * dpr; ctx.scale(dpr, dpr); ctx.lineJoin="round"; this.setData({ctx}); }); query.select('.handCenter').boundingClientRect(rect => { console.log('rect', rect); this.setData({ canvasWidth:rect.width, canvasHeight:rect.height }); }).exec(); }, //省略以下代码...... });
3. 点击时
Component({ //省略以上代码... methods: { scaleStart(event){ if (event.type != 'touchstart') return false; let currentPoint = { x: event.touches[0].x, y: event.touches[0].y } this.drawCircle(currentPoint); this.setData({startPoint:currentPoint}); }, drawCircle(point){//这里负责点 let ctx = this.data.ctx; ctx.beginPath(); ctx.fillStyle = this.data.lineColor; //笔迹粗细由圆的大小决定 ctx.arc(point.x, point.y, this.data.radius, 0 , 2 * Math.PI); ctx.fill(); ctx.closePath(); }, //省略以下代码... } })
4. 签名时
Component({ //省略以上代码 methods:{ drawLine(sourcePoint, targetPoint){ let ctx = this.data.ctx; this.drawCircle(targetPoint); ctx.beginPath(); ctx.strokeStyle = this.data.lineColor; ctx.lineWidth = this.data.radius * 2;//这里乘2是因为线条的粗细要和圆的直径相等 ctx.moveTo(sourcePoint.x, sourcePoint.y); ctx.lineTo(targetPoint.x, targetPoint.y); ctx.stroke(); ctx.closePath(); }, clearCanvas(){//清空画布 let ctx = this.data.ctx; ctx.rect(0, 0, this.data.canvasWidth, this.data.canvasHeight); ctx.fillStyle = '#FFFFFF'; ctx.fill(); } } })
三、总结
这个手写签名仅仅是为了业务应急使用。如果要优化的话,可以从笔锋模拟和笔迹模拟中入手。只不过要解决在实时模拟过程中卡顿的问题。
栏 目:JavaScript代码
下一篇:使用JSX 建立组件 Parser(解析器)开发的示例
本文标题:微信小程序实现简单手写签名组件的方法实例
本文地址:http://www.codeinn.net/misctech/205378.html