uniapp实现微信小程序的电子签名效果(附demo)
作者:瓜子三百克 发布时间:2024-04-19 09:55:39
标签:uniapp,小程序,电子签名
画布可以做很多事情,比如可以绘图,也可以做海报。在这里只是想拿它来的实现亲笔签名,开启不一样的亲笔签名姿势。
开发框架:uniapp
开发语言:vue2
展示平台:微信小程序(实际可以兼容多个平台)
标签和样式没什么好说的,这里绘制了简单的页面,见下图:
1、标签和样式
<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)">预览</button>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
/*
* 横屏后的适配方案
* @param $rpx为需要转换的字号
* @参考 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数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "亲笔签名",//导航栏标题
"pageOrientation": "landscape",//切换横屏
"enablePullDownRefresh": false,//关闭下拉刷新
"disableScroll": true // 整体页面禁止上下滑动
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#f5f5f5",
"navigationStyle": "default", // default/custom。custom即取消默认的原生导航栏
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
}
然后是绘制逻辑处理,注意点在代码中备注:
3、绘图
3.1、初始化数据会吧?
data() {
return {
canvasCtx: '', //绘图图像
points: [], //路径点集合
hasSign: false,
isInit: false,
}
},
onLoad(query) {
this.canvasCtx = uni.createCanvasContext('canvas_sign', this) //创建绘图对象
//设置画笔样式
this.canvasCtx.lineWidth = 6
// 设置线条的端点样式
this.canvasCtx.lineCap = 'round'
// 设置线条的交点样式
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、触摸结束,将未绘制的点清空防止对后续路径产生干扰,简单吧?
touchend: function() {
this.points = []
this.canvasCtx.draw(true)
},
3.5、绘制笔迹,没得问题吧?
这里有几个注意点:
1.为保证笔迹实时显示,必须在移动的同时绘制笔迹
2.为保证笔迹连续,每次从路径集合中区两个点作为起点(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、扫尾处理
上面的实现了,说明就可以签下你大名了。这里扫尾工作(按钮点击功能实现)只是景上添花。根据实际情况不一定要做。
<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('图片导出成功:', res)
let path = res.tempFilePath
// 保存图片
if (type === 2) {
that.uploadPic(path)
} else if (type === 3) {
// 预览图片
uni.previewImage({
urls: [path]
})
}
},
fail: (err) => {
// http://tmp/2LVQyvzddk2R820a9009dff43323d8e7fc9ef7a8d076.jpg
console.log('图片导出失败:', err)
}
})
})
}
})
}
},
// 图片上传处理
uploadPic(tempFile) {
// 1、将本地图片上传到服务器(假装是七牛云服务器)
// 2、将七牛云返回的链接,上传到我们的服务器平台
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
来源:https://blog.csdn.net/weixin_38633659/article/details/124700129


猜你喜欢
- 一、需求描述文本溢出省略,说实话这些年也实践过很多了,这次是针对富文本字符串,思量想去,也曾试图了解一些知名站点的实现方案,但结果不甚理想。
- 1 调试过程用Python3.6+Sciter+PyCharm写了一个py测试脚本helloworld.py,该脚本中只含有一条语句“imp
- Python版本是2.7.9,在win8上测试成功,就是抓取有点慢,本来想用多线程的,有事就罢了。模板之家的网站上的url参数与页数不匹配,
- 本文实例为大家分享了python实现抠图给证件照换背景的具体代码,供大家参考,具体内容如下import cv2import numpy as
- 酝酿了将近一个春夏秋冬的腾讯网首页终于亮剑!反响热烈!让我们来分享它成功背后的酸甜苦辣吧。腾讯网首页改版终于开花结果。于2008年3月25日
- 前言:PyPDF2是一个纯Python的开源库,能够分割或合并PDF文件,也可以裁剪或转换PDF文件中的页面。我们还可以使用PyPDF2查看
- 概览因工作场景,需要在python代码里调用Jar包来实现一些功能,调研下来主要有两种方式:java -jar xx.jarJPype环境配
- 1、在命令行里停止MySQL服务:net stop mysql2、修改mysql安装目录下的my,ini,将default-ch
- mitmproxy有3中监听请求与响应的方式:mitmproxy控制台方式mitmdump与Python对接的方式mitmweb可视化方式前
- 本文实例讲述了MySQL 的启动选项和系统变量。分享给大家供大家参考,具体如下:MySQL的配置信息可以通过两种方式实现,一种是命令行形式,
- http://www.cppcns.com/shujuku/mysql/283231.html 也可以参照这个8.0
- 问题:我们每天都要编写一些Python程序,或者用来处理一些文本,或者是做一些系统管理工作。程序写好后,只需要敲下python命令,便可将程
- 如何清除Vbscript惹出来的中文乱码? <script language=vbscript runat=s
- '*****************************************************************
- Python包导入报错的问题首先,一般来说,写一个小demo可能一个文件就够了,但是要是做一个小项目,可能需要拆分成很多零散的文件,放在不同
- 环境:python3 + unittest + requestsExcel管理测试用例,HTMLTestRunner生成测试报告测试完成后邮
- 正在看的ORACLE教程是:ORACLE常见错误代码的分析与解决三。 -----------------------------
- 一、Python 切片的一些用法alist = [3,4,5,6,7,9,11,13,15,17]print(alist[::]) # 返回
- folium是python的一个用来绘制地图,并在地图上打点,画圈,做颜色标记的工具类。简单易学,和pandas可以很好的融合,是居家必备良
- 方法一 <%dim total(7,3) total(1,0)="ASP之家"&n