一、效果图
二、代码示例
qianming.js
export const qianming = {
data() {
return {
windowWidth: 0,
pixelRatio: 0,
context: null,
points: [],
oldPoints: [],
qm_width: 280,
qm_height: 120,
qm_img: ''
}
},
methods: {
qm_start() {
const systemInfo = uni.getSystemInfoSync()
this.windowWidth = systemInfo.windowWidth
this.pixelRatio = systemInfo.pixelRatio
this.context = uni.createCanvasContext('canvasId', this)
this.context.fillStyle = '#fff'; //背景色
uni.createSelectorQuery().in(this).select("#qianming-box").boundingClientRect((data) => {
const width = data.width
const height = data.height
const lineWidth = 4 / 750 * this.windowWidth
this.context.fillRect(0, 0, width, height)
this.context.lineWidth = lineWidth
this.context.strokeStyle = '#000' //画笔颜色
this.context.lineCap = 'round'
this.context.lineJoin = 'round'
this.context.stroke()
this.context.draw(true)
}).exec();
},
qm_touchstart(e) {
this.points.push({
x: e.changedTouches[0].x,
y: e.changedTouches[0].y
})
this.context.beginPath()
},
qm_touchmove(e) {
this.points.push({
x: e.changedTouches[0].x,
y: e.changedTouches[0].y
})
this.oldPoints = JSON.parse(JSON.stringify(this.points))
if (this.points.length > 1) {
this.context.moveTo(this.points[0].x, this.points[0].y)
this.context.lineTo(this.points[1].x, this.points[1].y)
this.points.splice(0, 1)
this.context.stroke()
this.context.draw(true)
}
},
qm_touchend(e) {
this.points = []
},
qm_reset() {
this.context = null
this.points = []
this.oldPoints = []
this.qm_start()
},
qm_save() {
if (this.oldPoints.length == 0) {
uni.showToast({
title: '请进行签名!',
icon: 'none'
})
return
}
let self = this
uni.canvasToTempFilePath({
canvasId: 'canvasId',
fileType: self.fileType,
quality: 1,
width: self.qm_width,
height: self.qm_height,
destWidth: self.qm_width * self.pixelRatio,
destHeight: self.qm_height * self.pixelRatio,
success: (res) => {
//res.tempFilePath
// #ifdef MP-WEIXIN
let fileManager = uni.getFileSystemManager();
fileManager.readFile({
filePath: res.tempFilePath,
encoding: 'base64',
success: function(data) {
// data.data就是base64字符串
let base64Data = 'data:image/png;base64,' + data.data;
self.qm_img = base64Data
},
fail: function(err) {
console.error(err);
}
});
// #endif
// #ifdef APP-PLUS
const path = plus.io.convertLocalFileSystemURL(res.tempFilePath) //绝对路径
const fileReader = new plus.io.FileReader()
fileReader.readAsDataURL(path)
fileReader.onloadend = (res) => { //读取文件成功完成的回调函数
console.log(res.target.result) //输出base64内容
let base64Data = 'data:image/png;base64,' +res.target.result;
self.qm_img = base64Data
}
// #endif
self.toHidePopup('qianming')
},
fail: (err) => {
console.log('生成图片失败:', err)
}
}, self)
},
qm_error(e) {
console.log('错误信息:', e)
}
}
}
<my-popup position="qita" :show="qianming" :closeType="true">
<view class="prompt-box">
<view class="prompt-head">
请在空白区域写上你的姓名
</view>
<view class="prompt-body">
<view class="prompt-input-box" id="qianming-box"
style="height: 240upx;border: 1px dashed rgb(204, 204, 204);">
<canvas v-if="qianming" style="width:100%;height:240upx;" class="canvas-item"
disable-scroll="true" canvas-id="canvasId" @touchstart="qm_touchstart"
@touchmove="qm_touchmove" @touchend="qm_touchend" @error="qm_error"></canvas>
</view>
</view>
<view class="prompt-foot">
<view class="prompt-btn mr15" @click.stop="qm_save">确定签名</view>
<view class="prompt-btn mr15" @click.stop="qm_reset">重写</view>
<view class="prompt-btn prompt-btn-cancel" @click.stop="toHidePopup('qianming')">取消</view>
</view>
</view>
</my-popup>