vue3项目引入电子签名(可横屏竖屏)
实现效果:(左边横屏,右边竖屏)


前言:【使用开源项目smooth-signature 实现签名的功能。Gitee 地址是 :GitHub - linjc/smooth-signature: H5带笔锋手写签名,支持PC端和移动端,任何前端框架均可使用
以下代码可复制粘贴直接用,改下文件路径即可】
1.在项目中安装依赖包:npm install --save smooth-signature
2.我是放到一个dialog里,可根据需求自行开发。
弹框代码:
<!--签名--><Dialogv-model="signatureVisible"title="电子签名"width="100%"destroy-on-closedraggable:append-to-body="true"@close="handleClose"><div v-loading="endLoading"><ESign @closeson="closeVisi" /></div><button v-show="false" @click="closeVisi">关闭</button></Dialog>
引入模块:
import ESign from '@/views/officeDocument/office/components/packages/ESign/src/index2.vue'
使用方法:
//电子签名
const signatureVisible = ref(false)
const signatureBtn = () => {signatureVisible.value = true
}
//子组件关闭调用此方法
const closeVisi = () => {signatureVisible.value = false
}
2.开发电子签名功能及样式
电子签名文件目录(src/index.vue省略,主要是index2.vue文件):
packages/index.ts文件代码:
import { App, Plugin } from 'vue'import { ESignPlugin } from './ESign'
const XiPlugin: Plugin = {install(app: App) {ESignPlugin.install?.(app)}
}export default XiPluginexport * from './ESign'
packages/Esign/index.ts文件代码:
import { App, Plugin } from 'vue'
import ESign from './src/index.vue'export const ESignPlugin: Plugin = {install(app: App) {app.component('ESign', ESign)}
}export { ESign }
packages/Edign/src/index2.vue文件代码(主要代码):
<template><div class="sign-finish"><div class="wrap1" v-show="showFull"><span class="sign-title">请在区域内签字</span><canvas class="canvas1" ref="canvas1"></canvas><div class="actions"><button class="danger" @click="handleClear1">清除</button><button class="warning" @click="handleUndo1">撤销</button><button class="primary" @click="handleFull">横屏</button><button class="success" @click="handlePreview1">保存</button></div></div><div class="wrap2" v-show="!showFull"><div class="actionsWrap"><div class="actions"><button class="danger" @click="handleClear2">清除</button><button class="warning" @click="handleUndo2">撤销</button><button class="primary" @click="handleFull">竖屏</button><button class="success" @click="handlePreview2">保存</button></div></div><canvas class="canvas" ref="canvas2"></canvas></div></div>
</template><script lang="ts" setup>
import { emit } from 'process'
import { ref, watch, onMounted, onUnmounted } from 'vue'
import SmoothSignature from 'smooth-signature'//组件电子签名
const canvas = document.querySelector('canvas')
// const signature = new SmoothSignature(canvas)
const showFull = ref(true)
const canvas2 = ref<any>(null)
const canvas1 = ref<any>(null)
const signature1 = ref<any>(null)
const signature2 = ref<any>(null)
const emit = defineEmits(['closeson'])//坚屏横屏
const handleFull = () => {showFull.value = !showFull.value
}
const initSignature1 = () => {// const canvas = this.$refs["canvas1"]const canvas = canvas1.value as anyconst options = {width: window.innerWidth - 30,height: 200,minWidth: 2,maxWidth: 6,openSmooth: true,// color: "#1890ff",bgColor: '#f6f6f6'}signature1.value = new SmoothSignature(canvas, options)
}
const initSignture2 = () => {// const canvas = this.$refs["canvas2"]const canvas = canvas2.value as anyconst options = {width: window.innerWidth - 120,height: window.innerHeight - 80,minWidth: 3,maxWidth: 10,openSmooth: true,// color: "#1890ff",bgColor: '#f6f6f6'}signature2.value = new SmoothSignature(canvas, options)
}const handleClear1 = () => {const sgn = signature1.valuesgn.clear()
}
const handleClear2 = () => {const sgn2 = signature2.valuesgn2.clear()
}
const handleUndo1 = () => {const sgn = signature1.valuesgn.undo()
}
const handleUndo2 = () => {const sgn2 = signature2.valuesgn2.undo()
}
const handlePreview1 = () => {const sgn = signature1.valueconst isEmpty = sgn.isEmpty()if (isEmpty) {alert('isEmpty')return}// const pngUrl = sgn.getPNG()const pngUrl = sgn.getJPG()console.log(pngUrl)emit('closeson')// window.previewImage(pngUrl);
}
const handlePreview2 = () => {const sgn2 = signature2.valueconst isEmpty = sgn2.isEmpty()if (isEmpty) {alert('isEmpty')return}const canvas = sgn2.getRotateCanvas(-90)const pngUrl = canvas.toDataURL()console.log('pngUrl', pngUrl)// 生成JPG//signature.getJPG() // 或者 signature.toDataURL('image/jpeg')
}onMounted(() => {initSignature1()initSignture2()
})// onUnmounted(() => {
// removeEventListener()
// })
</script><style scoped lang="less">
.sign-finish {height: 100vh;width: 100vw;button {height: 32px;padding: 0 8px;font-size: 12px;border-radius: 2px;}.danger {color: #fff;background: #ee0a24;border: 1px solid #ee0a24;}.warning {color: #fff;background: #ff976a;border: 1px solid #ff976a;}.primary {color: #fff;background: #1989fa;border: 1px solid #1989fa;}.success {color: #fff;background: #07c160;border: 1px solid #07c160;}canvas {border-radius: 10px;border: 2px dashed #ccc;}.wrap1 {height: 100%;width: 96%;margin: auto;margin-top: 100px;.actions {display: flex;justify-content: space-around;}}.wrap2 {padding: 15px;height: 100%;display: flex;justify-content: center;.actionsWrap {width: 50px;display: flex;justify-content: center;align-items: center;}.canvas {flex: 1;}.actions {margin-right: 10px;white-space: nowrap;transform: rotate(90deg);button {margin-right: 20px;}}}
}
</style>
最后就实现啦!本人因项目 使用比较复杂,可根据个人情况减少代码。参考前面的开源项目地址即可。
相关文章:
vue3项目引入电子签名(可横屏竖屏)
实现效果:(左边横屏,右边竖屏) 前言:【使用开源项目smooth-signature 实现签名的功能。Gitee 地址是 :GitHub - linjc/smooth-signature: H5带笔锋手写签名,支持PC端和移动端,任何前…...
mysql中count(*)、count(1)、count(主键)、count(字段)的区别
文章目录 count函数的语义count(主键)count(1)count(*)count(字段)替代方案explain或者show table status中间表或者其他数据库计数 以下分析都是基于 select count(?) from table 这个语句来分析,不带过滤条件。 count函数的语义 count() 是一个聚合函数&#x…...
Nginx生成自签名证书从而添加域名的HTTPS访问
数字证书 ## 原理参考 https://mysticaldream.github.io/2023/05/certificate/## https://blog.csdn.net/m0_52440465/article/details/130713591 简介 数字证书是由证书颁发机构(CA)签名并颁发的电子文件,用于建立网络连接的身份认证和加密通信。SSL 证书是数字证书的一种。…...
无框架Java转go语言写http与tcp请求
项目地址 https://github.com/cmdch2017/http_tcpServer 项目结构 如何快速上手 http篇 1、controller包就相当于RestController,这里返回了一个Person对象,当你需要新建一个接口时,再新写一个func仿照下面的方法就行了 package control…...
【Git】Git基本操作
文章目录 Git 是什么Git 的优点Git 安装Linux UbuntuLinux CentOsWindows Git 基本操作1. 创建 Git 本地仓库2. 配置 Git3. Git工作区、暂存区和版本库4. 添加文件5. 查看 .git 文件6. 修改文件7. 版本回退 Git 是什么 Git是一个免费的、开源的分布式版本控制系统,…...
JavaSE学习笔记 Day20
JavaSE学习笔记 Day20 个人整理非商业用途,欢迎探讨与指正!! 上一篇 文章目录 JavaSE学习笔记 Day20十七、数据结构与算法17.1算法17.1.1冒泡排序17.1.2选择排序17.1.3插入排序17.1.4三个排序的区别 17.2顺序表17.2.1顺序表代码实现17.2.2顺…...
【蓝桥杯选拔赛真题52】python空调模式 第十四届青少年组蓝桥杯python 选拔赛比赛真题解析
目录 python空调模式 一、题目要求 1、编程实现 2、输入输出...
Android Studio: 解决Gradle sync failed 错误
文章目录 1. 前言2. 错误情况3. 解决办法3.1 获取gradle下载地址3.2 获取gradle存放目录3.3 替换并删除临时文件3.4 触发Try Again 4. 执行成功 1. 前言 今天调试项目,发现新装的AS,在下载gradle的过程中,一直显示连接失败,Gradl…...
【手写数据库】从零开始手写数据库内核,行列混合存储模型,学习大纲成型了
目录 专栏内容: 参天引擎内核架构 本专栏一起来聊聊参天引擎内核架构,以及如何实现多机的数据库节点的多读多写,与传统主备,MPP的区别,技术难点的分析,数据元数据同步,多主节点的情况下对故障容灾的支持。 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以…...
机器学习中的一些经典理论定理
PAC学习理论 当使用机器学习方法来解决某个特定问题时,通常靠经验或者多次试验来选择合适的模型、训练样本数量以及学习算法收敛的速度等。但是经验判断或多次试验往往成本比较高,也不太可靠,因此希望有一套理论能够分析问题难度、计算模型能…...
c语言:成本100元,40%的利润怎么计算|练习题
一、利润的计算公式: 利润售价-成本 售价成本/(1-利润率) 二、用c语言代码表示为: 如图: 三、计算源代码【带注释】 #include <stdio.h> int main() { float cost;//成本变量 int prof_rate;//利润率变量 float price;//…...
【Python必做100题】之第二十二题(复制列表)
题目:将一个列表的数据复制到另一个列表中 重点:确保复制到位要导入copy方法进行深度复制 代码如下: #将一个列表的数据复制到另一个列表中 import copy list [1,2,3,4] print(list) list1 copy.copy(list) list[0] 30 print(list) pri…...
Java 数据结构篇-实现堆的核心方法与堆的应用(实现 TOP-K 问题:最小 k 个数)
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 堆的说明 2.0 堆的成员变量及其构造方法 3.0 实现堆的核心方法 3.1 实现堆的核心方法 - 获取堆顶元素 peek() 3.2 实现堆的核心方法 - 下潜 down(int i) 3.3 实…...
startUML6.0.1破解方法
startUML6.0.1破解方法 文章目录 startUML6.0.1破解方法1.startUML6.0.1快速破解2.概述3.安装Nodejs4.安装asar5.修改app.asar中的源码6.将修改后的源码重新压缩7.覆盖官方的asar文件8.重启startUML9.参考文档 1.startUML6.0.1快速破解 后绪步骤可以不看,直接下载我…...
Python实现多种图像分割方法:基于阈值分割和基于区域分割
Python实现多种图像分割方法:基于阈值分割和基于区域分割 图像分割是图像分析的第一步,是计算机视觉的基础,但也是图像处理中最困难的问题之一。经典的计算机视觉任务,如目标检测、图像识别等都和图像分割相关,图像分…...
SQL学习笔记+MySQL+SQLyog工具教程
文章目录 1、前言2、SQL基本语言及其操作2.1、CREATE TABLE – 创建表2.2、DROP TABLE – 删除表2.3、INSERT – 插入数据2.4、SELECT – 查询数据2.5、SELECTDISTINCT – 去除重复值后查询数据2.6、SELECTWHERE – 条件过滤2.7、AND & OR – 运算符2.8、ORDER BY – 排序2…...
SpringBoot的日志管理
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…...
leetcode---76. 最小覆盖子串 [C++/滑动窗口+哈希表]
原题:76. 最小覆盖子串 - 力扣(LeetCode) 题目解析: 此题在这道题的基础上进行理解会更简单 leetcode --- 30. 串联所有单词的子串[C 滑动窗口/双指针]-CSDN博客 本题要求在s字符串中找到含有t字符串所有字符的最短子串。 也就是…...
Kafka 分级存储在腾讯云的实践与演进
导语 腾讯云消息队列 Kafka 内核负责人鲁仕林为大家带来了《Kafka 分级存储在腾讯云的实践与演进》的精彩分享,从 Kafka 架构遇到的问题与挑战、Kafka 弹性架构方案类比、Kafka 分级存储架构及原理以及腾讯云的落地与实践四个方面详细分享了 Kafka 分级存储在腾讯云…...
域架构下的功能安全思考
来源:联合电子 随着整车电子电气架构的发展,功能域控架构向整车集中式区域控制演进。新的区域控制架构下,车身控制模块(BCM),整车控制单元(VCU),热管理系统(TMS)和动力底…...
零基础入门:5分钟学会用Ollama运行Granite-4.0-H-350M文本生成
零基础入门:5分钟学会用Ollama运行Granite-4.0-H-350M文本生成 1. 为什么选择Granite-4.0-H-350M Granite-4.0-H-350M是一个轻量级但功能强大的文本生成模型,特别适合初学者和资源有限的用户。它只有3.5亿参数,却能在普通电脑上流畅运行&am…...
05-OpenClaw 自动生成 PPT 实战:每天节省 3 小时
作者:程序员小明儿 字数:约 9000 字 阅读时间:约 25 分钟 难度:⭐⭐⭐ 中级 系列:OpenClaw 实战 16 例(第 5 篇) 前置条件:已完成 OpenClaw 环境部署和基础配置写在前面 你是不是也这…...
10X探头隐藏技能:除了衰减信号,它如何用补偿电容拯救你的高频测量?
10X探头的高频测量奥秘:补偿电容如何成为信号保真的关键 在电子测量领域,示波器探头是工程师们不可或缺的工具,而10X探头凭借其独特的设计在高频测量中展现出无可替代的优势。本文将深入探讨10X探头内部补偿电容的工作原理,揭示它…...
别再手动校正了!用Landsat 9 L2SP地表反射率数据,在QGIS里5分钟搞定NDVI和水体提取
遥感分析效率革命:用Landsat 9 L2SP数据在QGIS中实现5分钟精准制图 当遥感数据处理流程从传统数小时缩短至五分钟,这意味着什么?去年在亚马逊雨林监测项目中,我们团队曾因大气校正步骤延误错过了最佳干预时机。如今Landsat 9 L2SP…...
保姆级教程:用Docker Compose一键部署带汉化和HTTPS的n8n,并配置反向代理(Nginx)
企业级n8n自动化平台全栈部署实战:从容器编排到安全加固 在数字化转型浪潮中,自动化工作流平台已成为企业降本增效的核心基础设施。n8n作为GitHub上增长最快的开源自动化工具之一,凭借其可视化编排能力和400节点生态,正在重塑企业…...
PWM技术原理与电机调速应用详解
PWM技术原理与电机调速应用详解1. PWM基础概念解析1.1 脉冲宽度调制定义PWM(Pulse Width Modulation)即脉冲宽度调制,是一种通过调节脉冲信号的宽度(占空比)来实现能量控制的电子电力技术。该技术在直流电机调速、开关电源、逆变器等电力电子领域有广泛应用。1.2 脉…...
NXP S32K3xx之HSE密钥管理与安全服务实战
1. HSE密钥管理基础:从零开始理解安全引擎 第一次接触NXP S32K3xx的HSE模块时,我被各种密钥术语搞得晕头转向。经过几个实际项目的打磨,现在我可以负责任地告诉你:理解HSE密钥管理就像学习一门新语言,掌握基础词汇后就…...
从拼图游戏到自动驾驶:点云配准技术的跨领域进化史
从拼图游戏到自动驾驶:点云配准技术的跨领域进化史 1. 三维世界的数字拼图师 1987年,当Paul Besl和Neil McKay在实验室里尝试将两组扫描数据对齐时,他们可能不会想到,这项被称为迭代最近点(ICP)的技术会成为…...
5分钟搞定三网话费余额查询:手把手教你用PHP+HTML搭建查询系统(含API调用避坑指南)
三网话费查询系统开发实战:从API调用到前端优化的全流程指南 最近在帮朋友开发一个小型话费查询工具时,发现市面上关于三网运营商API调用的完整教程并不多见。大多数开发者遇到问题时只能靠反复试错,特别是当需要同时对接移动、联通、电信三家…...
WebPlotDigitizer图表数据提取工具:科研工作者的终极数字化解决方案
WebPlotDigitizer图表数据提取工具:科研工作者的终极数字化解决方案 【免费下载链接】WebPlotDigitizer WebPlotDigitizer: 一个基于 Web 的工具,用于从图形图像中提取数值数据,支持 XY、极地、三角图和地图。 项目地址: https://gitcode.c…...
