背景:
在做项目过程中,需要在微信小程序中实现手写签名组件。在网上找了微信小程序手写签名实现,但是都是不太理想。在实际运用中,会因为实时计算较多的贝塞尔曲线而产生卡顿。效果不理想。所以退一步,不需要笔锋以及笔迹模拟效果。只需要简单的手写签名实现。
需求:
可以实现用户在微信小程序上手写签名。
需要组件化。
效果
一、思路
在微信小程序中,我们使用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();
}
}
})
三、总结
这个手写签名仅仅是为了业务应急使用。如果要优化的话,可以从笔锋模拟和笔迹模拟中入手。只不过要解决在实时模拟过程中卡顿的问题。
到此这篇关于微信小程序实现简单手写签名组件的文章就介绍到这了,更多相关微信小程序手写签名组件内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论