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

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)換的字號
* @參考 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】文件中添加橫屏切換配置
注意:不同的平臺橫屏切換將有所不一樣。這里是針對微信小程序的橫屏適配
{
"pages": [ //pages數(shù)組中第一項表示應(yīng)用啟動頁,參考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "親筆簽名",//導(dǎo)航欄標(biāo)題
"pageOrientation": "landscape",//切換橫屏
"enablePullDownRefresh": false,//關(guān)閉下拉刷新
"disableScroll": true // 整體頁面禁止上下滑動
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#f5f5f5",
"navigationStyle": "default", // default/custom。custom即取消默認(rèn)的原生導(dǎo)航欄
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
}
然后是繪制邏輯處理,注意點在代碼中備注:
3、繪圖
3.1、初始化數(shù)據(jù)會吧?
data() {
return {
canvasCtx: '', //繪圖圖像
points: [], //路徑點集合
hasSign: false,
isInit: false,
}
},
onLoad(query) {
this.canvasCtx = uni.createCanvasContext('canvas_sign', this) //創(chuàng)建繪圖對象
//設(shè)置畫筆樣式
this.canvasCtx.lineWidth = 6
// 設(shè)置線條的端點樣式
this.canvasCtx.lineCap = 'round'
// 設(shè)置線條的交點樣式
this.canvasCtx.lineJoin = 'round'
},
3.2、觸摸開始時獲取起點,會吧?
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)
//每次觸摸開始,開啟新的路徑
this.canvasCtx.beginPath()
},
3.3、觸摸移動獲取路徑點,會吧?
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) //存點
let len = this.points.length
if (len >= 2) {
this.draw() //繪制路徑
}
},
3.4、觸摸結(jié)束,將未繪制的點清空防止對后續(xù)路徑產(chǎn)生干擾,簡單吧?
touchend: function() {
this.points = []
this.canvasCtx.draw(true)
},
3.5、繪制筆跡,沒得問題吧?
這里有幾個注意點:
1.為保證筆跡實時顯示,必須在移動的同時繪制筆跡
2.為保證筆跡連續(xù),每次從路徑集合中區(qū)兩個點作為起點(moveTo)和終點(lineTo)
3.將上一次的終點作為下一次繪制的起點(即清除第一個點)
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、掃尾處理
上面的實現(xiàn)了,說明就可以簽下你大名了。這里掃尾工作(按鈕點擊功能實現(xiàn))只是景上添花。根據(jù)實際情況不一定要做。
<script>
export default {
methods: {
// 底部按鈕點擊操作
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ù)器平臺
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實現(xiàn)微信小程序的電子簽名效果的文章就介紹到這了,更多相關(guān)uniapp小程序電子簽名內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
每天一篇javascript學(xué)習(xí)小結(jié)(RegExp對象)
這篇文章主要介紹了javascript中的RegExp對象知識點,對RegExp對象的基本使用方法,以及各種方法進(jìn)行整理,感興趣的小伙伴們可以參考一下2015-11-11

