电子签章之文档缩放计算相对坐标

电子签章之文档缩放计算相对坐标

  • 电子签章
    • 记录背景
    • 需求描述
    • 知识普及:offset、client分别是到哪里的距离
    • 实现思路
    • 边角
          • 1. 文档缩放后,印章的大小也要响应改变
          • 2.缩放前后,图片在文档上的相对位置计算
          • 3.缩放前后文档比例系数
          • 4.监听页面变化,对图片宽高、页面上显示位置做计算
    • 致谢

电子签章

记录背景

随着互联网和无纸化的推行,现在各种操作电子化已经逐渐变成常态。各种单据电子化,合同电子化,因此出现了电子签章的概念。最近的工作就是在做一个电子签章系统,在这里记录一下掉头发的经历吧。

需求描述

电子签章系统的一个功能,在网页预览用户上传的文件,并拖拽签名或公章图片到文档上,完成模拟盖章动作,并获取盖章的坐标信息。说到这里,是不是会有小伙伴觉得这有什么难度吗?当然,没有[笑哭]。问题在于,预览的文件在页面可以进行缩放,而缩放前后,盖章位置相对于纸张的比例的不变的,但我们在页面上获取到的坐标位置是相对于网页来说的,要将网页坐标转换成其在纸上上的坐标,确实有一点麻烦。

知识普及:offset、client分别是到哪里的距离

一张图说明clientX、offsetX、screenX、pageX、x的区别
电子签章之文档缩放计算相对坐标_第1张图片
(图片来源:https://blog.csdn.net/weixin_41342585/article/details/80659736)

实现思路

不考虑缩放问题的情况下,首先我们可以获取到印章所在地方的坐标,记作(px, py)。
由于我们最终要的坐标是相对于印章后方的文档的,因此此处 px, py的计算方式如下:

px = seal.offsetLeft - PDFDom.offsetLeft;
py = seal.offsetTop - PDFDom.offsetTop;

电子签章之文档缩放计算相对坐标_第2张图片
这时得到的坐标就是我们要的坐标

当文档发生缩放后,缩放前的文档宽度和缩放后的文档宽度的比应该与缩放前的坐标和缩放后的坐标比。

// originPageWidth 表示文档的原始宽度,pageWidth, 表示缩放后文档的宽度,px表示从页面获取的横坐标,(未发生缩放是就是我们要的坐标,发生缩放后就是缩放后的坐标,那么我们要的坐标就是页面获取的坐标乘一个系数);x表示目标坐标
x = originPageWidth / pageWidth * px
// 同理,可获得y坐标
y = originPageWidth / pageWidth * py

边角

似乎到这里为止,我们要计算的数据都已经得到了;但是我们还需要考虑一个问题,即,缩放后印章在页面上显示的问题。

1. 文档缩放后,印章的大小也要响应改变
document.getElementById(key2).style.width = defaultWidth * this.getRatio + 'px'
2.缩放前后,图片在文档上的相对位置计算
document.getElementById(key2).style.left = PDFLeft + x * r + dis + 'px'
document.getElementById(key2).style.top = PDFTop + y * r + 'px'
3.缩放前后文档比例系数
getRatio () {
    let ratio = 1;
    if (this.pageWidth !== this.originPageWidth) {
        ratio = this.pageWidth / this.originPageWidth
    }
    return ratio;
},
4.监听页面变化,对图片宽高、页面上显示位置做计算
watch: {
    pageWidth (newValue, originValue) {
        if (newValue !== originValue) {
            // 图片的默认宽度
            const defaultWidth = 200
            // 装pdf文件的容器
            const PDF = document.getElementById('pdfWrap')
            // pdf到网页左侧的距离
            const PDFLeft = PDF.offsetLeft
            // pdf到网页上方的距离
            const PDFTop = PDF.offsetTop
            // 记录坐标
            let x, y;
            // 记录放大缩小时页面的减少量
            let dis;
            let r = newValue / this.originPageWidth
            if (newValue < originValue) {
                dis = this.originPageWidth * 0.05
            } else {
                dis = -this.originPageWidth * 0.05 
            }
            x = px
            y = py
            // 图片宽度
            document.getElementById(id).style.width = defaultWidth * this.getRatio + 'px'
            document.getElementById(id).style.left = PDFLeft + x * r + dis + 'px'
            document.getElementById(id).style.top = PDFTop + y * r + 'px'
            if (key === 'sign') {
            this.signPosition.sign[id] = [x, y, this.currentPage]
            } else if(key === 'date') {
                this.signPosition.date[id] = [x, y, this.currentPage]
            } else {
                this.signPosition.remark[id] = [x, y, this.currentPage]
            }
        }
    }
},

致谢

感谢 wss5 提供的offset、page、client、screen距离的讲解

前端小白,思路可能不是很严谨,不过确实是花费好几天时间做出来的,中间各种钻牛角尖,各种被已知条件混淆。如有错误还请路过的大神及时指出。

最后感谢各位花时间看完这篇文章。再会哦~

你可能感兴趣的:(电子签章,盖章坐标,电子合同,web,html,js,vue)