微信小程序签名组件:
现在线上签名的需求越来越多,然后就封装了一下组件,方便以后使用,可以获取的图片格式有 base64和临时文件
组件展示:
可以扫码查看是否符合自己的需求
wxml:
<!--components/autograph/index.wxml-->
<view class="autograph-container" style="width: {{ width }}; height: {{ height }}; display: block;">
<canvas class="autograph-canvas" type="2d" disable-scroll style="width: 100%; height: 100%; display: block;" bindtouchstart="handleTouchStart" bindtouchmove="handleTouchMove" bindtouchend="handleTouchEnd" bindtouchcancel="handleTouchEnd" binderror="handleTouchEnd"></canvas>
</view>
js:
// components/autograph/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
width: {
type: String,
value: '100%'
},
height: {
type: String,
value: '400rpx'
},
lineWidth: {
type: Number,
value: 2
},
lineColor: {
type: String,
value: '#000000'
}
},
/**
* 组件的初始数据
*/
data: {
isDraw: false, // 是否能画画
canvasElement: null,
canvasContext: null,
oldPosition: {
x: 0,
y: 0
}
},
/**
* 组件的方法列表
*/
methods: {
// 初始化canvas
initCanvas(fn) {
const query = wx.createSelectorQuery().in(this)
query.select('.autograph-canvas').fields({ node: true, size: true, context: true }).exec(res => {
const canvas = res[0].node
const context = canvas.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
context.scale(dpr, dpr)
this.setData({
canvasElement: canvas,
canvasContext: context
}, function () {
if (typeof fn == 'function') {
fn()
}
})
})
},
// 描绘canvas
drawCanvas(position) {
if (this.data.canvasContext) {
this.data.canvasContext.strokeStyle = this.properties.lineColor
this.data.canvasContext.lineWidth = this.properties.lineWidth
this.data.canvasContext.beginPath()
this.data.canvasContext.moveTo(this.data.oldPosition.x, this.data.oldPosition.y)
this.data.canvasContext.lineTo(position.x, position.y)
this.data.canvasContext.stroke()
this.data.canvasContext.closePath()
this.setData({
oldPosition: {
x: position.x,
y: position.y
}
})
}
},
// 在画布触摸开始
handleTouchStart(e) {
const x = e.touches[0].x;
const y = e.touches[0].y;
this.setData({
oldPosition: {
x: x,
y: y
},
isDraw: true
})
},
// 在画布触摸移动
handleTouchMove(e) {
if (this.data.isDraw) {
let positionItem = e.touches[0]
if (this.data.canvasContext) {
this.drawCanvas(positionItem, true)
} else {
this.initCanvas(() => {
this.drawCanvas(positionItem, true)
})
}
}
},
// 在画布触摸结束
handleTouchEnd() {
this.setData({
isDraw: false
})
},
// 清除画布
clearCanvas() {
const x = this.data.canvasElement.width
const y = this.data.canvasElement.height
this.data.canvasContext.clearRect(0, 0, x, y)
},
// 获取画布的base64
getCanvasBase64() {
const pngPic = this.data.canvasElement.toDataURL()
return pngPic
},
// 获取临时文件
getCavasTempFile() {
return new Promise((resolve, reject) => {
wx.canvasToTempFilePath({
x: 0,
y: 0,
// width: this.properties.width,
// height: this.properties.height,
// destWidth: 100,
// destHeight: 100,
canvas: this.data.canvasElement,
success: (res) => {
console.log(res);
resolve(res.tempFilePath)
},
fail: () => {
reject('图片临时文件生成失败')
}
})
})
}
}
})
使用:
- json文件
"usingComponents": {
"autograph": "../../components/autograph"
}
- wxml文件
<!--pages/useAutograph/index.wxml-->
<view>
<view class="autograph-border">
<autograph class="autograph-component"></autograph>
</view>
<view class="btn-box">
<button bindtap="handleReSign" style="display: inline-block; width: initial;">重签</button>
<button type="primary" style="display: inline-block; width: initial; margin-left: 40rpx;" bindtap="handleSure">确定</button>
</view>
<view>
<image src="{{ signBase64 }}"></image>
</view>
</view>
- js 文件中
// pages/useAutograph/index.js
data: {
signBase64: ''
},
// 清除画布
handleReSign() {
const autograph = this.selectComponent(".autograph-component")
autograph.clearCanvas()
},
// 获取base64
handleSure() {
const autograph = this.selectComponent(".autograph-component")
this.setData({
signBase64: autograph.getCanvasBase64()
})
},
// 获取临时文件路径
getTempFile() {
const autograph = this.selectComponent(".autograph-component")
autograph.getCavasTempFile().then(res => {
this.setData({
signBase64: res
})
})
},
- wxss
.autograph-border{
margin: 40rpx;
border: 2rpx solid #000000;
}
.btn-box{
margin: 40rpx;
text-align: center;
}