代码拉取完成,页面将自动刷新
同步操作将从 lv666/pdfSignature 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pdf</title>
<link rel="stylesheet" href="src/index.css">
<script type="text/javascript" src="src/vue.js"></script>
<script type="text/javascript" src="src/pdf.js"></script>
<script type="text/javascript" src="src/pdf.worker.js"></script>
<script type="text/javascript" src="src/fabric.js"></script>
<script type="text/javascript" src="src/axios.min.js"></script>
<script type="text/javascript" src="src/jquery.js"></script>
<script type="text/javascript" src="src/jquery-ui.js"></script>
<script type="text/javascript" src="src/Sortable.min.js"></script>
<script type="text/javascript" src="src/vuedraggable.umd.min.js"></script>
</head>
<body>
<div class="elesign" id="app">
<div class="left">
<div class="left-title">我的印章</div>
<draggable v-model="mainImagelist" :group="{name:'itext',pull:'clone'}" :sort="false" @end="end">
<transition-group type="transition">
<li v-for="item in mainImagelist" :key="item" class="item">
<img :src="item" width="100%;" height="100%" class="imgstyle"/>
</li>
</transition-group>
</draggable>
</div>
<!-- pdf的预览 -->
<div class="center">
<div class="page">
<button class="btn-outline-dark" id="view-fullscreen">全屏</button>
<button class="btn-outline-dark" id="cancel-fullscreen">退出全屏</button>
<button class="btn-outline-dark" @click="prevPage">上一页</button>
<button class="btn-outline-dark" @click="nextPage">下一页</button>
<button class="btn-outline-dark" >{{ pageNum }}/{{ numPages }}页</button>
<input id="page-input" class="btn-outline-dark" :value="pageNum" type="number" ref="getPages" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" />
<button class="btn-outline-dark" @click="cutover">跳转</button>
</div>
<canvas id="the-canvas" />
</div>
<!-- 盖章部分 -->
<canvas id="ele-canvas"></canvas>
<div class="ele-control">
<button class="btn-outline-dark" @click="removeSignature">删除签章</button >
<button class="btn-outline-dark" @click="clearSignature">清除所有签章</button>
<button class="btn-outline-dark" @click="submitSignature">提交所有签章信息</button>
</div>
<!-- 任务信息 -->
<div class="right">
<div class="left-title">任务信息</div>
<div>
<div>
<div class="right-item">
<span class="right-item-title">文件主题</span>
<span class="detail-item-desc">{{taskInfo.title}}</span>
</div>
<div class="right-item">
<span class="right-item-title">发起方</span>
<span class="detail-item-desc">{{taskInfo.uname}}</span>
</div>
<div class="right-item">
<span class="right-item-title">截止时间</span>
<span class="detail-item-desc">{{taskInfo.endtime}}</span>
</div>
</div>
</div>
</div>
<div fix v-show="isSpinShow" >
<div class="loadingclass">
<div id="preloader_6">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
</div>
</body>
</html>
<script>
let pdfjsLib = window["pdfjs-dist/build/pdf"];
pdfjsLib.GlobalWorkerOptions.workerSrc = `http://${window.location.host}/pdf.worker.js`;
let storage = window.localStorage;
var app = new Vue ({
el: '#app',
data() {
return {
pdfUrl: '',
pdfDoc: null,
numPages: 1,
pageNum: 1,
scale: 1,
pageRendering: false,
pageNumPending: null,
sealUrl: '',
signUrl: '',
canvas: null,
ctx: null,
canvasEle: null,
whDatas: null,
isSpinShow: false,
mainImagelist: [],
taskInfo: {},
};
},
//计算属性,就是依赖其它的属性计算所得出最后的值
computed: {
hasSigna() {
return !!this.canvasEle && !!this.canvasEle.getObjects()[0] ? true : false;
},
},
//监听一个值的变化,然后执行相对应的函数。
watch: {
whDatas: {
handler() {
if (!!this.whDatas) {
this.renderFabric();
this.canvasEvents();
}
},
},
pdfUrl: function(val){
this.$nextTick(() => {
this.showpdf(val);
});
},
pageNum: function(pageNum) {
let pageNums = Number(pageNum)
this.commonSign(this.pageNum);
this.queueRenderPage(this.pageNum);
}
},
//事件方法
methods: {
renderPage(num) {
let _this = this;
this.pageRendering = true;
// Using promise to fetch the page
return this.pdfDoc.getPage(num).then((page) => {
let viewport = page.getViewport({ scale: _this.scale });
_this.canvas.height = viewport.height;
_this.canvas.width = viewport.width;
// Render PDF page into canvas context
let renderContext = {
canvasContext: _this.ctx,
viewport: viewport,
};
let renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(() => {
_this.pageRendering = false;
if (_this.pageNumPending !== null) {
// New page rendering is pending
this.renderPage(_this.pageNumPending);
_this.pageNumPending = null;
}
this.isSpinShow = false;
});
});
},
queueRenderPage(num) {
if (this.pageRendering) {
this.pageNumPending = num;
} else {
this.renderPage(num);
}
},
prevPage() {
this.confirmSignature();
if (this.pageNum <= 1) {
return;
}
this.pageNum--;
},
nextPage() {
this.confirmSignature();
if (this.pageNum >= this.numPages) {
return;
}
this.pageNum++;
},
cutover() {
this.confirmSignature();
let pageNums = Number(this.$refs.getPages.value);
if(pageNums > this.numPages) {
this.pageNum = this.numPages;
return;
}
if (pageNums < 1) {
this.pageNum = 1;
return;
}
if(!(/(^[1-9]\d*$)/.test(pageNums))) {
this.pageNum = 1;
return;
}
this.pageNum = pageNums;
},
showpdf(pdfUrl) {
this.canvas = document.getElementById("the-canvas");
this.ctx = this.canvas.getContext("2d");
pdfjsLib.getDocument({url:pdfUrl, rangeChunkSize:65536, disableAutoFetch:false}).promise.then((pdfDoc_) => {
this.pdfDoc = pdfDoc_;
this.numPages = this.pdfDoc.numPages;
this.renderPage(this.pageNum).then((res) => {
this.renderPdf({
width: this.canvas.width,
height: this.canvas.height,
});
// this.isSpinShow = false;
});
this.commonSign(this.pageNum, true);
});
},
/**
* 盖章部分开始
*/
// 设置绘图区域宽高
renderPdf(data) {
this.whDatas = data;
document.querySelector(".elesign").style.width = data.width + "px";
},
// 生成绘图区域
renderFabric() {
let canvaEle = document.querySelector("#ele-canvas");
canvaEle.width = this.whDatas.width;
canvaEle.height = this.whDatas.height;
this.canvasEle = new fabric.Canvas(canvaEle);
let container = document.querySelector(".canvas-container");
container.style.position = "absolute";
container.style.top = "42px";
},
// 相关事件操作哟
canvasEvents() {
// 拖拽边界 不能将图片拖拽到绘图区域外
this.canvasEle.on("object:moving", function (e) {
var obj = e.target;
// if object is too big ignore
if(obj.currentHeight > obj.canvas.height || obj.currentWidth > obj.canvas.width){
return;
}
obj.setCoords();
// top-left corner
if(obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0){
obj.top = Math.max(obj.top, obj.top-obj.getBoundingRect().top);
obj.left = Math.max(obj.left, obj.left-obj.getBoundingRect().left);
}
// bot-right corner
if(obj.getBoundingRect().top+obj.getBoundingRect().height > obj.canvas.height || obj.getBoundingRect().left+obj.getBoundingRect().width > obj.canvas.width){
obj.top = Math.min(obj.top, obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top);
obj.left = Math.min(obj.left, obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left);
}
});
},
// 添加公章
addSeal(sealUrl, left, top, index) {
fabric.Image.fromURL(
sealUrl,
(oImg) => {
oImg.set({
left: left,
top: top,
// angle: 10,
scaleX: 0.8,
scaleY: 0.8,
index:index,
});
// oImg.scale(0.5); //图片缩小一
this.canvasEle.add(oImg);
}
);
},
// 删除签章
removeSignature() {
this.canvasEle.remove(this.canvasEle.getActiveObject())
},
//翻页展示盖章信息
commonSign(pageNum, isFirst = false) {
if(isFirst == false) this.canvasEle.remove(this.canvasEle.clear()); //清空页面所有签章
let caches = JSON.parse(storage.getItem('signs')); //获取缓存字符串后转换为对象
if(caches == null) return false;
let datas = caches[this.pageNum];
if(datas != null && datas != undefined) {
for (let index in datas) {
this.addSeal(datas[index].sealUrl, datas[index].left, datas[index].top, datas[index].index);
}
}
},
//确认签章位置并保存到缓存
confirmSignature() {
let data = this.canvasEle.getObjects(); //获取当前页面内的所有签章信息
let caches = JSON.parse(storage.getItem('signs')); //获取缓存字符串后转换为对象
let signDatas = {}; //存储当前页的所有签章信息
let i = 0;
let sealUrl = '';
for(var val of data) {
signDatas[i] = {
width: val.width,
height: val.height,
top: val.top,
left: val.left,
angle: val.angle,
translateX: val.translateX,
translateY: val.translateY,
scaleX: val.scaleX,
scaleY: val.scaleY,
pageNum: this.pageNum,
sealUrl: this.mainImagelist[val.index],
index:val.index
}
i++;
}
if(caches == null) {
caches = {};
caches[this.pageNum] = signDatas;
} else {
caches[this.pageNum] = signDatas;
}
storage.setItem('signs', JSON.stringify(caches)); //对象转字符串后存储到缓存
},
//提交数据
submitSignature() {
this.confirmSignature();
let caches = storage.getItem('signs');
if (this.isSpinShow === false) {
this.isSpinShow = true
axios.post('/index.php?a=getInfo&m=sign&d=cg', {
'pdfWidth':this.whDatas.width,
'pdfHeight':this.whDatas.height,
'signs':caches,
'mid':mid
}).then(function (response) {
if(response.data.code == 200) {
storage.removeItem('signs');
this.isSpinShow = false
}else{
alert(response.data.msg);
}
})
.catch(function (error) {
this.isSpinShow = false
console.log(error);
});
}
},
//清空数据
clearSignature() {
this.canvasEle.remove(this.canvasEle.clear()); //清空页面所有签章
storage.removeItem('signs'); //清除缓存
},
/**
* 盖章部分结束
*/
//获取url参数
getParam(str) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == str){return pair[1];}
}
return(false);
},
end(e){
this.addSeal(this.mainImagelist[e.newDraggableIndex], e.originalEvent.layerX, e.originalEvent.layerY, e.newDraggableIndex)
},
},
//未渲染html页面时执行
created: function () {
var that = this;
that.pdfUrl = './show.pdf';
that.mainImagelist = [`http://${window.location.host}/`+'sign.png',`http://${window.location.host}/`+'seal.png'];
that.taskInfo = {'title':'测试盖章', uname:'张三', endtime:'2021-09-01 17:59:59'};
// let mid = that.getParam('mid');
// that.isSpinShow = true;
// // //获取pdf路径和签章路径
// let param = "&mid="+mid;
// axios.get('/index.php?a=infos&m=sign&d=cg'+param)
// .then(function (obj) {
// let res = obj.data;
// if(res.code == 200) {
// let list = [];
// for (let i = 0; i < res.data.seals.length; i++) {
// let path = res.data.seals[i]['files']
// list[i] = `http://${window.location.host}/`+ path;
// }
// list.unshift(`http://${window.location.host}/`+res.data.signPath)
// that.mainImagelist = list;
// that.pdfUrl = res.data.pdfPath+'?v='+Math.random();
// that.taskInfo = res.data.taskInfo;
// // that.pdfUrl = '';
// }else{
// alert(res.msg);
// }
// })
// .catch(function (error) {
// console.log(error);
// that.isSpinShow = false;
// });
},
//html加载完成后执行
mounted() {
},
});
</script>
<script type="text/javascript">
(function () {
var viewFullScreen = document.getElementById("view-fullscreen");
if (viewFullScreen) {
viewFullScreen.addEventListener("click", function () {
var docElm = document.documentElement;
if (docElm.requestFullscreen) {
docElm.requestFullscreen();
}
else if (docElm.msRequestFullscreen) {
docElm = document.body; //overwrite the element (for IE)
docElm.msRequestFullscreen();
}
else if (docElm.mozRequestFullScreen) {
docElm.mozRequestFullScreen();
}
else if (docElm.webkitRequestFullScreen) {
docElm.webkitRequestFullScreen();
}
}, false);
}
var cancelFullScreen = document.getElementById("cancel-fullscreen");
if (cancelFullScreen) {
cancelFullScreen.addEventListener("click", function () {
if (document.exitFullscreen) {
document.exitFullscreen();
}
else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
}
else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}
}, false);
}
var fullscreenState = document.getElementById("fullscreen-state");
if (fullscreenState) {
document.addEventListener("fullscreenchange", function () {
fullscreenState.innerHTML = (document.fullscreenElement)? "" : "not ";
}, false);
document.addEventListener("msfullscreenchange", function () {
fullscreenState.innerHTML = (document.msFullscreenElement)? "" : "not ";
}, false);
document.addEventListener("mozfullscreenchange", function () {
fullscreenState.innerHTML = (document.mozFullScreen)? "" : "not ";
}, false);
document.addEventListener("webkitfullscreenchange", function () {
fullscreenState.innerHTML = (document.webkitIsFullScreen)? "" : "not ";
}, false);
}
var marioVideo = document.getElementById("mario-video")
videoFullscreen = document.getElementById("video-fullscreen");
if (marioVideo && videoFullscreen) {
videoFullscreen.addEventListener("click", function (evt) {
if (marioVideo.requestFullscreen) {
marioVideo.requestFullscreen();
}
else if (marioVideo.msRequestFullscreen) {
marioVideo.msRequestFullscreen();
}
else if (marioVideo.mozRequestFullScreen) {
marioVideo.mozRequestFullScreen();
}
else if (marioVideo.webkitRequestFullScreen) {
marioVideo.webkitRequestFullScreen();
}
}, false);
}
})();
</script>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。