移动端签名组件封装 借用插件 vue-esign

目录

  • 需求
  • 实现讲解
  • 工具 - 图片旋转、base64 转换为 file 对象
  • 组件封装
  • 组件全局注册
  • 组件使用
    • 效果展示

需求

移动端需要实现手机横屏手写签名并上传签名图片功能。

实现讲解

vue-esign 插件文档地址 https://www.npmjs.com/package/vue-esign
SignCanvas 组件封装原理:

  1. 页面分为左右两部分:左-按钮区域,右-签名区域
  2. 按钮区域:将按钮进行旋转,视觉上制造手机横屏的效果
  3. 签名区域:由于是横屏签名,所以在签名结束提交签名时需要将签名图片进行逆时针90°旋转

工具 - 图片旋转、base64 转换为 file 对象

@/utils/index

/*** 图片旋转*/
export function rotateBase64Img(src, edg, fileName, fileType, callback) {var canvas = document.createElement('canvas')var ctx = canvas.getContext('2d')var imgW // 图片宽度var imgH // 图片高度var size // canvas初始大小if (edg % 90 !== 0) {console.error('旋转角度必须是90的倍数!')return '旋转角度必须是90的倍数!'}edg < 0 && (edg = (edg % 360) + 360)const quadrant = (edg / 90) % 4 // 旋转象限const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 } // 裁剪坐标var image = new Image()image.crossOrigin = 'Anonymous'image.src = srcimage.onload = () => {imgW = image.widthimgH = image.heightsize = imgW > imgH ? imgW : imgHcanvas.width = size * 2canvas.height = size * 2switch (quadrant) {case 0:cutCoor.sx = sizecutCoor.sy = sizecutCoor.ex = size + imgWcutCoor.ey = size + imgHbreakcase 1:cutCoor.sx = size - imgHcutCoor.sy = sizecutCoor.ex = sizecutCoor.ey = size + imgWbreakcase 2:cutCoor.sx = size - imgWcutCoor.sy = size - imgHcutCoor.ex = sizecutCoor.ey = sizebreakcase 3:cutCoor.sx = sizecutCoor.sy = size - imgWcutCoor.ex = size + imgHcutCoor.ey = size + imgWbreak}ctx.translate(size, size)ctx.rotate((edg * Math.PI) / 180)ctx.drawImage(image, 0, 0)var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey)if (quadrant % 2 === 0) {canvas.width = imgWcanvas.height = imgH} else {canvas.width = imgHcanvas.height = imgW}ctx.putImageData(imgData, 0, 0)callback(dataURLtoFile(canvas.toDataURL(), fileName, fileType))// callback(canvas.toDataURL())}
}
/*** 将 base64 转换为 file 对象*    dataURL:base64 格式*    fileName:文件名*    fileType:文件格式*/
export function dataURLtoFile(dataURL, fileName, fileType) {const arr = dataURL.split(',')const mime = arr[0].match(/:(.*?);/)[1]const bstr = atob(arr[1])let n = bstr.lengthconst u8arr = new Uint8Array(n)while (n--) {u8arr[n] = bstr.charCodeAt(n)}return new File([u8arr], fileName, { type: fileType || 'image/jpg' })
}

组件封装

@/components/SignCanvas.vue

