uniapp實(shí)現(xiàn)微信小程序的電子簽名效果(附demo)
畫布可以做很多事情,比如可以繪圖,也可以做海報(bào)。在這里只是想拿它來(lái)的實(shí)現(xiàn)親筆簽名,開(kāi)啟不一樣的親筆簽名姿勢(shì)。
開(kāi)發(fā)框架:uniapp
開(kāi)發(fā)語(yǔ)言:vue2
展示平臺(tái):微信小程序(實(shí)際可以兼容多個(gè)平臺(tái))
標(biāo)簽和樣式?jīng)]什么好說(shuō)的,這里繪制了簡(jiǎn)單的頁(yè)面,見(jiàn)下圖:

1、標(biāo)簽和樣式
<template>
<view class="page-content">
<view class="form">
<view class="form-content">
<canvas class="form-content__canvas" canvas-id="canvas_sign" @touchstart="touchstart"
@touchmove="touchmove" @touchend="touchend" disable-scroll="true"></canvas>
</view>
<view class="form-footer">
<button class="form-footer__reset" @click="autographClick(1)">重置</button>
<button class="form-footer__save" @click="autographClick(2)">保存</button>
<button class="form-footer__preview" @click="autographClick(3)">預(yù)覽</button>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
/*
* 橫屏后的適配方案
* @param $rpx為需要轉(zhuǎn)換的字號(hào)
* @參考 https://blog.csdn.net/sdfsfsdscd/article/details/91375066
**/
@function tovmin($rpx) {
@return #{$rpx * 100 / 750}vmin;
}
.page-content {
width: 100vw;
height: 100vh;
.form {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
.form-content {
width: 100%;
height: 100%;
&__canvas {
height: calc(100vh - tovmin(20) - tovmin(120) - constant(safe-area-inset-bottom));
height: calc(100vh - tovmin(20) - tovmin(120) - env(safe-area-inset-bottom));
width: 100vw;
}
}
.form-footer {
padding-top: tovmin(20);
height: calc(tovmin(120) + constant(safe-area-inset-bottom));
height: calc(tovmin(120) + env(safe-area-inset-bottom));
width: 100%;
display: flex;
flex-direction: row;
background: #FFFFFF;
box-shadow: 0 tovmin(4) tovmin(20) tovmin(2) rgba(183, 183, 183, 0.20);
button {
width: 20vw;
height: tovmin(88);
line-height: tovmin(88);
border-radius: tovmin(48);
text-align: center;
font-size: tovmin(36);
font-weight: bold;
}
button::after {
border: none;
}
&__reset {
color: #008AFE;
border: tovmin(1) solid #008AFE;
}
&__save {
background-image: linear-gradient(135deg, #1BC5FF 0%, #008AFE 100%);
}
&__preview {
color: #008AFE;
border: tovmin(1) solid #008AFE;
}
}
}
}
</style>
2、橫屏切換
到【pages.json】文件中添加橫屏切換配置
注意:不同的平臺(tái)橫屏切換將有所不一樣。這里是針對(duì)微信小程序的橫屏適配
{
"pages": [ //pages數(shù)組中第一項(xiàng)表示應(yīng)用啟動(dòng)頁(yè),參考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "親筆簽名",//導(dǎo)航欄標(biāo)題
"pageOrientation": "landscape",//切換橫屏
"enablePullDownRefresh": false,//關(guān)閉下拉刷新
"disableScroll": true // 整體頁(yè)面禁止上下滑動(dòng)
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#f5f5f5",
"navigationStyle": "default", // default/custom。custom即取消默認(rèn)的原生導(dǎo)航欄
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
}
然后是繪制邏輯處理,注意點(diǎn)在代碼中備注:
3、繪圖
3.1、初始化數(shù)據(jù)會(huì)吧?
data() {
return {
canvasCtx: '', //繪圖圖像
points: [], //路徑點(diǎn)集合
hasSign: false,
isInit: false,
}
},
onLoad(query) {
this.canvasCtx = uni.createCanvasContext('canvas_sign', this) //創(chuàng)建繪圖對(duì)象
//設(shè)置畫筆樣式
this.canvasCtx.lineWidth = 6
// 設(shè)置線條的端點(diǎn)樣式
this.canvasCtx.lineCap = 'round'
// 設(shè)置線條的交點(diǎn)樣式
this.canvasCtx.lineJoin = 'round'
},
3.2、觸摸開(kāi)始時(shí)獲取起點(diǎn),會(huì)吧?
touchstart: function(e) {
if (!this.isInit) {
this.isInit = true
this.autographClick(1);
}
let startX = e.changedTouches[0].x
let startY = e.changedTouches[0].y
let startPoint = {
X: startX,
Y: startY
}
this.points.push(startPoint)
//每次觸摸開(kāi)始,開(kāi)啟新的路徑
this.canvasCtx.beginPath()
},
3.3、觸摸移動(dòng)獲取路徑點(diǎn),會(huì)吧?
touchmove: function(e) {
let moveX = e.changedTouches[0].x
let moveY = e.changedTouches[0].y
let movePoint = {
X: moveX,
Y: moveY
}
this.points.push(movePoint) //存點(diǎn)
let len = this.points.length
if (len >= 2) {
this.draw() //繪制路徑
}
},
3.4、觸摸結(jié)束,將未繪制的點(diǎn)清空防止對(duì)后續(xù)路徑產(chǎn)生干擾,簡(jiǎn)單吧?
touchend: function() {
this.points = []
this.canvasCtx.draw(true)
},
3.5、繪制筆跡,沒(méi)得問(wèn)題吧?
這里有幾個(gè)注意點(diǎn):
1.為保證筆跡實(shí)時(shí)顯示,必須在移動(dòng)的同時(shí)繪制筆跡
2.為保證筆跡連續(xù),每次從路徑集合中區(qū)兩個(gè)點(diǎn)作為起點(diǎn)(moveTo)和終點(diǎn)(lineTo)
3.將上一次的終點(diǎn)作為下一次繪制的起點(diǎn)(即清除第一個(gè)點(diǎn))
draw: function() {
let point1 = this.points[0]
let point2 = this.points[1]
this.points.shift()
this.canvasCtx.moveTo(point1.X, point1.Y)
this.canvasCtx.lineTo(point2.X, point2.Y)
this.canvasCtx.stroke()
this.canvasCtx.draw(true)
this.hasSign = true
},
4、掃尾處理
上面的實(shí)現(xiàn)了,說(shuō)明就可以簽下你大名了。這里掃尾工作(按鈕點(diǎn)擊功能實(shí)現(xiàn))只是景上添花。根據(jù)實(shí)際情況不一定要做。
<script>
export default {
methods: {
// 底部按鈕點(diǎn)擊操作
autographClick(type) {
let that = this
if (type === 1) {
//清空畫布
this.hasSign = false
uni.getSystemInfo({
success: function(res) {
let canvas = uni.createSelectorQuery().select('.form-content__canvas')
canvas.boundingClientRect().exec(function(data) {
console.log('canvas', data)
console.log('canvas wh:' + data[0].width + 'X' + data[0].height)
let canvasw = Math.ceil(data[0].width)
let canvash = Math.ceil(data[0].height)
that.canvasCtx.fillStyle = '#fff'
that.canvasCtx.fillRect(0, 0, canvasw, canvash)
that.canvasCtx.draw(true)
})
}
})
} else {
if (!this.hasSign) {
uni.showToast({
title: '簽名不能為空',
icon: 'none',
duration: 2000
})
return
}
uni.getSystemInfo({
success: function(res) {
let canvas = uni.createSelectorQuery().select('.form-content__canvas')
canvas.boundingClientRect().exec(function(data) {
console.log('canvas saveSign:', data[0].width + 'X' + data[0].height)
let canvasw = Math.ceil(data[0].width)
let canvash = Math.ceil(data[0].height)
uni.canvasToTempFilePath({
destWidth: canvasw,
destHeight: canvash,
fileType: 'jpg',
canvasId: 'canvas_sign',
success: function(res) {
console.log('圖片導(dǎo)出成功:', res)
let path = res.tempFilePath
// 保存圖片
if (type === 2) {
that.uploadPic(path)
} else if (type === 3) {
// 預(yù)覽圖片
uni.previewImage({
urls: [path]
})
}
},
fail: (err) => {
// http://tmp/2LVQyvzddk2R820a9009dff43323d8e7fc9ef7a8d076.jpg
console.log('圖片導(dǎo)出失?。?, err)
}
})
})
}
})
}
},
// 圖片上傳處理
uploadPic(tempFile) {
// 1、將本地圖片上傳到服務(wù)器(假裝是七牛云服務(wù)器)
// 2、將七牛云返回的鏈接,上傳到我們的服務(wù)器平臺(tái)
console.log("------:", tempFile);
uni.showLoading({
title: '正在上傳中...'
})
setTimeout(() => {
uni.showToast({
title: '假裝簽名上傳成功',
duration: 2000,
icon: 'none'
});
}, 1000);
}
}
}
</script>
demo地址:
gitee地址:https://gitee.com/chenzm_186/autograph-mini.git
到此這篇關(guān)于uniapp實(shí)現(xiàn)微信小程序的電子簽名效果的文章就介紹到這了,更多相關(guān)uniapp小程序電子簽名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
每天一篇javascript學(xué)習(xí)小結(jié)(RegExp對(duì)象)
這篇文章主要介紹了javascript中的RegExp對(duì)象知識(shí)點(diǎn),對(duì)RegExp對(duì)象的基本使用方法,以及各種方法進(jìn)行整理,感興趣的小伙伴們可以參考一下2015-11-11
js實(shí)現(xiàn)可以點(diǎn)擊收縮或張開(kāi)的懸浮窗
這篇文章主要介紹了js實(shí)現(xiàn)可以點(diǎn)擊收縮或張開(kāi)的懸浮窗效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
JavaScript?評(píng)測(cè)代碼運(yùn)行速度的案例代碼
在?JavaScript?中,可以使用?performance.now()?API?來(lái)評(píng)測(cè)代碼的運(yùn)行速度。該?API?返回當(dāng)前頁(yè)面的高精度時(shí)間戳,您可以在代碼執(zhí)行前后調(diào)用它來(lái)計(jì)算代碼執(zhí)行所需的時(shí)間,這篇文章主要介紹了JavaScript?評(píng)測(cè)代碼運(yùn)行速度,需要的朋友可以參考下2023-02-02
JS實(shí)現(xiàn)多物體運(yùn)動(dòng)的方法詳解
這篇文章主要介紹了JS實(shí)現(xiàn)多物體運(yùn)動(dòng)的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了javascript實(shí)現(xiàn)多物體運(yùn)動(dòng)的原理與相關(guān)操作技巧,需要的朋友可以參考下2018-01-01

