uniapp实现微信小程序的电子签名效果(附demo)

目录
  • 1、标签和样式
  • 2、横屏切换
  • 3、绘图
    • 3.1、初始化数据会吧?
    • 3.2、触摸开始时获取起点,会吧?
    • 3.3、触摸移动获取路径点,会吧?
    • 3.4、触摸结束,将未绘制的点清空防止对后续路径产生干扰,简单吧?
    • 3.5、绘制笔迹,没得问题吧?
  • 4、扫尾处理

画布可以做很多事情,比如可以绘图,也可以做海报。在这里只是想拿它来的实现亲笔签名,开启不一样的亲笔签名姿势。

开发框架: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

到此这篇关于uniapp实现微信小程序的电子签名效果的文章就介绍到这了,更多相关uniapp小程序电子签名内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • uniapp小程序实现瀑布流布局的思路与代码

    一.前言 现在写瀑布流算不算是炒冷饭啊? 我不管, 我就要写,谁也别想拦我. 瀑布流应该算是很常见的一种布局方法了,大致的思路也很好理解, 但是在小程序里面确有另外需要考虑的几个问题. 问题1:uniapp是基于Vue的,所以不好直接操作DOM. 问题2:uniapp基于Vue,但也做了一些修改,所以不好拿ref来操作 二.先说思路 为了保证文章的长度,以及有些小伙伴对瀑布流的基本思路不是很了解,所以先讲讲瀑布流的思路,先看下图. 可以看到,商品的图片高度是不一致的,再加上商品标题的行数不一致,

  • 使用 UniApp 实现小程序的微信登录功能

    1.微信登录思路: 在main.js 中封装公共函数,用于判断用户是否登录 在main.js 中分定义全局变量,用于存储接口地址 如果没有登录.则跳转至登录页面 进入登录页面 通过 wx.login 获取用户的 code 通过 code 获取用户的 SessionKey.OpenId 等信息[本应后台接口.但是此处使用js发送请求] 通过 openId 调用后台 Api 获取用户的信息 获取成功,则说明已经授权过了,直接登录成功 获取失败,则说明没有授权过,需要授权之后才能进行登录 用户点击页面

  • uniapp封装小程序雷达图组件的完整代码

    效果图: 实现代码如下 view <canvas id="radar-canvas" class="radar-canvas" type="2d"></canvas> style .radar-canvas width 550rpx height 550rpx margin 0 auto script <script> import { toRpx } from "@/utils/common&quo

  • uniapp开发小程序实现全局悬浮按钮的代码

    目录 看效果 须知: 1.uni.getSystemInfoSync()获取手机的信息接口 2.uni.createSelectorQuery().in(this) 3.touchmove滑动事件 取出存储的值 赋值 全局注册组件 看效果 这是一个全局的按钮,可以换成图片,自己写样式,每个页面都有: 须知: 1.uni.getSystemInfoSync()获取手机的信息接口 可以拿到手机屏幕的宽高 2.uni.createSelectorQuery().in(this) uniapp中式没有w

  • uniapp微信小程序实现一个页面多个倒计时

    本文实例为大家分享了uniapp实现一个页面多个倒计时的具体代码,供大家参考,具体内容如下 设计图(需求) 在这里插入图片描述 结构 <view class="group-list" v-for="item in message" :key="item.productId"> <view class="group-img" @click="navTo"> <image :src

  • uniapp,微信小程序中使用 MQTT的问题

    最近在uniapp打包成微信小程序的项目中第一次用到了MQTT.使用比较简单,但是还是遇到了一些问题.在此记录一下. 官方文档:MQTT Github 官方MQTT测试工具:MQTTX.测试工具使用说明 MQTT的js文件:mqtt.min.js 先上一点注意事项: (1)MQTT.js 一个 MQTT 协议的客户端库,用 JavaScript 编写,可用于 Node.js 和浏览器.在 Node.js 端可以通过全局安装使用命令行连接,同时还支持 MQTT ,MQTT TLS 证书连接:值得一

  • uniapp开发小程序的经验总结

    1. 新建UI项目 首先,我们的UI是基于ColorUI,当ColorUI没有的样式,就基于Uniapp自带的UI.所以项目的开始要引入这两个UI框架. 如下,新建一个uni-ui项目. 再建立一个ColorUI项目. 如果需要观看ColorUI的效果以便直到自己需要用哪些组件,可以将其运行起来,如下. uni-ui同理.这样只要我们需要的样式都可以在这两个UI取材了. 2. 搭建自己的项目 新建一个自己的uniapp项目,建立完成后.项目结构如下. 接着先引入ColorUI样式: 将Color

  • uniapp开发小程序实现滑动页面控制元素的显示和隐藏效果

    前言 实现思路:通过小程序API中的触摸事件,配合CSS来实现元素的显示和隐藏.ps(也想过另一种通过监听页面滚动的方式来实现,不过效果一定很差0.0) 一.需要用到的事件touchmove.touchend 二.话不多说上代码 1.看需求,如果是整个屏幕滑动后元素发生变化,最好放在最外面的view 代码如下: <view class="container" @touchmove="handletouchstart" @touchend="handl

  • uniapp实现微信小程序的电子签名效果(附demo)

    目录 1.标签和样式 2.横屏切换 3.绘图 3.1.初始化数据会吧? 3.2.触摸开始时获取起点,会吧? 3.3.触摸移动获取路径点,会吧? 3.4.触摸结束,将未绘制的点清空防止对后续路径产生干扰,简单吧? 3.5.绘制笔迹,没得问题吧? 4.扫尾处理 画布可以做很多事情,比如可以绘图,也可以做海报.在这里只是想拿它来的实现亲笔签名,开启不一样的亲笔签名姿势. 开发框架:uniapp开发语言:vue2展示平台:微信小程序(实际可以兼容多个平台) 标签和样式没什么好说的,这里绘制了简单的页面,

  • uni-app使用微信小程序云函数的步骤示例

    创建云函数目录 首先,我们需要在uni-app项目文件夹下,创建一个云函数目录,路径随意,我这里是functions.然后先随便在里面放一些文件,这里以new_file.css为例.(放文件的原因是:确保编译成小程序后cloudfunctions文件夹存在.如果该文件夹下没有文件,默认是不会在微信小程序开发平台中显示该文件夹的.) 修改manifest.json 在uni-app根目录下,修改manifest.json中的微信小程序项,结构如下 "mp-weixin" : { /* 小

  • uniapp在微信小程序中使用ECharts的方法

    今天使用uniapp集成Echarts,实现地图图表的展示 可以参照mpvue-echarts 参照:https://github.com/F-loat/mpvue-echarts https://ask.dcloud.net.cn/article/36288 进行改进 网上有很多教程,但都说的不是很明白,下面直接上步骤 1.npm install echarts mpvue-echarts 执行该命令后,会在node_modules下生成mpvue-echarts.echarts,然后把mpv

  • uniapp 实现微信小程序全局分享的示例代码

    目录 创建全局分享内容文件 引入并全局注册该文件 自定义页面分享内容  uniapp 实现微信小程序的全局转发给好友/分享到朋友圈的功能.主要使用 Vue.js 的 全局混入 概念. 下面直接上 实现步骤和代码: 创建全局分享内容文件 1.创建一个全局分享的 js 文件.示例文件路径为:@/common/share.js ,在该文件中定义全局分享的内容: export default { data() { return { // 默认的全局分享内容 share: { title: '全局分享的标

  • 利用uni-app生成微信小程序的踩坑记录

    目录 前言 1.不允许id选择器 2.默认竖排 3.图片加载不出来 4.eval函数不可用 5.getStorage异步 6.props的中的值不可修改 7.wx.uploadFile携带字符串参数 8.picker的multiSelector mode中选择框出现undefined 总结 前言 毕设要求写一个浏览器端,一个APP端,一个微信端,刚开始以为要学三个技术然后写三个客户端,后来知道了uni-app这个神器,一次编写就可以编译生成APP.H5以及各种小程序版本的客户端.然而我比较熟悉的

  • uniapp开发微信小程序自定义顶部导航栏功能实例

    目录 自定义导航栏渐变色,先上效果 重点来了,导航栏设置渐变色 补充:更换图标 总结 自定义导航栏渐变色,先上效果 使用uniapp开发小程序,在不同界面,要去对页面进行修改顶部导航栏. 比如说要去定义导航栏的背景颜色,常规的去定义导航栏背景颜色 全局定义导航栏 "window": { "navigationBarBackgroundColor": "#32A2FD", // 顶部背景颜色 "navigationBarTitleText

  • 微信小程序 tabs选项卡效果的实现

    微信小程序 tabs选项卡效果 前言: 最近微信应用号是炒的如火如荼,热门满满,但是也可以发现搜索关键词出来,各类网站出现的还都是微信的官方文档解释.正好赶上这个热潮,这几天先把小程序技术文档看了个遍,就直接着手写案例了.很多组件微信内部已经封装完了,正好发现没有tab选项卡效果,这两天正好研究了下.思路如下: 1.首先点击导航的时候需要两个变量,一个存储当前点击样式类,一个是其它导航默认的样式类 2.选项卡内容列表同样也需要两个变量,一个存储当前显示块,一个存储的是其它隐藏的默认块 3.使用三

  • 微信小程序五星评分效果实现代码

    微信小程序五星评分效果实现代码 很多做过电商项目的朋友会经常用到评分的功能,我这里正好写了一个例子,发出来分享一下: 我写的是5分满分制的,首先,准备3个图片, ,像这样的,分别代表分数为0,0.5,1 时的状态, 效果图:(以3.5为例) 然后上代码: js: function pingfenxing(pingfen){ var that=this, //这里是图片的路径,自己需要改 data={ ling:"img/pingfen0.png", zheng:"img/pi

  • 微信小程序实现日历效果

    本文实例为大家分享了微信小程序实现日历效果的具体代码,供大家参考,具体内容如下 效果预览: wxml部分: <view class='box1' style='width: {{ sysW * 7 }}px'> <view class='dateBox'>{{ year }} - {{ month}}</view> <block wx:for='{{ weekArr }}'> <view style='width: {{ sysW }}px; heig

  • 微信小程序实现选项卡效果

    本文实例为大家分享了微信小程序实现选项卡效果展示的具体代码,供大家参考,具体内容如下 demo.wxss .swiper-tab{ width: 100%; border-bottom: 2rpx solid #777777; text-align: center; line-height: 80rpx;} .swiper-tab-list{ font-size: 30rpx; display: inline-block; width: 33.33%; color: #777777; } .on

随机推荐