小程序canvas手寫(xiě)簽名適配PC實(shí)現(xiàn)示例詳解
引言
繼上一篇的《絲滑流暢的手寫(xiě)簽名功能》博文才過(guò)去沒(méi)多久,我才發(fā)現(xiàn) canvas 2d 無(wú)法在 PC 的小程序中使用,真實(shí)白費(fèi)了我的優(yōu)化了,還好之前的代碼沒(méi)刪掉,原本以為直接簡(jiǎn)單改改就能用,發(fā)現(xiàn)還不是,下面看看吧。
先看看效果圖

鼠標(biāo)用起來(lái)效果不怎么樣,但是還是挺流暢的。
看看代碼
主要就看看 Page.js 的代碼吧,也就這個(gè)不一樣,當(dāng)然 HTML 內(nèi)的 canvas 標(biāo)簽記得加上 canvas-id,把 type = '2d' 給去掉。
// pages/mine/signature/drawCanvas/drawCanvas.js
var app = getApp()
Page({
data: {
context: null,
index: 0,
height: 0,
width: 0,
// 前 一點(diǎn)
preX: 0,
preY: 0,
preCenterX: 0,
preCenterY: 0
},
onShow: function () {
let query = wx.createSelectorQuery();
const that = this;
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.setStrokeStyle('#000000')
context.setLineWidth(2)
context.setFontSize(20)
});
},
/**記錄開(kāi)始點(diǎn) */
bindtouchstart: function (e) {
let context = this.data.context
let curX = e.changedTouches[0].x
let curY = e.changedTouches[0].y
context.beginPath()
context.moveTo(curX, curY)
this.data.preX = curX
this.data.preY = curY
this.data.preCenterX = curX
this.data.preCenterY = curY
},
/**記錄移動(dòng)點(diǎn),刷新繪制 */
bindtouchmove: function (e) {
let context = this.data.context
let preX = this.data.preX
let preY = this.data.preY
let preCenterX = this.data.preCenterX
let preCenterY = this.data.preCenterY
let curX = e.changedTouches[0].x
let curY = e.changedTouches[0].y
let deltaX = Math.abs(preX - curX)
let deltaY = Math.abs(preY - curY)
// 相差大于3像素的時(shí)候作二階貝塞爾曲線(xiàn)
if (deltaX >= 3 || deltaY >= 3) {
// 前后兩點(diǎn)中心點(diǎn)
let centerX = (preX + curX) / 2
let centerY = (preY + curY) / 2
//這里以前一點(diǎn)作為控制點(diǎn),中心點(diǎn)作為終點(diǎn),起始點(diǎn)為上一次的中點(diǎn),很流暢??!
context.moveTo(preCenterX, preCenterY)
context.quadraticCurveTo(preX, preY, centerX, centerY);
context.stroke();
context.draw(true);
this.data.preX = curX
this.data.preY = curY
this.data.preCenterX = centerX
this.data.preCenterY = centerY
}
},
/**清空畫(huà)布 */
clear: function () {
let context = this.data.context
context.clearRect(0, 0, this.data.width, this.data.height);
context.draw();
context.setStrokeStyle('#000000')
context.setLineWidth(2)
context.setFontSize(20)
},
/**導(dǎo)出圖片 */
export: function () {
const that = this;
this.data.context.draw(false, wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.width,
height: that.data.height,
destWidth: that.data.width,
destHeight: that.data.height,
fileType: 'png',
canvasId: 'firstCanvas',
success(res) {
app.log("tempFilePath:" + res.tempFilePath);
// 你的代碼
},
fail() {
wx.showToast({
title: '提交失敗',
icon: 'none',
duration: 2000
})
}
}))
},
})
下面仔細(xì)講講不同點(diǎn)
- 獲取canvas方式不一樣
這里因?yàn)槭褂玫氖桥f版本的 canvas,所以用的還是原來(lái)的方式獲取 canvas 的。
- 屬性值多加了 preCenterX 和 preCenterY
這個(gè)就很奇怪哦,可能是因?yàn)?canvas 的用法不一樣,導(dǎo)致使用貝塞爾曲線(xiàn)的時(shí)候無(wú)法正確的定位到前一點(diǎn)位置,也可能是里面的前一點(diǎn)位置就是 canvas 內(nèi)移動(dòng)時(shí)一系列點(diǎn)中前一個(gè)點(diǎn)的位置,放在就不對(duì),如果按前一篇博客的方式做,出來(lái)的就是下面的效果:

