代码拉取完成,页面将自动刷新
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes">
<title>PDF.js新UI</title>
<link rel="icon" href="data:;base64,=">
<link href="./static/css/style.css" rel="stylesheet" type="text/css"/>
<style>
.page-container {
background-color: #fff;
}
.page-container::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 30px; /* 调整加载动画的宽度 */
height: 30px; /* 调整加载动画的高度 */
border: 4px solid rgba(0, 0, 0, 0.3); /* 外圈颜色 */
border-top-color: #000; /* 旋转部分的颜色 */
border-radius: 50%;
animation: spin 1s linear infinite; /* 动画效果 */
transform: translate(-50%, -50%);
display: none; /* 初始不显示 */
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.page-container.loading::after {
display: block; /* 显示 loading 动画 */
}
.page-container.loading:empty {
height: 1085px;
background-color: #fff;
}
@media (max-width: 767px) {
.btn-text {
display: none;
}
#toolbar {
height: 46px;
}
#viewer-container {
height: calc(100% - 46px);
}
.dialog.eye .dialog-content .color-wrap {
width: 45px;
height: 45px
}
.dialog.eye .dialog-content{
padding: 20px;
gap: 20px;
}
#toolbar .btn-icon {
width: 18px;
height: 18px;
}
#dialog-zoom .dialog-content > div{
padding: 12px;
width: 100px;
}
#dialog-zoom .dialog-content .title{
font-size: 14px;
}
#dialog-zoom .dialog-content .description{
font-size: 12px;
}
.dialog .dialog-title {
font-size: 14px;
line-height: 30px;
}
.dialog .btn-wrap .btn{
font-size: 14px;
line-height: 30px;
font-weight: bold;
}
.dialog.goto .dialog-content .page-info{
font-size: 14px;
}
.dialog.goto .dialog-content .btn {
font-size: 12px;
display: inline-block;
margin-right: 4px;
height: 23px;
line-height: 23px;
padding: 0 5px;
background-color: #6f9bf6;
border-radius: 5px;
color: #ffffff;
}
.dialog.goto .dialog-content .goto-num-label{
font-size: 12px;
}
.dialog.goto .dialog-content .goto-num{
width: 50px;
}
#toolbar .btn-wrap{
border-radius: 10px;
height: 46px;
}
#sign-type .type-group{
border-radius: 8px;
}
#sign-type .btn-wrap{
width: 40px;
height: 40px;
}
#sign-type .btn-icon{
width: 20px;
height: 20px;
}
#sign-type{
right: 10px;
bottom: 90px;
}
.drawer{
height: calc(100% - 46px);
left: -75px;
padding: 10px 0;
}
.drawer.open{
width: 75px;
padding-top: 10px;
}
.drawer-item{
height: 85px;
}
}
</style>
</head>
<body>
<!-- 页码 -->
<div class="page-num">
<span id="current-page" class="current-page">1</span>
<span class="page-line">/</span>
<span id="total-page" class="total-page">-</span>
</div>
<div class="toolbar" id="toolbar">
<div class="btn-wrap" id="changeDrawer">
<div class="btn-icon"></div>
<span class="btn-text">文档总览</span>
</div>
<div class="btn-wrap" id="btn-zoom">
<img class="btn-icon" src="./static/icon/scaling.png" alt="">
<span class="btn-text">适合页面</span>
</div>
<div class="btn-wrap" id="btn-eye">
<img class="btn-icon" src="./static/icon/eye.png" alt="">
<span class="btn-text">护眼模式</span>
</div>
<div class="btn-wrap" id="btn-prev-page">
<img class="btn-icon" src="./static/icon/pre.png" alt="">
<span class="btn-text">上一页</span>
</div>
<div class="btn-wrap" id="btn-next-page">
<img class="btn-icon" src="./static/icon/next.png" alt="">
<span class="btn-text">下一页</span>
</div>
<div class="btn-wrap" id="btn-goto-page">
<img class="btn-icon" src="./static/icon/go.png" alt="">
<span class="btn-text">跳转到</span>
</div>
<div class="btn-wrap" id="sign">
<div class="btn-icon"></div>
<span class="btn-text">手写批阅</span>
</div>
<div class="btn-wrap disabled" id="save_pdf">
<img class="btn-icon" src="./static/icon/save.png" alt="">
<span class="btn-text">保存批阅</span>
</div>
</div>
<div id="page">
<div id="drawer" class="drawer"></div>
<div id="viewer-container" class="viewer-container"></div>
</div>
<!-- 缩放比例对话框 -->
<div id="dialog-zoom" class="dialog zoom">
<div class="dialog-title">缩放比例设置</div>
<div class="dialog-content">
<div id="dialog-zoom-width-page" class="item on">
<div class="title">适合页宽</div>
<div class="description">根据页面最大宽度适配文档内容</div>
</div>
<div id="dialog-zoom-fill-page" class="item">
<div class="title">适合页面</div>
<div class="description">根据页面宽高显示完整文档内容</div>
</div>
</div>
<div class="btn-wrap">
<a class="btn btn-close" href="javascript:void(0);">关闭</a>
</div>
</div>
<!-- 跳转到对话框 -->
<div id="dialog-goto" class="dialog goto">
<div class="dialog-title">跳转到指定页面</div>
<div class="dialog-content">
<div class="page-info">总页数:<span id="goto-total-page">-</span>页,当前页号:<span
id="goto-current-page">-</span></div>
<a id="btn-goto-first-page" href="javascript:void(0);" class="btn">到首页</a>
<a id="btn-goto-last-page" href="javascript:void(0);" class="btn">到尾页</a>
<span class="goto-num-label">输入页号:</span>
<input type="number" id="goto-num" class="goto-num">
<a id="btn-goto-num-page" href="javascript:void(0);" class="btn">跳转</a>
</div>
<div class="btn-wrap">
<a class="btn btn-close" href="javascript:void(0);">关闭</a>
</div>
</div>
<!-- 护眼模式对话框 -->
<div id="dialog-eye" class="dialog eye">
<div class="dialog-title">请选择护眼颜色</div>
<div class="dialog-content">
<div class="warp on" data-color="#ffffff">
<div class="color-wrap" style="background-color: #ffffff"></div>
<div class="color-text">银河白</div>
</div>
<div class="warp" data-color="#FAF9DE">
<div class="color-wrap" style="background-color: #FAF9DE"></div>
<div class="color-text">杏仁黄</div>
</div>
<div class="warp" data-color="#FFF2E2">
<div class="color-wrap" style="background-color: #FFF2E2"></div>
<div class="color-text">秋叶褐</div>
</div>
<div class="warp" data-color="#FDE6E0">
<div class="color-wrap" style="background-color: #FDE6E0"></div>
<div class="color-text">胭脂红</div>
</div>
<div class="warp" data-color="#E3EDCD">
<div class="color-wrap" style="background-color: #E3EDCD"></div>
<div class="color-text">青草绿</div>
</div>
<div class="warp" data-color="#DCE2F1">
<div class="color-wrap" style="background-color: #DCE2F1"></div>
<div class="color-text">海天蓝</div>
</div>
<div class="warp" data-color="#E9EBFE">
<div class="color-wrap" style="background-color: #E9EBFE"></div>
<div class="color-text">葛巾紫</div>
</div>
<div class="warp" data-color="#EAEAEF">
<div class="color-wrap" style="background-color: #EAEAEF"></div>
<div class="color-text">极光灰</div>
</div>
</div>
<div class="btn-wrap">
<a class="btn btn-close" href="javascript:void(0);">关闭</a>
</div>
</div>
<div id="sign-type">
<div class="type-group">
<div class="btn-wrap active" id="pen">
<div class="btn-icon"></div>
<span class="btn-text">笔触</span>
</div>
<div class="btn-wrap" id="hand">
<div class="btn-icon"></div>
<span class="btn-text">手触</span>
</div>
</div>
<div class="type-group">
<div class="btn-wrap" id="eraser">
<div class="btn-icon"></div>
<span class="btn-text">橡皮擦</span>
</div>
</div>
</div>
<div id="touch-circle"></div>
<script src="./static/plugin/pdfjs/pdf.js" type="module"></script>
<script src="./static/plugin/jquery/jquery.min.js" type="text/javascript"></script>
<script src="./static/plugin/signature_pad/signature_pad.umd.min.js"></script>
<script src="./static/plugin/uniapp/uni.webview.1.5.6.js"></script>
<script type="module">
import Viewer from './static/js/viewer.js';
// 视图容器
const viewerContainer = document.getElementById('viewer-container');
// 总览按钮
const changeDrawerButton = document.getElementById('changeDrawer');
// 签批按钮
const signButton = document.getElementById('sign');
// 缩略图抽屉
const drawer = document.getElementById('drawer');
// 上一页按钮
const prevPageButton = document.getElementById('btn-prev-page');
// 下一页按钮
const nextPageButton = document.getElementById('btn-next-page');
// 护眼模式按钮
const warpElements = document.querySelectorAll('#dialog-eye .warp');
// 页面容器
const pageContainers = document.querySelectorAll('.page-container');
// 工具栏
const toolbar = document.getElementById('toolbar');
const btnGotoPage = document.getElementById('btn-goto-page');
const gotoNum = document.getElementById('goto-num');
const gotoTotalPage = document.getElementById('goto-total-page');
const gotoCurrentPage = document.getElementById('goto-current-page');
const btnGotoNumPage = document.getElementById('btn-goto-num-page');
// 获取按钮元素
const btnZoom = document.getElementById('btn-zoom');
// 获取元素
const zoomWidthPage = document.getElementById('dialog-zoom-width-page');
const zoomFillPage = document.getElementById('dialog-zoom-fill-page');
const dialogZoom = document.getElementById('dialog-zoom');
const signType = document.getElementById('sign-type');
const eraserButton = document.getElementById('eraser');
// 手触按钮
const handButton = document.getElementById('hand');
// 笔触按钮
const penButton = document.getElementById('pen');
const saveButton = document.getElementById('save_pdf');
let params = (
new URL(location.href)
).searchParams;
// 文件路径
let filePath = params.get('file');
// 会议类型
let meetType = params.get('meetType');
// 是否源文件
let isSource = params.get('isSource') === null;
// 会议类型为历史会议时禁用签批按钮
if (parseInt(meetType) === 2) {
// 禁用签批按钮
if (signButton) {
signButton.classList.add('disabled');
signButton.style.pointerEvents = 'none';
}
// 禁用橡皮擦按钮
if (eraserButton) {
eraserButton.classList.add('disabled');
eraserButton.style.pointerEvents = 'none';
}
// 禁用保存批阅按钮
if (saveButton) {
saveButton.classList.add('disabled');
saveButton.style.pointerEvents = 'none';
}
}
let viewer = await Viewer.create({
urlType: "local",
url: filePath,
drawerElementId: 'changeDrawer',
signFileName: !isSource ? filePath.split('/').pop() : "",
})
/**
* 监听错误
*/
window.onerror = function (message, source, line, column, error) {
viewer.writeErrorToFile(message + source + line + column + error);
}
let togglePageStatus = false;
// 护眼模式
document.getElementById('btn-eye').addEventListener('click', function (e) {
if (this.classList.contains('disabled')) {
return false;
}
viewer.dialogTools('dialog-eye', true);
});
// 下一页按钮
nextPageButton.addEventListener('click', function () {
// 防止重复点击
if (togglePageStatus) return;
togglePageStatus = true;
// 如果当前页大于总页数,则直接返回
if (viewer.pageNumber > viewer.totalPages) {
togglePageStatus = false;
return;
}
viewer.skipPage(parseInt(viewer.pageNumber) + 1);
// 恢复页面点击状态
togglePageStatus = false;
});
// 监听 '上一页' 按钮
prevPageButton.addEventListener('click', function () {
// 防止重复点击
if (togglePageStatus) return;
togglePageStatus = true;
viewer.skipPage(parseInt(viewer.pageNumber) - 1);
// 恢复页面点击状态
togglePageStatus = false;
});
// 跳转到按钮点击事件
btnGotoPage.addEventListener('click', function () {
// 显示对话框
viewer.dialogTools('dialog-goto', true);
// 设置页面信息
gotoTotalPage.textContent = viewer.totalPages;
gotoCurrentPage.textContent = viewer.pageNumber;
// 清空输入框并聚焦
gotoNum.value = '';
gotoNum.focus();
});
// 跳转到最后一页按钮
document.getElementById('btn-goto-last-page').addEventListener('click', function () {
if (togglePageStatus) return;
togglePageStatus = true;
viewer.skipPage(parseInt(viewer.totalPages));
// 恢复页面点击状态
togglePageStatus = false;
viewer.dialogTools('dialog-goto', false);
});
// 跳转到第一页按钮
document.getElementById('btn-goto-first-page').addEventListener('click', function () {
if (togglePageStatus) return;
togglePageStatus = true;
viewer.skipPage(1);
// 恢复页面点击状态
togglePageStatus = false;
viewer.dialogTools('dialog-goto', false);
});
// 绑定点击事件
btnGotoNumPage.addEventListener('click', function () {
let gotoNumVal = gotoNum.value;
if (gotoNumVal !== '') {
viewer.skipPage(parseInt(gotoNumVal));
// 关闭对话框
viewer.dialogTools('dialog-goto', false);
} else {
// 如果输入框为空,聚焦到该输入框
gotoNum.focus();
}
});
// 抽屉开关事件
changeDrawerButton.addEventListener('click', function () {
if (changeDrawerButton.classList.contains('disabled')) {
return;
}
changeDrawerButton.classList.toggle('active');
if (changeDrawerButton.classList.contains('active')) {
viewer.drawerOpen = true;
viewer.renderThumbnails();
// 滑动到当前页
viewer.changeThumbnailActive(viewer.pageNumber);
} else {
viewer.drawerOpen = false;
}
viewer.zoomPage();
viewer.skipPage(parseInt(viewer.pageNumber));
document.getElementById('drawer').classList.toggle('open');
});
// 为按钮添加点击事件监听器
btnZoom.addEventListener('click', function () {
// 检查按钮是否有 'disabled' 类
if (this.classList.contains('disabled')) {
return;
}
// 调用 dialogTools 函数
viewer.dialogTools('dialog-zoom', true);
});
// 为“页面宽度”选项添加点击事件
zoomWidthPage.addEventListener('click', function () {
viewer.pageZoom = 'page-width';
var items = dialogZoom.querySelectorAll('.item');
// 移除所有 .item 元素上的 'on' 类
items.forEach(function (item) {
item.classList.remove('on');
});
// 为当前选项添加 'on' 类
this.classList.add('on');
viewer.zoomPage();
viewer.dialogTools('dialog-zoom', false);
});
// 为“页面填充”选项添加点击事件
zoomFillPage.addEventListener('click', function () {
viewer.pageZoom = 'page-fill';
var items = dialogZoom.querySelectorAll('.item');
// 移除所有 .item 元素上的 'on' 类
items.forEach(function (item) {
item.classList.remove('on');
});
// 为当前选项添加 'on' 类
this.classList.add('on');
viewer.zoomPage();
viewer.dialogTools('dialog-zoom', false);
});
// 通用的更新 signatureList 函数
function updateSignatureList(updates) {
viewer.signatureList.forEach((currentSignature, k) => {
Object.assign(currentSignature, updates);
viewer.signatureList.set(k, currentSignature); // 更新 signatureList
});
}
// 监听签名按钮点击事件
document.getElementById('sign').addEventListener('click', function () {
this.classList.toggle('active');
viewer.isAnnotationLayer = this.classList.contains('active');
if (!viewer.isAnnotationLayer) {
signType.style.display = 'none';
viewer.closeSignLayer();
viewer.isEraser = false;
updateSignatureList({
minWidth: viewer.minLineWidth,
maxWidth: viewer.maxLineWidth,
compositeOperation: 'source-over'
});
} else {
signType.style.display = 'block';
eraserButton.classList.remove('active');
viewer.isEraser = false;
viewer.drawSignLayer();
}
});
// 监听手写按钮点击事件
handButton.addEventListener('click', function () {
viewer.penType = 'touch';
// 更新 signatureList 中的 pointerType
updateSignatureList({pointerType: 'touch'});
this.classList.add('active');
penButton.classList.remove('active');
});
// 监听画笔按钮点击事件
penButton.addEventListener('click', () => {
viewer.penType = 'pen';
// 更新 signatureList 中的 pointerType
updateSignatureList({pointerType: 'pen'});
// 更新按钮状态
penButton.classList.add('active');
handButton.classList.remove('active');
});
// 监听橡皮擦按钮点击事件
eraserButton.addEventListener('click', function () {
this.classList.toggle('active');
const isActive = this.classList.contains('active');
if (isActive) {
viewer.isEraser = true;
// 使用 updateSignatureList 来更新 signatureList
updateSignatureList({
minWidth: 20,
maxWidth: 20,
compositeOperation: 'destination-out'
});
} else {
// 恢复 compositeOperation 为 source-over
updateSignatureList({compositeOperation: 'source-over'});
viewer.isEraser = false;
viewer.updateBrushSize();
}
});
// 遍历每个 .warp 元素并添加点击事件监听
warpElements.forEach(warpElement => {
warpElement.addEventListener('click', function () {
// 移除所有 .warp 元素的 'on' 类并添加 'on' 类到当前点击元素
warpElements.forEach(element => element.classList.remove('on'));
this.classList.add('on');
// 获取当前点击元素的 'data-color' 属性值并更新 viewer 的背景色
viewer.pdfBackgroundColor = this.getAttribute('data-color');
// 调用 viewer 的 setPdfBackgroundColor 方法
viewer.setPdfBackgroundColor(viewer.pdfBackgroundColor);
// 设置 page-container 和 toolbar 的背景颜色
pageContainers.forEach(page => page.style.backgroundColor = viewer.pdfBackgroundColor);
toolbar.style.backgroundColor = viewer.pdfBackgroundColor;
// 调用 viewer 的 dialogTools 方法
viewer.dialogTools('dialog-eye', false);
// 如果需要发送消息,可以启用下面的代码
uni.postMessage({
data: {
type: 'color',
color: viewer.pdfBackgroundColor
}
});
});
});
saveButton.addEventListener('click', function () {
if (saveButton.classList.contains('disabled')) {
return;
}
viewer.savePdfFile();
})
</script>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。