web pdf 拖拽签章
web pdf 拖拽签章
主要通过火狐的pdfjs 来实现
1. 下载js 并编译
地址 https://mozilla.github.io/pdf.js/
按照官网当下下载并编译就得到了js
2.其实也没有什么好讲的,都是用的js中的方法,官网中都有
按照步骤就能生成一个document元素,然后通过js方法操作元素就好了。
注意web页面显示的元素的大小和元素的大小不一样,要注意比例
3.效果展示
- 原图

- 签字后

- 下载后

4.代码展示
<div><div class="container"><div class="left" id="canvas"></div><div class="right"><ul><li><img class="sign-img" th:src="@{/sign/img.jpg}" onmousedown="srcImgMoveDown(this);" /></li></ul><button type="button" onclick="saveAndDown();">保存并下载</button></div></div><input type="hidden" value="" id="hiddenInput">
</div><script>var moveFlag = falsevar downFlag = falsevar bodyvar scale = 1.5;window.onload = function () {document.body.ondrop = function(event) {event.preventDefault();event.stopPropagation();}getPdf()body = document.getElementsByTagName('body')[0]body.addEventListener('mousemove',function(eve){if(!moveFlag){return}var img = document.getElementById('moveImg')img.style.position = 'fixed'img.style.top = eve.clientY + 'px'img.style.left = eve.clientX + 'px'})document.getElementById('canvas').addEventListener('click',function (){moveFlag = !moveFlag})}function getPdf() {var loadingTask = pdfjsLib.getDocument("/index/getPdf")loadingTask.promise.then(function (pdf) {for (let i = 1; i <= pdf.numPages; i++) {pdf.getPage(i).then(function (page) {var viewport = page.getViewport({scale: scale,});var outputScale = window.devicePixelRatio || 1;var canvas = document.createElement('canvas')canvas.setAttribute('name','canvas')canvas.setAttribute('id','canvas'+i)canvas.addEventListener('mouseup',eleClick)var context = canvas.getContext('2d');canvas.width = Math.floor(viewport.width * outputScale);canvas.height = Math.floor(viewport.height * outputScale);canvas.style.width = Math.floor(viewport.width) + "px";canvas.style.height = Math.floor(viewport.height) + "px";var transform = outputScale !== 1? [outputScale, 0, 0, outputScale, 0, 0]: null;var renderContext = {canvasContext: context,transform: transform,viewport: viewport,background:'beige'};page.render(renderContext);document.getElementById('canvas').appendChild(canvas)});}})}function eleClick(even){let clientX = even.pageX - this.offsetLeft;let clientY = even.pageY - this.offsetTop;let id = this.getAttribute('id')console.log(id,clientX,clientY)document.getElementById('hiddenInput').value = clientX + "," +clientY + "," + id + "," + scale}function srcImgMoveDown(obj){var _img = document.getElementById('moveImg')console.log(_img)if(_img){return}var img = document.createElement('img')img.setAttribute('class',obj.getAttribute('class'))img.setAttribute('src',obj.getAttribute('src'))img.setAttribute('id','moveImg')body.appendChild(img)moveFlag = true}function saveAndDown(){var val = document.getElementById('hiddenInput').valuewindow.open("/index/saveAndDown?val=" + val)}
5.问题和完整代码请在评论区留言
相关文章:
web pdf 拖拽签章
web pdf 拖拽签章 主要通过火狐的pdfjs 来实现 1. 下载js 并编译 地址 https://mozilla.github.io/pdf.js/ 按照官网当下下载并编译就得到了js 2.其实也没有什么好讲的,都是用的js中的方法,官网中都有 按照步骤就能生成一个document元素,然…...
SQLAlchemy 库创建数据库引擎和会话工厂附带SQLSERVER驱动版本确认方式
SQLAlchemy 库创建数据库引擎和会话工厂 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker# 创建数据库引擎 engine create_engine(mssqlpyodbc://user:passhost:port/database?driverODBCDriver11forSQLServer)# 创建会话工厂 Session sess…...
用Python登录账户
1 问题 如何利用python登录账户? 2 方法 账户和密码存放在文件夹中从文件夹中读取并比较密码密文验证三次后,如不成功则锁定用户 通过。。。。。。。。等证明提出的方法是有效的,能够解决开头提出的问题。 代码清单 1 import osimport getpas…...
梳理下我自已对Reactor与及IO多路复用的select\poll\epoll的理解
Reactor是一种设计思想的落地,其中IO多路复用的具体落地:select\poll\epoll。都是基于Reactor的延伸。它的核心是Reactor与资源处理器。Reactor负责监听与事件的分发,事件包括连接事件、读事件、写事件。 具体的流程是系统调用监听请求&…...
4. 广播变量
一、分区规则(DataStream Broadcast)和广播变量(Flink Broadcast) 1.1 DataStream Broadcast(分区规则) 分区规则是把元素广播给所有的分区,数据会被重复处理。 DataStream.broadcast()1.…...
GPT 内部 — I : 了解文本生成
年轻的陀思妥耶夫斯基被介绍给生成AI,通过Midjourney创建 一、说明 我经常与不同领域的同事互动,我喜欢向几乎没有数据科学背景的人传达机器学习概念的挑战。在这里,我试图用简单的术语解释 GPT 是如何连接的,只是这次是书面形式。…...
平板触控笔哪款好用?好用的第三方apple pencil
而对于那些把ipad当做学习工具的人而言,苹果Pencil就成了必备品。但因为苹果Pencil太贵了,不少的学生们买不起。因此,最佳的选择还是平替电容笔,今天在这里整理了一些高性价比的电容笔! 一、挑选电容笔的要点…...
Mac 上更新系统PATH环境变量
目录 为什么要更新系统的PATH环境变量如何更新系统的PATH环境变量1. 确保你知道工具的实际安装位置。2. 将目录(实际安装位置)添加到PATH:export PATH$PATH:/path/to/your/tools补充:通过以下方法来确定当前正在使用的是Bash还是Z…...
Visual Studio Code 终端配置使用 MySQL
Visual Studio Code 终端配置使用 MySQL 找到 MySQL 的 bin 目录 在导航栏中搜索–》服务 找到MySQL–>双击 在终端切换上面找到的bin目录下输入指令 终端为Git Bash 输入命令 ./mysql -u root -p 接着输入密码,成功在终端使用 MySQL 数据库。...
12 | 使用 Spark SQL执行CURL
Spark SQL 是 Apache Spark 生态系统中的一个组件,它提供了用于结构化数据处理和分析的高级接口。Spark SQL 可以让用户使用 SQL 语言来查询和操作数据,同时也提供了强大的分布式计算能力。下面是关于 Spark SQL、SparkSession 和 DataFrame 的关键点: 1. Spark SQL: 定义…...
容器编排学习(七)控制器介绍与使用
一 控制器 控制器是 k8s内置的管理工具。可以帮助用户实现 Pod的自动部署、自维护、扩容、滚动更新等功能的自动化程序。 为什么要使用控制器? 有大量的 Pod需要维护管理需要维护 Pod的健康状态控制器可以像机器人一样可以替用户完成维护管理的工作 二 Deployment 1 概…...
一文看懂微信小程序新版隐私协议(附带弹窗组件)
一、前言 微信小程序近期又迎来了一次改革–9月15日之后如果小程序涉及调用微信的隐私接口获取用户的信息的,需要用户手动同意协议后才可正常调用接口,否则会返回报错信息。 隐私接口目前常用的有:手机号快捷获取、读取照片、获取用户的头像…...
Java认识异常(超级详细)
目录 异常的概念和体系结构 异常的概念 异常的体系结构 异常的分类 1.编译时异常 2.运行时异常 异常的处理 防御式编程 LBYL EAFP 异常的抛出 异常的捕获 异常声明throws try-catch捕获并处理 finally 异常的处理流程 异常的概念和体系结构 异常的概念 在Java中…...
危险边缘:揭示 Python 编程中易被忽视的四个安全陷阱
今天我们将要谈论一个非常重要的话题:Python 编程中的安全问题。作为一门广受欢迎的编程语言,Python 已经成为了许多开发者、计算机专业学生以及打工人的必备技能。 原文链接食用更佳 危险边缘:揭示 Python 编程中易被忽视的四个安全问题 然…...
抖店开通后,新手必须要知道的几个做店技巧,建议认真看完
我是王路飞。 抖店的运营,无非就是围绕【产品】【流量】展开的。 你要是能把这两个点给搞明白,新店快速出单、真是爆单就不再是问题了。 今天就给你们说一下,抖店开通后,作为一个新手商家,你必须要知道的几个做店技…...
FPGA时序分析与约束(5)——时序路径
一、前言 在之前的文章中我们分别介绍了组合电路的时序,时序电路的时序和时钟的时序问题,我们也对于时序分析,时序约束和时序收敛几个基本概念进行了区分,在这篇文章中,我们将介绍时序约束相关的最后一部分基本概念&am…...
Flutter:构建跨平台应用的未来选择
随着移动设备的普及和技术的不断发展,跨平台移动应用开发成为了一个热门的需求。Flutter作为一款由Google开发的开源移动应用开发框架,受到了越来越多的关注。本文将带你了解Flutter的优势、应用场景以及如何使用Flutter进行开发。 一、Flutter的优势 …...
08_瑞萨GUI(LVGL)移植实战教程之LVGL对接串口打印
本系列教程配套出有视频教程,观看地址:https://www.bilibili.com/video/BV1gV4y1e7Sg 8. LVGL对接串口打印 本次实验我们为LVGL库对接串口的打印功能。 8.1 复制工程 上次实验得出的工程我们可以通过复制在原有的基础上得到一个新的工程。 如果你不清…...
【LeetCode75】第五十题 无限集中的最小数字
目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 这是我们在LeetCode75里遇到的第二道设计类题目,难度比上一次的设计题目要难上一些。 题目假设我们拥有一个从1开始的无限集…...
关于 Unity 连接 MuMu 模拟器上的 Unity Remote 5 的方法
在使用 Unity 开发 Android 的过程中,可以通过使用 Unity Remote 这个 app 来和真机连接,进而在真实环境下进行测试性能等工作,而本次则是由于其他问题引出的一个小坑,记录以备后续查询。 这次是由于在自学过程中遇到的一个工程&…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