這里記得在手指初次落下的時(shí)候,初始化這兩個(gè)值,并在移動(dòng)后重新賦值。
- 導(dǎo)出圖片方式不一樣
這里就是網(wǎng)上一大堆的辦法,沒(méi)什么好說(shuō)的。
判別是否是PC版本
這里涉及一個(gè)判別是否是 pc 版本的小程序的問(wèn)題,看下面代碼
wx.getSystemInfo({
success:function(res){
that.setData({
systemInfo:res,
})
if(res.platform == "devtools"){
//開(kāi)發(fā)者工具
}else if(res.platform == "ios"){
//IOS
}else if(res.platform == "android"){
//android
}else {
//電腦了吧
}
}
})
在使用的地方合理選擇正確的手寫(xiě)簽名頁(yè)面就可以,這里建議分別做兩個(gè)頁(yè)面,別把功能耦合在一起。
注意事項(xiàng)
- 真機(jī)調(diào)試有問(wèn)題,真機(jī)調(diào)試 SelectorQuery.exec 方法不執(zhí)行回調(diào),太坑了。要查看的話(huà)使用預(yù)覽吧,預(yù)覽是沒(méi)問(wèn)題的。
- 還有就是橫豎屏問(wèn)題,我這設(shè)置的橫屏實(shí)際顯示的豎屏,可以在全局設(shè)置窗口改變吧,我就不動(dòng)了。
- 最后就是樣式問(wèn)題,為什么我的圖標(biāo)不行了?這里注意下 rpx 值的變化,這里是豎屏,在橫屏情況下值更大,看起來(lái)效果好。
結(jié)語(yǔ)
試了下沒(méi)問(wèn)題!而且調(diào)試器也是電腦版本,很奇怪為什么它可以使用 canvas 2d,而微信PC版本就不可以,開(kāi)發(fā)者論壇很多人反饋也不解決。

以上就是小程序canvas手寫(xiě)簽名適配PC實(shí)現(xiàn)示例詳解的詳細(xì)內(nèi)容,更多關(guān)于小程序canvas手寫(xiě)簽名適配PC的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序開(kāi)發(fā)中Promise的使用(aysnc,await)及場(chǎng)景分析
在微信小程序開(kāi)發(fā)中,錯(cuò)誤使用Promise可能導(dǎo)致無(wú)法正確獲取數(shù)據(jù),本文分析了一個(gè)常見(jiàn)錯(cuò)誤場(chǎng)景,即在異步函數(shù)中未使用await或.then()處理Promise,導(dǎo)致無(wú)法獲取異步操作的返回結(jié)果,文章提供了使用await和鏈?zhǔn)秸{(diào)用.then()的解決方法,幫助開(kāi)發(fā)者避免類(lèi)似錯(cuò)誤,確保數(shù)據(jù)正確返回2024-10-10
JavaScript之RegExp_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
正則表達(dá)式是一種用來(lái)匹配字符串的強(qiáng)有力的武器。它的設(shè)計(jì)思想是用一種描述性的語(yǔ)言來(lái)給字符串定義一個(gè)規(guī)則,凡是符合規(guī)則的字符串,我們就認(rèn)為它“匹配”了,否則,該字符串就是不合法的2017-06-06
Javascript圖片上傳前的本地預(yù)覽實(shí)例
圖片的上傳預(yù)覽功能主要用于圖片上傳前的一個(gè)效果的預(yù)覽,這篇文章主要介紹了Javascript圖片上傳前的本地預(yù)覽實(shí)例,需要的朋友可以參考下2014-06-06
JavaScript實(shí)現(xiàn)為指定對(duì)象添加多個(gè)事件處理程序的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)為指定對(duì)象添加多個(gè)事件處理程序的方法,可實(shí)現(xiàn)讓指定對(duì)象處理多個(gè)事件的功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04
TypeScript中type和interface的區(qū)別及注意事項(xiàng)
type的類(lèi)型別用可以用戶(hù)其他的類(lèi)型,比如聯(lián)合類(lèi)型、元祖類(lèi)型、基本類(lèi)型,interface不行,下面這篇文章主要給大家介紹了關(guān)于TypeScript中type和interface的區(qū)別及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下2022-10-10
JS使用正則截取兩個(gè)字符串之間的字符串實(shí)現(xiàn)方法詳解
這篇文章主要介紹了JS使用正則截取兩個(gè)字符串之間的字符串實(shí)現(xiàn)方法,結(jié)合實(shí)例形式簡(jiǎn)單分析了JS正則匹配與截取操作的實(shí)現(xiàn)技巧,并拓展分析了數(shù)量詞的概念與功能,需要的朋友可以參考下2017-01-01

