小程序canvas實現簽名功能,封裝canvas簽名功能組件
剛剛接觸小程序,因爲項目需求,有簽名功能研究了很久,網上也找了不少資料,最終實現了canvas簽名功能,並封裝成可用組件
canvas組件代碼
wxml
<view class="wrapper">
<view class="back" catchtap="back">返回</view>
<view class="handBtn">
<button catchtap="cleardraw" class="delBtn">清空</button>
<button catchtap="getimg" class="subBtn">完成</button>
</view>
<view class="handCenter">
<canvas class="canvas"
id="canvas"
canvas-id="canvas"
disable-scroll="true"
bindtouchstart="canvasStart"
bindtouchmove="canvasMove"
binderror="canvasIdErrorCallback"></canvas>
<cover-image class='overImg' src="{{src}}" wx:if="{{src!=''}}"></cover-image>
</view>
</view>
wxss
.wrapper{
position: fixed;
top:0;
bottom: 0;
right: 0;
left: 0;
box-sizing: border-box;
background-color: #fff;
}
.back{
width: 160rpx;
background: #008ef6;
margin: 20rpx;
padding: 10rpx 0;
color:#fff;
border-radius:16rpx;
text-align: center;
}
.handCenter{
box-sizing: border-box;
width: 100%;
}
canvas {
width:100%;
height: 800rpx;
margin:auto;
}
.overImg{
width: 200rpx;
height: 200rpx;
}
.handCenter {
box-sizing: border-box;
}
.handBtn {
height: 100rpx;
display: flex;
align-content: space-between;
align-items: center;
margin-top:40rpx;
}
.delBtn {
width: 40%;
color: #666;
}
.subBtn {
width: 40%;
background: #008ef6;
color: #fff;
}
button{
font-size: 28rpx;
}
js
// pages/component/signature/signature.js
var cxt = null;// 使用 wx.createContext 獲取繪圖上下文 cxt
var arrx = [];//所有點的X軸集合
var arry = [];//所有點的Y軸集合
var canvasw = 0;//畫布的寬
var canvash = 0;//畫布的高
// var canvasTop=0;
// var canvasLeft=0;
Component({
/**
* 組件的屬性列表
*/
properties: {
can:Boolean,//用於顯示隱藏canvas
},
/**
* 組件的初始數據
*/
data: {
src:""
},
/**
* 組件的方法列表
*/
methods: {
//顯示隱藏組件
back(){
//子組件傳遞給父組件一個方法canvasDis,並傳遞一個參數src給父組件
this.triggerEvent("canvasDis",{src:this.data.src})
},
//創建canvas上下文
createdCanvas(){
wx.showLoading({
title: '加載中...',
mask: true
})
// 使用 wx.createContext 獲取繪圖上下文 cxt
//創建 canvas 的繪圖上下文,因爲這裏是封裝成組件,所有需要加this
cxt = wx.createCanvasContext('canvas',this);
cxt.beginPath();
//封裝成組件,所有需要in(this),如果不加無法創建畫布
var query = wx.createSelectorQuery().in(this).select('.handCenter');
query.boundingClientRect(rect => {
// canvasTop = rect.top;
// canvasLeft = rect.left;
canvasw = rect.width;
canvash = rect.height;
wx.hideLoading()
}).exec();
},
//canvas發生錯誤時觸發
canvasIdErrorCallback(e){
console.error(e.detail.errMsg)
},
//canvas觸摸開始
canvasStart(e){
arrx.push(e.changedTouches[0].x);
arry.push(e.changedTouches[0].y);
},
//canvas觸摸過程中
canvasMove(e){
let len = arrx.length;
cxt.moveTo(arrx[len - 1], arry[len - 1]);//把路徑移動到畫布中指定的點,第一個參數爲x軸,第二個參數爲y軸
arrx.push(e.changedTouches[0].x);//手指移動過程中canvas的橫座標存入到全局數組變量arrx中
arry.push(e.changedTouches[0].y);//手指移動過程中canvas的縱座標存入到全局數組變量arry中
cxt.lineTo(e.changedTouches[0].x, e.changedTouches[0].y);//moveTo座標到lineTo座標的
cxt.setLineWidth(4);//設置線條的寬度
cxt.setLineCap('round');//設置結束時 點的樣式
cxt.stroke();//畫線
cxt.draw(true);//設置爲true時,會保留上一次畫出的圖像,false則會清空(方式二設置爲false,一爲true)
},
getimg() {
if (arrx.length == 0) {
wx.showModal({
title: '提示',
content: '簽名內容不能爲空!',
showCancel: false
});
return false;
};
wx.showLoading({
title: '簽名生成中..',
mask:true
})
let that = this;
wx.canvasToTempFilePath({
canvasId: 'canvas',
success: function (res) {
that.setData({
src: res.tempFilePath
})
wx.hideLoading();
//子組件傳遞給父組件一個方法canvasDis,並傳遞一個參數src給父組件
that.triggerEvent("canvasDis",{src:res.tempFilePath})
}
},this)
},
cleardraw() {
//清除畫布
arrx = [];
arry = [];
cxt.clearRect(0, 0, canvasw, canvash);
cxt.draw();
this.setData({src:''});
},
canvasEnd(e){}
},
ready(){
this.createdCanvas()
}
})
父組件調用canvas簽名功能,在子組件的json文件夾中,"component": true,
父json文件中,給子組件定義一個名稱,並引入路徑
父中wxml中使用,因爲我這裏定義的名稱是signature,所以可以直接signature來使用子組件
<view class="usermotto" bindtap="handlChangeCanvasShow">顯示canvas簽名功能</view>
<signature
wx:if="{{can}}"
backInfo="{{can}}"
bindcanvasDis="handlChangeCanvasShow"
></signature>
js
//index.js
//獲取應用實例
const app = getApp()
Page({
data: {
can:false,
src:"",
},
//handlChangeCanvasShow自定義事件,子組件傳遞過來的方法和數據
handlChangeCanvasShow(e){
//顯示隱藏canvas
this.setData({
can:(!this.data.can),
src:e.detail.src
})
}
})
以上便是canvas簽名功能組件的封裝和使用,小程序官方文檔建議使用canvas-2d,就版本的canvas已經不維護和更新了,後期有時間再補更!