<!-- 签名组件 -->
<template><div class="signContainer"><div class="btns"><van-button type="default" round @click="resetHandler" class="reset">重签</van-button><van-button type="info" round @click="sureHandler">确认</van-button></div><vue-esignref="VueEsignRef"class="vue-esign":width="width":height="height":lineWidth="lineWidth":lineColor="lineColor":bgColor="bgColor":isCrop="isCrop":isClearBgColor="isClearBgColor":format="format":quality="quality"/><div :style="{ '--width': height + 'px' }" class="tipText"><span v-if="signName">{{ ` ${signName} ` }}</span>在此区域内签名</div></div>
</template><script>
import { rotateBase64Img } from '@/utils/index'export default {name: 'SignCanvas',components: {},props: {// 画布宽度,即导出图片的宽度width: {type: Number,default: () => {const dom = document.querySelector('#app')const width = dom && dom.offsetWidthreturn width ? width - 60 : 300 // 减去按钮区域的宽度}},// 画布高度,即导出图片的高度height: {type: Number,default: () => {const dom = document.querySelector('#app')return (dom && dom.offsetHeight) || 800}},// 画笔粗细lineWidth: {type: Number,default: 6},// 画笔颜色lineColor: {type: String,default: '#000'},// 画布背景色,为空时画布背景透明,支持多种格式 '#ccc','#E5A1A1','rgb(229, 161, 161)','rgba(0,0,0,.6)','red'bgColor: {type: String,default: ''},// 是否裁剪,在画布设定尺寸基础上裁掉四周空白部分isCrop: {type: Boolean,default: false},// 清空画布时(reset)是否同时清空设置的背景色(bgColor)isClearBgColor: {type: Boolean,default: true},// 生成图片格式 image/jpeg(jpg格式下生成的图片透明背景会变黑色请慎用或指定背景色)、 image/webpformat: {type: String,default: 'image/png'},// 生成图片质量;在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。quality: {type: Number,default: 1},// 未签名时提示信息noSignTipText: {type: String,default: '请确保已签名!'},// 需要签名的姓名signName: {type: String,default: ''}},methods: {resetHandler() {this.$refs.VueEsignRef.reset() // 清空画布},sureHandler() {// 可选配置参数 ,在未设置format或quality属性时可在生成图片时配置 例如: {format:'image/jpeg', quality: 0.5}// this.$refs.esign.generate({format:'image/jpeg', quality: 0.5})this.$refs.VueEsignRef.generate().then(res => {/*** res:base64图片*/rotateBase64Img(res, 270, `${this.signName ? this.signName + '-签名.jpg' : 'sign.jpg'}`, '', data => {this.$emit('sureHandler', data)})}).catch(err => {console.log('err----', err)this.$dialog.alert({message: this.noSignTipText})})}}
}
</script><style lang='scss' scoped>
.signContainer {width: 100%;height: 100vh;display: flex;background-color: #fff;.btns {width: 55px;background-color: #f8f8f8;display: flex;flex-direction: column;justify-content: center;.reset {margin-bottom: 70px;}}.vue-esign {z-index: 2;}.tipText {position: absolute;top: 50%;width: var(--width);left: calc(50% + 55px);transform: translateX(-50%) translateY(-50%) rotateZ(90deg);text-align: center;color: #ddd;letter-spacing: 2px;}
}
::v-deep .van-button {width: 85px !important;height: 35px;transform: rotate(90deg) translateY(15px);text-align: center;.van-button__text {letter-spacing: 5px;}
}
</style>

组件全局注册

main.js

import vueEsign from 'vue-esign' // 需要 npm 包下载 npm install vue-esign
Vue.use(vueEsign)import SignCanvas from '@/components/SignCanvas'
Vue.component('SignCanvas', SignCanvas)
// ...

组件使用

<!-- XXXX签名 -->
<template><SignCanvas ref="SignCanvasRef" :signName="nameList[nameIndex]" @sureHandler="sureSignHandler" />
</template><script>
export default {name: 'BloodRegisterSign',components: {},data() {return {// ...inputData: {}, // 该数据中 cxmjView 为需要签名的人员姓名nameIndex: 0, // 当前签名为第几个人签名signFileList: [] // 签名图片列表}},computed: {nameList() {return this.inputData.cxmjView ? this.inputData.cxmjView.split(',') : [] // 需要有多个签名}},watch: {},created() {console.log('this.$route----', this.$route)this.inputData = JSON.parse(this.$route.query.inputData || '{}')// ...},methods: {sureSignHandler(data) {this.signFileList.push(data)if (this.nameIndex < this.nameList.length - 1) {this.nameIndex++this.$refs.SignCanvasRef.resetHandler()} else {this.submitHandler()}},submitHandler() {// TODO:调用接口,提交签名图片等数据}}
}
</script><style lang='scss' scoped>
</style>

效果展示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/109447.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数学建模——最优连接(基于最小支撑树)

一、概念 1、图的生成树 由图G(V,E)的生成子图G1(V,E1)(E1是E的子集&#xff09;是一棵树&#xff0c;则称该树为图G的生成树&#xff08;支撑树&#xff09;&#xff0c;简称G的树。图G有支撑树的充分必要条件为图G连通。 2、最小生成树问题 连通图G(V,E)&#xff0c;每条边…

C语言实现// 输入一个英文句子,以‘ . ’结束,统计句子中包含的字符个数

完整代码&#xff1a; // 输入一个英文句子&#xff0c;以‘ . ’结束&#xff0c;统计句子中包含的字符个数 #include<stdio.h>int main(){char ch;int length0;printf("请输入一个英文句子\n");while (chgetchar()!.){length;}printf("字符个数是&…

开源CasaOS云软件发现关键漏洞

近日&#xff0c;开源 CasaOS 个人云软件中发现的两个严重的安全漏洞。该漏洞一旦被攻击者成功利用&#xff0c;就可实现任意代码执行并接管易受攻击的系统。 这两个漏洞被追踪为CVE-2023-37265和CVE-2023-37266&#xff0c;CVSS评分均为9.8分。 发现这些漏洞的Sonar安全研究…

【Java实战】创建第一个Springboot项目Hello world

没有旗舰版的Idea授权&#xff0c;所以安装了社区版的idea。不知道从何时开始&#xff0c;社区版IDEA的插件不好用了&#xff0c;所以就换了个方法生成Springboot项目。 一 在线生成 选择好对应的选项后&#xff0c;点击生成就可以下载到一个完整的springboot项目了。 二 使用…

linux安装达梦数据库(命令行安装)

安装达梦数据库 创建安装用户 1,创建安装用户组dinstall [rootdmDMServer1 ~]# groupadd -g 12345 dinstallgroupadd : 创建组 -g : 指定组id&#xff08;GID&#xff09; 12345&#xff1a; 指定的组名称 dinstall &#xff1a; 组名 2,创建安装用户dmdba [rootdmDMSe…

Mycat2 分布式数据库中间件

一.安装部署 Mycat2目前还不支持直接获取Docker镜像&#xff0c;需要自己通过Dockerfile打包镜像&#xff0c;其实这也是为了开发者考虑&#xff0c;比如一些个性化功能&#xff0c;如自定义分片等 Dockerfile FROM docker.io/adoptopenjdk/openjdk8:latestENV AUTO_RUN_DIR…

PhotoShop字体加粗,PhotoShop字体添加边框,PhotoShop设置文字背景为图片

字体加粗 创建文字&#xff1a; 选中文字 &#xff08;用鼠标点一下&#xff09; 然后 转换为智能对象 输入合适的数值即可加粗字体 字体添加外边框 点击字体&#xff0c;点击右下角的fx 咋fx中选择描边 设置文字背景为图片 将文字放到刚刚图片所在的位置即可 。…

vscode工程屏蔽不使用的文件夹或文件的方法

一. 简介 vscode是一款 微软提供的免费的代码编辑软件。 对于 IMX6ULL-ALPHA开发板而言&#xff0c;NXP官方uboot一定会支持不止 IMX6ULL芯片的代码&#xff0c;也不止支持 一种架构&#xff0c;还支持其他芯片或架构的源码文件。 为了方便阅读代码&#xff0c;vscode软件可…

2024年关于湖北省建筑安全员B证报考你需要了解

2024年关于湖北省建筑安全员B证报考你需要了解 建筑安全员B证指的是建设厅三类人员建安B证&#xff0c;很多人对于B证报考不是很了解&#xff0c;对于安全员B报考条件、报考流程、报考时间、报考地区等事项叙后尘告诉你们。 湖北建筑安全员B证报考条件-建安B证 1.你的二级建造师…

SpringCloud对服务内某个client进行单独配置

文章目录 问题解决过程问题解决 问题 我们的微服务项目用的是springCloud&#xff0c;某个微服务接口因为数据处理量大&#xff0c;出现了接口超时的情况&#xff0c;我们需要单独修改这一个feignClient的超时时间。 解决过程 一开始项目只是在application文件里面进行了全局…

计算机缺失pasmutility.dll怎么办,三步解决pasmutility.dll缺失

pasmutility.dll文件是windows系统中重要的dll文件&#xff0c;电脑一旦缺失dll文件就会导致电脑无法正常运行&#xff0c;同时还会唐初电脑缺失pasmutility.dll文件的提示窗口&#xff0c;非常影响电脑运行&#xff0c;那么出现计算机缺失pasmutility.dll该怎么办呢&#xff1…

21.1 stm32使用LTDC驱动LCD--配置说明

本文讲解如何配置LTDC驱动LCD的参数配置&#xff0c;以及CubeMx参数配置说明 本文使用的是淘宝买的一块带电容触摸的液晶显示屏&#xff1a;5寸TFT液晶显示屏高清800*480免驱40P通用RGBIPS全视角彩屏GT911 说实话&#xff0c;价格还是相对挺便宜的&#xff0c;值得入手&#xf…

LoRa和LoRaWAN详细介绍

目录 简介 1.LoRaWAN系统架构 2.LoRa射频技术有什么优缺点 3.LoRa和其他通讯方式对比 4.哪些场合和需求需要用到LoRaWAN 简介 LoRa技术是由Semtech公司开发&#xff0c;基于扩频频移键控&#xff08;CSS&#xff09;调制&#xff0c;这种调制技术可以实现在不同频率上发送…

2.SpringSecurity - 处理器简单说明

文章目录 SpringSecurity 返回json一、登录成功处理器1.1 统一响应类HttpResult1.2 登录成功处理器1.3 配置登录成功处理器1.4 登录 二、登录失败处理器2.1 登录失败处理器2.2 配置登录失败处理器2.3 登录 三、退出成功处理器3.1 退出成功处理器3.2 配置退出成功处理器3.3 退出…

list.set交换数据需要(or不需要)添加其他中间变量,两个例子告诉你

说明&#xff1a;set()方法是来修改指定位置的元素。 两个参数&#xff0c;第一个参数是要修改的元素的索引&#xff0c;第二个参数是要设置的新值。 案例一&#xff1a;当链表中传入的是字符串时&#xff1a; public static void main(String[] args) {List list new Linke…

关于W5500网卡使用过程的部分问题记录

某个项目中用到了W5500这种自带网络协议栈的网卡芯片&#xff0c;由于该项目开发时间很紧&#xff0c;就临时网上买了一些模块拼凑到了一套系统&#xff0c;经过验证果真这种拼积木的方法只能用在学生实验开发中&#xff0c;真不能拿来做工程应用&#xff0c;硬件太不稳定很容易…

openGauss学习笔记-101 openGauss 数据库管理-管理数据库安全-客户端接入之用SSH隧道进行安全的TCP/IP连接

文章目录 openGauss学习笔记-101 openGauss 数据库管理-管理数据库安全-客户端接入之用SSH隧道进行安全的TCP/IP连接101.1 背景信息101.2 前提条件101.3 操作步骤 openGauss学习笔记-101 openGauss 数据库管理-管理数据库安全-客户端接入之用SSH隧道进行安全的TCP/IP连接 101.…

杨辉三角按列求和

假设求杨辉三角这一列 我们考虑这个格子&#xff1a; 然后对其不断展开 综上&#xff1a; ∑ i 0 n ( i k ) ( n 1 k 1 ) \sum_{i0}^n\binom i k\binom {n1}{k1} i0∑n​(ki​)(k1n1​) ∑ i l r ( i k ) ( r 1 k 1 ) − ( l k 1 ) \sum_{il}^r\binom i k\binom{r1}{k…

九月 NFT 行业解读:熊市情绪仍占上风

作者: stellafootprint.network 9 月&#xff0c;著名主流媒体《滚石》&#xff08;Rolling Stone&#xff09;发表了一篇题为《你的 NFT 实际上——终于——完全不值钱了》&#xff08;Your NFTs Are Actually — Finally — Totally Worthless&#xff09;的文章&#xff0c…

论文解析-moETM-多组学整合模型

论文解析-moETM 参考亮点动机发展现状现存问题 功能方法Encoder改进Decoder改进 评价指标生物保守性批次效应移除 实验设置结果多组学数据整合cell-topic mixture可解释性组学翻译性能评估RNA转录本、表面蛋白、染色质可及域调控关系研究1. 验证同一主题下&#xff0c;top gene…