当前位置: 首页 > news >正文

uni-app 微信小程序 电子签名及签名图片翻转显示功能

文章目录

    • 1. 需求背景
    • 2. 开始撸
      • 2.1 点击 重写 进入签名页面(上图一)
      • 2.2 书写签名,点击确认返回,及图片翻转显示(上图二,三)
    • 3. 图片进行翻转,返回翻转后的图片

1. 需求背景

接的一个开发一个小程序,需求很简单,使用uni-app实现一个微信小程序的电子签名功能请添加图片描述

2. 开始撸

2.1 点击 重写 进入签名页面(上图一)

在这里插入图片描述

<template><view><view class="ft-26 color-red mt-20 mb-20">本人承诺以上检查内容真实</view><view class="sign"><view class="sign-header"><span><i class="color-red">*</i> 本人签名</span><div @click="goSign"><img class="edit-icon" :src="require('@/static/images/edit.png')" alt=""><label for="">重写</label></div></view><img class="sign-img" :src="tempFilePath"></view></view>
</template><script>export default {data() {return {tempFilePath: "",}},methods: {// 点击重写,进入签名页面goSign() {uni.navigateTo({url: `/examine/q-sign`})},// 签名页面返回回来,接收签名照片展示getTempFilePath(data) {let { tempFilePath } = JSON.parse(data)this.tempFilePath = tempFilePath},},}
</script><style lang="scss" scoped>.report-view {height: 50vh;background: #fff;}.popup-content {width: 100vw;height: 100vh;}.sign {border-radius: 10rpx;border: 1rpx solid #E6E6E6;overflow: hidden;.sign-header {line-height: 56rpx;background: #E8EFF8;border-radius: 0px;display: flex;justify-content: space-between;padding: 0 20rpx;font-size: 26rpx;display: flex;align-items: center;.edit-icon {width: 24rpx;height: 24rpx;display: inline-block;margin-right: 5rpx;}span {i {line-height: 56rpx;display: inline-block;margin-right: 10rpx;}}text {font-weight: 500;color: #999999;}}.sign-img {width: 100%;height: 300rpx;background: #fff;}}
</style>

2.2 书写签名,点击确认返回,及图片翻转显示(上图二,三)

在这里插入图片描述
完整代码

<template><view><!-- 自定义导航栏 --><NaviBar title="签署" :autoBack="true" /><view class="wrapper"><view class="handBtn"><button @click="retDraw" class="delBtn">清除</button><button @click="saveCanvasAsImg" class="saveBtn">取消</button><button @click="subCanvas" class="subBtn">确认</button></view><view class="handCenter"><canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart"@touchmove="uploadScaleMove" canvas-id="handWriting" /><!--用于旋转图片的canvas容器--><canvas style="position: absolute" :style="{ width: cavWidth, height: cavWidth1 }"canvas-id="handWriting2"></canvas></view></view></view>
</template><script>export default {name: 'Signature',data() {return {canvasName: 'handWriting',ctx: '',startX: null,startY: null,canvasWidth: 0,canvasHeight: 0,selectColor: 'black',lineColor: '#1A1A1A', // 颜色canvas: null,cavWidth: 2000,cavWidth1: 2000,lineSize: 5, // 笔记倍数}},onLoad({location}) {if (location) {this.location = location;}this.ctx = uni.createCanvasContext('handWriting', this)this.$nextTick(() => {uni.createSelectorQuery().select('.handCenter').boundingClientRect((rect) => {this.canvasWidth = rect.widththis.canvasHeight = rect.height/* 将canvas背景设置为 白底,不设置  导出的canvas的背景为透明 */this.setCanvasBg('#fff')}).exec()})},methods: {// 笔迹开始uploadScaleStart(e) {this.startX = e.changedTouches[0].xthis.startY = e.changedTouches[0].y//设置画笔参数//画笔颜色this.ctx.setStrokeStyle(this.lineColor)//设置线条粗细this.ctx.setLineWidth(this.lineSize)//设置线条的结束端点样式this.ctx.setLineCap('round') //'butt'、'round'、'square'//开始画笔this.ctx.beginPath()},// 笔迹移动uploadScaleMove(e) {//取点let temX = e.changedTouches[0].xlet temY = e.changedTouches[0].y//画线条this.ctx.moveTo(this.startX, this.startY)this.ctx.lineTo(temX, temY)this.ctx.stroke()this.startX = temXthis.startY = temYthis.ctx.draw(true)},/*** 重写*/retDraw() {this.ctx.clearRect(0, 0, 700, 730)this.ctx.draw()//设置canvas背景this.setCanvasBg('#fff')},/*** @param {Object} str* @param {Object} color* 选择颜色*/selectColorEvent(str, color) {this.selectColor = strthis.lineColor = color},// 确认subCanvas() {const _this = thisuni.canvasToTempFilePath({canvasId: 'handWriting',fileType: 'png',quality: 1, //图片质量success(res) {console.log(res.tempFilePath, 'canvas生成图片地址')wx.getImageInfo({// 获取图片的信息src: res.tempFilePath,success: (res1) => {console.log(res1)// 将canvas1的内容复制到canvas2中let canvasContext = wx.createCanvasContext('handWriting2')let rate = res1.height / res1.widthlet width = 300 / ratelet height = 300_this.cavWidth = 300 / rate_this.cavWidth1 = 300canvasContext.translate(height / 2, width / 2)canvasContext.rotate((270 * Math.PI) / 180)canvasContext.drawImage(res.tempFilePath, -width / 2, -height / 2,width, height)canvasContext.draw(false, () => {// 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中wx.canvasToTempFilePath({// 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。canvasId: 'handWriting2',fileType: 'png',quality: 1, //图片质量success(res2) {let data = JSON.stringify({tempFilePath: res2.tempFilePath,})let pages = getCurrentPages();let prevPage = pages[pages.length - 2];prevPage.$vm.getTempFilePath(data)uni.navigateBack({delta: 1})}})})}})},})},//旋转图片,生成新canvas实例rotate(cb) {const that = thiswx.createSelectorQuery().select('#handWriting2').fields({node: true,size: true}).exec((res) => {const rotateCanvas = res[0].nodeconst rotateCtx = rotateCanvas.getContext('2d')//this.ctxW-->所绘制canvas的width//this.ctxH -->所绘制canvas的heightrotateCanvas.width = this.ctxHrotateCanvas.height = this.ctxWwx.canvasToTempFilePath({canvas: that.canvas,success(res) {const img = rotateCanvas.createImage()img.src = res.tempFilePathimg.onload = function() {rotateCtx.translate(rotateCanvas.width / 2,rotateCanvas.height / 2)rotateCtx.rotate((270 * Math.PI) / 180)rotateCtx.drawImage(img, -rotateCanvas.height / 2, -rotateCanvas.width / 2)rotateCtx.scale(that.pixelRatio, that.pixelRatio)cb(rotateCanvas)}},fail(err) {console.log(err)}})})},//取消saveCanvasAsImg() {this.retDraw()uni.navigateBack()},//设置canvas背景色  不设置  导出的canvas的背景为透明//@params:字符串  colorsetCanvasBg(color) {/* 将canvas背景设置为 白底,不设置  导出的canvas的背景为透明 *///rect() 参数说明  矩形路径左上角的横坐标,左上角的纵坐标, 矩形路径的宽度, 矩形路径的高度//这里是 canvasHeight - 4 是因为下边盖住边框了,所以手动减了写this.ctx.rect(0, 0, this.canvasWidth, this.canvasHeight - 4)// ctx.setFillStyle('red')this.ctx.setFillStyle(color)this.ctx.fill() //设置填充this.ctx.draw() //开画},toJSON() {}}}
</script><style>page {background: #fbfbfb;height: auto;overflow: hidden;}.wrapper {position: relative;width: 100%;height: 100vh;margin: 20rpx 0;overflow: auto;display: flex;align-content: center;flex-direction: row;justify-content: center;font-size: 28rpx;}.handWriting {background: #fff;width: 100%;height: 100vh;}.handCenter {border-left: 2rpx solid #e9e9e9;flex: 5;overflow: hidden;box-sizing: border-box;}.handBtn button {font-size: 28rpx;}.handBtn {height: 100vh;display: inline-flex;flex-direction: column;justify-content: space-between;align-content: space-between;flex: 1;}.delBtn {width: 200rpx;position: absolute;bottom: 350rpx;left: -35rpx;transform: rotate(90deg);color: #666;}.subBtn {width: 200rpx;position: absolute;bottom: 52rpx;left: -35rpx;display: inline-flex;transform: rotate(90deg);background: #29cea0;color: #fff;margin-bottom: 60rpx;text-align: center;justify-content: center;}/*Peach - 新增 - 保存*/.saveBtn {width: 200rpx;position: absolute;bottom: 590rpx;left: -35rpx;transform: rotate(90deg);color: #666;}
</style>

3. 图片进行翻转,返回翻转后的图片

在这里插入图片描述
在这里插入图片描述

相关文章:

uni-app 微信小程序 电子签名及签名图片翻转显示功能

文章目录 1. 需求背景2. 开始撸2.1 点击 重写 进入签名页面&#xff08;上图一&#xff09;2.2 书写签名&#xff0c;点击确认返回&#xff0c;及图片翻转显示&#xff08;上图二&#xff0c;三&#xff09; 3. 图片进行翻转&#xff0c;返回翻转后的图片 1. 需求背景 接的一个…...

MySQL 8.0关键字和保留字

官网地址&#xff1a; https://dev.mysql.com/doc/refman/8.0/en/keywords.html 可以粘贴出去自己排版整理 {accessible} {account} {action} {active} {add} {admin} {after} {against} {aggregate} {algorithm} {all} {alter} {always} {analyse} {analyze} …...

PyLMKit(3):基于角色扮演的应用案例

角色扮演应用案例RolePlay 0.项目信息 日期&#xff1a; 2023-12-2作者&#xff1a;小知课题: 通过设置角色模板并结合在线搜索、记忆和知识库功能&#xff0c;实现典型的对话应用功能。这个功能是大模型应用的基础功能&#xff0c;在后续其它RAG等功能中都会用到这个功能。功…...

JAVA全栈开发 集合详解(day14+day15汇总)

一、数组 数组是一个容器&#xff0c;可以存入相同类型的多个数据元素。 数组局限性&#xff1a; ​ 长度固定&#xff1a;&#xff08;添加–扩容&#xff0c; 删除-缩容&#xff09; ​ 类型是一致的 对象数组 &#xff1a; int[] arr new int[5]; … Student[] arr …...

Linux Spug自动化运维平台本地部署与公网远程访问

文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件…...

zookeeper集群和kafka集群

&#xff08;一&#xff09;kafka 1、kafka3.0之前依赖于zookeeper 2、kafka3.0之后不依赖zookeeper&#xff0c;元数据由kafka节点自己管理 &#xff08;二&#xff09;zookeeper 1、zookeeper是一个开源的、分布式的架构&#xff0c;提供协调服务&#xff08;Apache项目&…...

Java——》JSONObjet 数据顺序

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…...

【个人记录】NGINX反向代理grpc服务

最开始使用proxy_pass去代理了grpc服务&#xff0c;结果请求时候报错提示&#xff1a; rpc error: code Unavailable desc connection error: desc "error reading server preface: http2: frame too large"后来才知道代理grpc服务需要使用grpc_pass&#xff0c;…...

【小白推荐】安装OpenCV4.8 系统 Ubuntu 22.04LST Linux.

先看一下目录&#xff0c;知道大致的流程&#xff01; 文章目录 安装OpenCV安装依赖下载源码配置与构建安装 测试编写CMakeListx.txt编写测试代码 安装OpenCV 安装依赖 sudo apt update && sudo apt upgrade sudo apt install cmake ninja-build build-essential lib…...

使用Docker Compose搭建CIG监控平台

CIG简介 CIG监控平台是基于CAdvisor、InfluxDB和Granfana构建的一个容器重量级监控系统&#xff0c;用于监控容器的各项性能指标。其中&#xff0c;CAdvisor是一个容器资源监控工具&#xff0c;用于监控容器的内存、CPU、网络IO和磁盘IO等。InfluxDB是一个开源的分布式时序、时…...

前端文本省略号后面添加复制文字

前端文本省略号后面添加复制文字 1、效果图 2、代码展示 <div class"link-content-wrap" click"copyLinkText"><div class"link-content">{{ shareResult.url || }} </div><span class"show-ellipsis" click&…...

【算法】动态规划中的路径问题

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;如果给算法的难度和复杂度排一个排名&#xff0c;那么动态规划算法一定名列前茅。今天&#xff0c;我们通过由简单到困难的两道题目带大家学会动…...

代数学笔记9: 群的直积,可解群,自由群,群表示

群的直积 外直积 H 1 , H 2 H_1,H_2 H1​,H2​是两个群(固定的群), 且有 G H 1 H 2 GH_1\times H_2 GH1​H2​,(构造的新群) G ( { ( h 1 , h 2 ) ∣ h 1 ∈ H 1 , h 2 ∈ H 2 } , ⋅ ) , G\big(\{(h_1,h_2)|h_1\in H_1,h_2\in H_2\},\cdot\big), G({(h1​,h2​)∣h1​∈H…...

kali学习

目录 黑客法则&#xff1a; 一&#xff1a;页面使用基础 二&#xff1a;msf和Windows永恒之蓝漏洞 kali最强渗透工具——metasploit 介绍 使用永恒之蓝进行攻击 ​编辑 使用kali渗透工具生成远程控制木马 渗透测试——信息收集 域名信息收集 黑客法则&#xff1a; 一&…...

《论文阅读》DualGATs:用于对话中情绪识别的双图注意力网络

《论文阅读》DualGATs:用于会话中情感识别的双图注意力网络 前言摘要模型架构DisGAT图构建图关系类型图节点更新SpkGAT图构建图关系类型图节点更新交互模块情绪预测损失函数问题前言 今天为大家带来的是《DualGATs: Dual Graph Attention Networks...

【算法】单调栈题单——字典序最小⭐(一种类型的模板题)

文章目录 题目列表316. 去除重复字母⭐⭐⭐⭐⭐&#xff08;类型题模板&#xff1a;单调栈&#xff0c;字典序最小&#xff09;221021天池-03. 整理书架&#xff08;保留数量为 limit 的字典序最小&#xff09;402. 移掉 K 位数字&#xff08;最多删除 k 次 前导零的处理&…...

DockerCompose修改某个服务的配置(添加或编辑端口号映射)后如何重启单个服务使其生效

场景 docker-compose入门以及部署SpringBootVueRedisMysql(前后端分离项目)以若依前后端分离版为例&#xff1a; docker-compose入门以及部署SpringBootVueRedisMysql(前后端分离项目)以若依前后端分离版为例_docker-compose部署java mysql redis-CSDN博客 上面讲了docker c…...

DOM 事件的传播机制

前端面试大全DOM 事件的传播机制 &#x1f31f;经典真题 &#x1f31f;事件与事件流 事件流 事件冒泡流 事件捕获流 标准 DOM 事件流 &#x1f31f;事件委托 &#x1f31f;真题解答 &#x1f31f;总结 &#x1f31f;经典真题 谈一谈事件委托以及冒泡原理 &#x1f3…...

(数据结构)顺序表的查找

静态分配代码&#xff1a; #include<stdio.h> #include<stdlib.h> #define MAX 100 typedef struct LinkList {int data[MAX];int lenth; }Link; //初始化 void CreateList(Link* L) {L->lenth 0;for (int i 0; i < MAX; i){L->data[i] 0;} } //插入 …...

vue 解决响应大数据表格渲染崩溃问题

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; 1.场景描述 发起请求获取上万条数据&#xff0c;进行表格渲染&#xff0c;使浏览器卡顿&#xff0c;导致网页崩溃。 2.分析原因 1.大量数据加载&#xff0c;过多操作Dom&#xff0c;消耗性能。 2.表格中包含其他…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...