uniapp,使用canvas制作一个签名版
先看效果图
我把这个做成了页面,没有做成组件,因为之前我是配合uview-plus的popup弹出层使用的,这种组件好像是没有生命周期的,第一次打开弹出层可以正常写字,但是关闭之后再打开就不会显示绘制的线条了,还需要重新加载组件的父页面才可以重新写字,所以我又做成了页面,功能就正常了。
代码实现:
<template><view class="page"><canvas class="mycanvas" canvas-id="mycanvas" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"></canvas><view class="button-group"><button class="one" @click="clear">清空</button><button class="two" @click="finish">确定</button></view></view>
</template><script setup>
import { reactive,onMounted } from "vue";
import {onReachBottom,onShow,onLoad,onReady,onHide} from '@dcloudio/uni-app';import http from '@/common/http.js'import store from '@/store/index.js'import { pathToBase64, base64ToPath } from 'image-tools'let state = store()let props=defineProps({})let emits = defineEmits()let data=reactive({ctx:null, //绘图图像points:[],//路径点集合path:'',flag:false,})onShow(()=>{data.ctx = uni.createCanvasContext("mycanvas",this); //创建绘图对象//设置画笔样式data.ctx.lineWidth = 4;data.ctx.lineCap = "round"data.ctx.lineJoin = "round"data.flag=false}) //触摸开始,获取到起点function touchstart(e){let startX = e.changedTouches[0].x;let startY = e.changedTouches[0].y;let startPoint = {X:startX,Y:startY};/* **************************************************#由于uni对canvas的实现有所不同,这里需要把起点存起来* **************************************************/data.points.push(startPoint);//每次触摸开始,开启新的路径data.ctx.beginPath();}//触摸移动,获取到路径点function touchmove(e){let moveX = e.changedTouches[0].x;let moveY = e.changedTouches[0].y;let movePoint = {X:moveX,Y:moveY};data.points.push(movePoint);//存点let len = data.points.length;if(len>=2){draw();//绘制路径}}// 触摸结束,将未绘制的点清空防止对后续路径产生干扰function touchend(){ data.points=[];}/* ***********************************************# 绘制笔迹# 1.为保证笔迹实时显示,必须在移动的同时绘制笔迹# 2.为保证笔迹连续,每次从路径集合中区两个点作为起点(moveTo)和终点(lineTo)# 3.将上一次的终点作为下一次绘制的起点(即清除第一个点)************************************************ */function draw() {let point1 = data.points[0]let point2 = data.points[1]data.points.shift()data.ctx.moveTo(point1.X, point1.Y)data.ctx.lineTo(point2.X, point2.Y)data.ctx.stroke()data.ctx.draw(true)data.flag=true}//清空画布function clear(){uni.getSystemInfo({success: function(res) {let canvasw = res.windowWidth;let canvash = res.windowHeight;data.ctx.clearRect(0, 0, canvasw, canvash);data.ctx.draw(false);data.flag=false}})}//完成绘画并保存到本地function finish(){if(!data.flag){http.hint('请签名!')return}// 此API,H5中返回的是base64,APP中返回的是png图片,一个临时路径uni.canvasToTempFilePath({canvasId: 'mycanvas',success: function(res) {let path = res.tempFilePath;// 因为我是在APP在,所以需要base64,在这里用image-tools插件把png转为base64pathToBase64(path).then(res=>{// 因为之前后端要svg字符串,但是png直接转svg转不了,所以先转为base64,然后在转svg
// let svg=`<?xml version="1.0" standalone="no"?>
// <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
// <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body_1" width="100%" height="500">// <g transform="matrix(1.3333334 0 0 1.3333334 0 0)">
// <image x="0" y="0" xlink:href="${res}" preserveAspectRatio="none" width="100%" height="500" /></g>
// </svg>` state.svgPath=res// emits('confirm',true)uni.navigateBack({delta:1})}).catch(err=>{console.log('err :>> ', err);})}})}
</script><style scoped lang="less">
.page{overflow: hidden;
}.button-group{position: fixed;left: 50rpx;bottom: 10rpx;display: flex;align-items: center;// justify-content: space-between;// height: 200rpx;.one{width: 200rpx;margin-right: 50rpx;border: 1px solid #123454;}.two{width: 400rpx;background-color: #123454;color: #fff;}}.title{height:50upx;line-height: 50upx;font-size: 16px;}.mycanvas{width: 100%;height: calc(100vh - 200upx);background-color: #ECECEC;}.footer{font-size: 16px;height: 150upx;display: flex;justify-content: space-around;align-items: center;}.left,.right{line-height: 100upx;height: 100upx;width: 250upx;text-align: center;font-weight: bold;color: white;border-radius: 5upx;}.left{background: #007AFF;}.right{background:orange;}
</style>
在H5中,点击确定后输出为base64,在APP中输出为临时路径的png图片,我是在APP中使用,所以还需要把png图片转为base64,格式按后端要求,如果只需要传图片就不需要转base64了,也可以转svg,转svg的我注释掉了,用到的图片转换插件为image-tools。
如果大家在使用过程中发现了什么问题,欢迎在评论区指正,谢谢观看!
相关文章:
uniapp,使用canvas制作一个签名版
先看效果图 我把这个做成了页面,没有做成组件,因为之前我是配合uview-plus的popup弹出层使用的,这种组件好像是没有生命周期的,第一次打开弹出层可以正常写字,但是关闭之后再打开就不会显示绘制的线条了,还…...
【大数据】Flink 详解(五):核心篇 Ⅳ
Flink 详解(五):核心篇 Ⅳ 45、Flink 广播机制了解吗? 从图中可以理解 广播 就是一个公共的共享变量,广播变量存于 TaskManager 的内存中,所以广播变量不应该太大,将一个数据集广播后࿰…...
设计模式-建造者模式
核心思想 抽取共同的行为,允许使用者指定复杂对象的类型和内容,不需要了解内部的构建细节使用多个简单的行为构建一个复杂的对象,将对象的构建过程和它的表示分离,同样的构建过程可以创建不同的表示 优缺点 优点 使用者不需要知…...
flutter 设置app图标
使用插件 flutter_launcher_icons 在 pubspec.yaml 配置文件中 加入 dev_dependencies dev_dependencies: flutter_launcher_icons: "^0.13.1" 准备好app得 icon 图标 其中icon的名字为icon.png 创建assets文件夹 和子文件夹icon iamge 配置静态资源路径 完整配置…...
守护网络安全:深入了解DDOS攻击防护手段
ddos攻击防护手段有哪些?在数字化快速发展的时代,网络安全问题日益凸显,其中分布式拒绝服务(DDOS)攻击尤为引人关注。这种攻击通过向目标网站或服务器发送大量合法或非法的请求,旨在使目标资源无法正常处理其他用户的请求,从而达…...
计组 | 寻址方式
目录 一、知识点 1.寻址方式什么? 2.根据操作数所在的位置,都有哪些寻址方式? 3.直接寻址 4.立即寻址 5.隐含寻址 6.相对寻址 7.寄存器 8.寄存器-寄存器型(RR)、寄存器-存储器型(RS)和…...
matlab工具箱Filter Designer设计butterworth带通滤波器
1、在matlab控制界面输入fdatool; 2、在显示的界面中选择合适的参数;本实验中采样频率是200,低通30hz,高通60hz,点击butterworth滤波器。 3、点击设计滤波器按钮后,在生成的界面点击红框按钮,可生成simulink模型到当前…...
Python学习笔记第六十天(Matplotlib Pyplot)
Python学习笔记第六十天 Matplotlib Pyplot后记 Matplotlib Pyplot Pyplot 是 Matplotlib 的子库,提供了和 MATLAB 类似的绘图 API。 Pyplot 是常用的绘图模块,能很方便让用户绘制 2D 图表。 Pyplot 包含一系列绘图函数的相关函数,每个函数…...
服务器自动备份、打包、传输脚本
备份脚本 #!/bin/bash #author cheng #备份服务器自动打包归档每天的备份文件 Path/backhistory Host$(hostname) Date$(date %F) Dest${Host}_${Date}#创建目录 mkdir -p ${Path}/${Dest}#打包文件到目录 cd / && \#结合autoback.sh脚本,它往那个地方备&a…...
Docker 的数据管理 网络通信
目录 1.管理容器数据的方式 数据卷 数据卷的容器 2.操作命令 3.Docker 镜像的创建 1.管理容器数据的方式 数据卷 可以独立于容器生命周期存储的机制 可提供持久化 数据共享 docker run -v /var/www:/data1 --name web1 -it centos:7 /bin/bash 数据卷的容器 用来提供持久化数…...
目标检测YOLO实战应用案例100讲-基于孤立森林算法的高光谱遥感图像异常目标检测
目录 前言 孤立森林算法的基本理论 2.1 引言 2.2 孤立森林算法的基本思想...
excel中两列数据生成折线图
WPS中excel的两列数据,第一列为x轴,第二列为y轴,生成折线图,并生成拟合函数。 1.选中两列数据,右击选择插入图表,选择XY(散点图),生成散点折线图 2.选中图中散点&#x…...
JS加密的域名锁定功能,JShaman支持泛域名
JShaman的域名锁定功能,支持泛域名 JShaman的JS代码混淆加密中,有一项“域名锁定”功能。使用此功能后,代码运行时会检测浏览器地址中的域名信息,如是非指定域名,则不运行,以此防止自己网站的JS代码被复制…...
概率论与数理统计:第七章:参数估计 第八章:假设检验
文章目录 Ch7. 参数估计7.1 点估计1.矩估计2.最大似然估计(1)离散型(2)连续型 7.2 评价估计量优良性的标准(1)无偏性 (无偏估计)(2)有效性(3)一致性 7.3 区间估计1.置信区间、置信度2.求μ的置信区间 Ch8. 假设检验1.拒绝域α、接受域1-α、H₀原假设、H₁备择假设2.双边检验、…...
【Kubernetes】Kubernetes的监控工具Promethues
Prometheus 一、Prometheus 概念1. Prometheus 概述2. Prometheus 的监控数据3. Prometheus 的特点4. Prometheus 和 zabbix 区别5. Prometheus 的生态组件5.1 Prometheus server5.2 Client Library5.3 Exporters5.4 Service Discovery5.5 Alertmanager5.6 Pushgateway5.7 Graf…...
【linux】2 Linux编译器-gcc/g++和Linux调试器-gdb
文章目录 一、Linux编译器-gcc/g使用1.1 背景知识1.2 gcc如何完成1.3 函数库1.4 gcc选项 二、linux调试器-gdb使用2.1 背景2.2 开始使用 总结 ヾ(๑╹◡╹)ノ" 人总要为过去的懒惰而付出代价ヾ(๑╹◡╹)ノ" 一、Linux编译器-gcc/g使用 1.1 背景…...
【力扣每日一题】2023.8.17 切披萨的方案数
目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一个二维数组来表示一个披萨,其中‘A’表示披萨上的苹果。 让我们切k-1刀,把披萨切成 k 份࿰…...
Linux调试器-gdb使用
1. 背景 程序的发布方式有两种, debug 模式和 release 模式 Linux gcc/g 出来的二进制程序,默认是 release 模式 要使用 gdb 调试,必须在源代码生成二进制程序的时候 , 加上 - g 选项 2. 开始使用 gdb binFile 退出: ct…...
linux安装mysql错误处理
linux下mysql的安装与使用 linux安装mysql可有三种方式: 1、yum安装 2、源码安装 3、glibc安装 安装wget yum install -y wget https://blog.csdn.net/darendu/article/details/89874564?utm_sourceapp Linux上error while loading shared libraries问题解决方法…...
Matlab绘制灰度直方图
直方图是根据灰图像绘制的,而不是彩色图像通。查看图像直方图时候,需要先确定图片是否为灰度图,使用MATLAB2019查看图片是否是灰度图片,在读取图片后在MATLAB界面的工作区会显示读取的图像矩阵,如果是,那么…...
http学习笔记1
图解HTTP学习笔记 1.2 HTTP的诞生 CERN(欧洲核子研究组织)的蒂姆 • 伯纳斯 - 李(Tim BernersLee)博士提出了一种能让远隔两地的研究者们共享知识的设想。最初设想的基本理念是:借助多文档之间相互关联形成的超文本&am…...
PDF文件分割合并
PDF文件的分割和合并代码。 from PyPDF2 import PdfFileReader,PdfFileWriterdef pdf_split(filename,outputname)pr PdfFileReader(filename)for page in range(p.getNumPages()):pw PdfFileWriter()pw.addPage(pr.getPage(page))with open(f{outputname}{page}.pdf,wb) as…...
物联网无线通信方式总结
本文主要内容(一些物联网无线通信方式) 本文将介绍一些物联网无线通信方式的技术特点、底层调制方式和主要应用场景物联网无线通信方式是指利用无线技术实现物体之间的信息交换和网络连接的方式物联网无线通信方式的选择需要考虑多种因素,如传输距离、功耗、数据速…...
计算机竞赛 python的搜索引擎系统设计与实现
0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 python的搜索引擎系统设计与实现 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:5分创新点:3分 该项目较为新颖ÿ…...
ue5 场景搭建和灯光照明参考
https://www.youtube.com/watch?vOCgn40aWVuU https://www.youtube.com/watch?vIGLujClhL5U...
Mycat跨分片Join指南
前言Mycat目前版本支持跨分片的join,主要实现的方式有四种。 全局表 ER分片 HBT ShareJoin ShareJoin在开发版中支持,前面三种方式1.3.0.1支持 2.ShareJoin ShareJoin是一个简单的跨分片Join,基于HBT的方式实现。 目前支持2个表的join,原理就是解析SQL语句,拆分成单表的…...
网络:RIP协议
1. RIP协议原理介绍 RIP是一种比较简单的内部网关协议(IGP协议),RIP基于距离矢量的贝尔曼-福特算法(Bellman - Ford)来计算到达目的网络的最佳路径。最初的RIP协议开发时间较早,所以在带宽、配置和管理方面的要求也较低。 路由器运…...
如何优化因为高亮造成的大文本(大字段)检索缓慢问题
首先还是说一下背景,工作中用到了 elasticsearch 的检索以及高亮展示,但是索引中的content字段是读取的大文本内容,所以后果就是索引的单个字段很大,造成单独检索请求的时候速度还可以,但是加入高亮之后检索请求的耗时…...
HTML <table> 标签
实例 一个简单的 HTML 表格,包含两行两列: <table border="1"><tr><th>Month</th><th>Savings</th></tr><tr><td>January</td><td>$100</td></tr> </table>定义和用法 &l…...
ubuntu pdf阅读器okular
sudo apt-get install okular安装完毕后,使用如下命令浏览pdf文档 okular xxx.pdf...
杰奇网站地图怎么做/百度外推排名
下面是两个Widget: 蓝图: 这里一定要是这个才正常,我找了一天的原因。 4.12 时,设为Visible也是正常的,4.13要是使用了WidgetInteration,就一定这样才行。 切记切记。...
天津公司网站制作公司/百度竞价推广有哪些优势
原因: CBCentralManager 实例是局部变量,初始化完成之后没有被当前创建它的类所持有 参考博客: [CoreBluetooth] XPC connection invalid...
网站开发人员绩效如何计算/外贸接单平台网站
Webx入口点:(webx2:WebxControllerServlet, webx3:WebxFrameworkFilter) 1、wex3分析 webx3采用了和spring相同的设计思路,在创建bean的时候,存在factory bean的概念,不过换了名字为ToolFactory 其中涉及2个方法,分别是…...
网站开发的认知/广告媒体资源平台
VIM 是从VI发展出来的一个文本编辑器,在类Unix系统中成为了用户最喜欢的文本编辑器,VIM 是依靠于ASCII的纯文本文件。 在Windows当中我们接触最多的是字处理器,类似于word。 由于Vim在Linux中经常使用,且功能强大,想要…...
怎样让网站的排名靠前/宁波公司做网站
今天先说个题外话 就现在科学的年代 大家已经不太谈所谓的命了 就命运的那个命 而UP主呢 现在其实主要是讲程序相关的东西 这些东西 其实是UP主很久以前喜欢研究的东西 那今天说个题外话拿来讲一讲 就命如果我们从科学的角度看 你看它是个什么东西 也就是说命中注定 也就是说一…...
数控技术是学什么/seo自学网app
作者:维吉特伯链接:https://www.zhihu.com/question/49812013/answer/148825073来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。简单地说,根据链式法则,如果每一层神经元对…...