實現簽名方法就是使用canvas
<canvas canvas-id="firstCanvas" id='firstCanvas' bindtouchstart="bindtouchstart" bindtouchmove="bindtouchmove"></canvas>
<!-- 旋裝圖片 -->
<canvas canvas-id="saveImg" id='saveImg'></canvas>
<view class="clear" hidden="{{!sureBtn}}" bindtap='clear'>重新簽名</view>
<view class="save {{sureBtn?'sureBet':''}}" bindtap='export'>完成</view>
在canvas上綁定手指點擊事件和移動事件:
上圖是想要實現的效果,
有幾個考慮的點:
- 1、簽字區域和按鈕都是橫屏顯示的,這個首先想到的使用微信小程序的方法直接在json文件設置"pageOrientation":"landscape",但效果是整個屏幕橫屏,標題也橫,效果不同。只能通過css方法旋轉實現按鈕橫屏展示
- 2、簽字區域有個占位符,簽字的時候需要去除,首先想到的是用個view去占位,然后點擊切換為canvas,但是個人覺的略顯刻意,就用canvas來旋轉實現,bindtouchstart時讓文字為空,這樣也多了一個設置默認文字的函數
- 3、生成圖片,在使用wx.canvasToTempFilePath({})的時候發現生成的圖片也是反着的,這里用了一個笨方法,添加一個canvas來單獨處理圖片旋轉
//index.js
//獲取應用實例
const app = getApp()
Page({
data: {
context: null,
index: 0,
height: 0,
width: 0,
writeTips: '請清晰書寫您的英文簽名',
writeTipsTrue: true,
src:'',
sureBtn:false,
saveContext:null
},
/**記錄開始點 */
bindtouchstart: function (e) {
let { writeTipsTrue } = this.data
if (writeTipsTrue) {
this.data.context.clearRect(0, 0, this.data.width, this.data.height);
this.setData({ writeTipsTrue: false, sureBtn:true })
}
this.data.context.moveTo(e.changedTouches[0].x, e.changedTouches[0].y)
},
/**記錄移動點,刷新繪制 */
bindtouchmove: function (e) {
this.data.context.setLineWidth(2) // 設置線條寬度
this.data.context.lineTo(e.changedTouches[0].x, e.changedTouches[0].y);
this.data.context.stroke();
this.data.context.draw(true);
this.data.context.moveTo(e.changedTouches[0].x, e.changedTouches[0].y);
},
/**清空畫布 */
clear () {
let context = this.data.context
this.setData({ writeTipsTrue: true, sureBtn:false })
context.clearRect(0, 0, this.data.width, this.data.height);
// this.data.saveContext.clearRect(0, 0, this.data.height, this.data.width);
context.save();
context.setTransform(1, 0, 0, 1, Math.ceil(this.data.width / 2), 155); // 旋轉畫布 默認文字區域
context.rotate(Math.PI / 2);
let str = this.data.writeTips;
context.setFontSize(24)
context.setFillStyle('#ADADB2');
context.fillText(str, 0, 0)
context.restore();
context.draw()
},
/**導出圖片 */
export () {
const that = this;
let signImg;
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.width,
height: that.data.height,
destWidth: that.data.width,
destHeight: that.data.height,
canvasId: 'firstCanvas',
success (res) {
console.log(res.tempFilePath)
signImg = res.tempFilePath
that.setData({ src1: signImg})
//下載圖片
wx.getImageInfo({
src: signImg, // 簽字畫布生成的暫存地址
success (res) {
// canvas繪制圖片需要下載圖片或者getImageInfo
console.log(res,'res');
let rototalImg = res.path
that.setData({ src: rototalImg})
if (rototalImg) {
// 單獨處理圖片旋轉
that.saveImg(rototalImg)
}
}
})
}
})
},
// drew img
saveImg (signImg){
if (!this.data.sureBtn){
app.toast(this, {
type: 'text',
text: '請清晰書寫您的英文簽名'
})
return
}
// 旋轉圖
let that = this
const context = wx.createCanvasContext('saveImg');
this.setData({saveContext:context})
context.translate(that.data.width / 2, that.data.height / 2)
context.setTransform(1, 0, 0, 1, 0, Math.ceil(that.data.height / 2) -20);
context.rotate(-Math.PI / 2)
// context.drawImage(signImg, -that.data.width / 2, -that.data.height / 2, that.data.width, that.data.height)
context.drawImage(signImg, 0, 0, that.data.width, that.data.height)
// context.fill()
//繪制圖片 生成圖片函數寫在draw()的回調中,不然會出現還沒有畫圖就生成圖片的問題
context.draw(true,()=>{
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.height,
height: that.data.width,
destWidth: that.data.height,
destHeight: that.data.width,
canvasId: 'saveImg',
fileType: 'png',
success: function (res) {
var tempFilePath = res.tempFilePath;
console.log(tempFilePath);
that.setData({ src: tempFilePath })
// 生成圖片 並返回上一頁 賦值
let curPages = getCurrentPages();
var prevPage = curPages[curPages.length - 2]
prevPage.setData({
signImg: tempFilePath,
})
wx.navigateBack({
delta: 1
});
},
fail: function (res) {
console.log(res);
}
});
})
},
onLoad: function (options) {
},
onShow: function () {
// 進入頁面渲染canvas
let query = wx.createSelectorQuery();
const that = this;
let context
query.select('#firstCanvas').boundingClientRect();
query.exec(function (rect) {
let width = rect[0].width;
let height = rect[0].height;
that.setData({
width,
height
});
const context = wx.createCanvasContext('firstCanvas')
that.setData({
context: context
})
context.save();
// context.translate(Math.ceil(width / 2) - 20,0)
context.setTransform(1, 0, 0, 1, Math.ceil(width / 2), 155);
context.rotate(Math.PI / 2);
let str = that.data.writeTips;
// context.fillText(str, Math.ceil((width - context.measureText(str).width) / 2), Math.ceil(height / 2) - 20)
context.setFontSize(24)
context.setFillStyle('#ADADB2');
// context.fillRect(0, 0, that.data.height, that.data.width);
context.fillText(str, 0, 0)
context.restore();
context.draw()
});
},
// 彈窗
onToast(){
app.toast(this, {
type: 'text',
text: '生成成功'
})
},
onShareAppMessage: (res) => { }
})
相關注釋代碼中都有,也么有優化,有好的方法,還希望大佬們多多指點