|
|
@@ -1,6 +1,5 @@
|
|
|
<!DOCTYPE html>
|
|
|
<html lang="zh-CN">
|
|
|
-
|
|
|
<head>
|
|
|
<meta charset="UTF-8">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
@@ -15,6 +14,7 @@
|
|
|
|
|
|
.container {
|
|
|
width: 100%;
|
|
|
+ position: relative;
|
|
|
}
|
|
|
|
|
|
#pdf-container {
|
|
|
@@ -39,23 +39,141 @@
|
|
|
padding: 100px 20px;
|
|
|
text-align: center;
|
|
|
}
|
|
|
+
|
|
|
+ /* ========================
|
|
|
+ 完全还原 uni-loading 4点跳动
|
|
|
+ ======================== */
|
|
|
+ .loading-container {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+ background: #fff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 99999;
|
|
|
+ transition: opacity 0.3s ease;
|
|
|
+ }
|
|
|
+ .loading2 {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ position: relative;
|
|
|
+ -webkit-transform: rotate(10deg);
|
|
|
+ transform: rotate(10deg);
|
|
|
+ }
|
|
|
+ .loading2 .shape {
|
|
|
+ border-radius: 5px;
|
|
|
+ }
|
|
|
+ .loading2 {
|
|
|
+ -webkit-animation: rotation 1s infinite;
|
|
|
+ animation: rotation 1s infinite;
|
|
|
+ }
|
|
|
+ .shape {
|
|
|
+ position: absolute;
|
|
|
+ width: 10px;
|
|
|
+ height: 10px;
|
|
|
+ border-radius: 1px;
|
|
|
+ }
|
|
|
+ .shape.shape1 { left: 0; background-color: #1890FF; }
|
|
|
+ .shape.shape2 { right: 0; background-color: #91CB74; }
|
|
|
+ .shape.shape3 { bottom: 0; background-color: #FAC858; }
|
|
|
+ .shape.shape4 { bottom: 0; right: 0; background-color: #EE6666; }
|
|
|
+
|
|
|
+ .loading2 .shape1 {
|
|
|
+ -webkit-animation: animation2shape1 0.5s ease 0s infinite alternate;
|
|
|
+ animation: animation2shape1 0.5s ease 0s infinite alternate;
|
|
|
+ }
|
|
|
+ @-webkit-keyframes animation2shape1 {
|
|
|
+ from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
|
|
+ to { -webkit-transform: translate(20px, 20px); transform: translate(20px, 20px); }
|
|
|
+ }
|
|
|
+ @keyframes animation2shape1 {
|
|
|
+ from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
|
|
+ to { -webkit-transform: translate(20px, 20px); transform: translate(20px, 20px); }
|
|
|
+ }
|
|
|
+ .loading2 .shape2 {
|
|
|
+ -webkit-animation: animation2shape2 0.5s ease 0s infinite alternate;
|
|
|
+ animation: animation2shape2 0.5s ease 0s infinite alternate;
|
|
|
+ }
|
|
|
+ @-webkit-keyframes animation2shape2 {
|
|
|
+ from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
|
|
+ to { -webkit-transform: translate(-20px, 20px); transform: translate(-20px, 20px); }
|
|
|
+ }
|
|
|
+ @keyframes animation2shape2 {
|
|
|
+ from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
|
|
+ to { -webkit-transform: translate(-20px, 20px); transform: translate(-20px, 20px); }
|
|
|
+ }
|
|
|
+ .loading2 .shape3 {
|
|
|
+ -webkit-animation: animation2shape3 0.5s ease 0s infinite alternate;
|
|
|
+ animation: animation2shape3 0.5s ease 0s infinite alternate;
|
|
|
+ }
|
|
|
+ @-webkit-keyframes animation2shape3 {
|
|
|
+ from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
|
|
+ to { -webkit-transform: translate(20px, -20px); transform: translate(20px, -20px); }
|
|
|
+ }
|
|
|
+ @keyframes animation2shape3 {
|
|
|
+ from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
|
|
+ to { -webkit-transform: translate(20px, -20px); transform: translate(20px, -20px); }
|
|
|
+ }
|
|
|
+ .loading2 .shape4 {
|
|
|
+ -webkit-animation: animation2shape4 0.5s ease 0s infinite alternate;
|
|
|
+ animation: animation2shape4 0.5s ease 0s infinite alternate;
|
|
|
+ }
|
|
|
+ @-webkit-keyframes animation2shape4 {
|
|
|
+ from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
|
|
+ to { -webkit-transform: translate(-20px, -20px); transform: translate(-20px, -20px); }
|
|
|
+ }
|
|
|
+ @keyframes animation2shape4 {
|
|
|
+ from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
|
|
+ to { -webkit-transform: translate(-20px, -20px); transform: translate(-20px, -20px); }
|
|
|
+ }
|
|
|
+
|
|
|
+ @-webkit-keyframes rotation {
|
|
|
+ 0% { transform: rotate(0deg); }
|
|
|
+ 100% { transform: rotate(360deg); }
|
|
|
+ }
|
|
|
+ @keyframes rotation {
|
|
|
+ 0% { transform: rotate(0deg); }
|
|
|
+ 100% { transform: rotate(360deg); }
|
|
|
+ }
|
|
|
</style>
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
- <div class="container">
|
|
|
- <div id="pdf-container">
|
|
|
- <div class="tip">...</div>
|
|
|
+
|
|
|
+ <!-- loading -->
|
|
|
+ <div class="loading-container" id="loading">
|
|
|
+ <div class="loading2">
|
|
|
+ <div class="shape shape1"></div>
|
|
|
+ <div class="shape shape2"></div>
|
|
|
+ <div class="shape shape3"></div>
|
|
|
+ <div class="shape shape4"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
+ <div class="container">
|
|
|
+ <div id="pdf-container"></div>
|
|
|
+ </div>
|
|
|
+
|
|
|
<script src="js/pdf.min.js"></script>
|
|
|
<script>
|
|
|
- pdfjsLib.GlobalWorkerOptions.workerSrc =
|
|
|
- 'js/pdf.worker.min.js'
|
|
|
+ pdfjsLib.GlobalWorkerOptions.workerSrc = 'js/pdf.worker.min.js'
|
|
|
const container = document.getElementById('pdf-container')
|
|
|
let pdfDoc = null
|
|
|
|
|
|
+ // ✅ 立即隐藏 loading(无卡顿)
|
|
|
+ function hideLoading() {
|
|
|
+ const el = document.getElementById('loading')
|
|
|
+ if (el) {
|
|
|
+ el.style.opacity = '0'
|
|
|
+ setTimeout(() => {
|
|
|
+ el.style.display = 'none'
|
|
|
+ }, 300)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 获取URL参数
|
|
|
function getPdfUrl() {
|
|
|
const params = new URLSearchParams(window.location.search)
|
|
|
@@ -80,28 +198,24 @@
|
|
|
// 高清渲染 + 宽度100%自适应
|
|
|
async function renderAllPages() {
|
|
|
container.innerHTML = ''
|
|
|
- const containerWidth = container.clientWidth - 20 // 内边距修正
|
|
|
+ const containerWidth = container.clientWidth - 20
|
|
|
|
|
|
for (let i = 1; i <= pdfDoc.numPages; i++) {
|
|
|
const page = await pdfDoc.getPage(i)
|
|
|
const defaultViewport = page.getViewport({ scale: 1 })
|
|
|
-
|
|
|
- // 自动计算适应宽度的高清比例
|
|
|
const scale = containerWidth / defaultViewport.width
|
|
|
const viewport = page.getViewport({ scale })
|
|
|
|
|
|
const canvas = document.createElement('canvas')
|
|
|
const ctx = canvas.getContext('2d')
|
|
|
-
|
|
|
- // 高清核心:适配设备像素比,永远不模糊
|
|
|
const dpr = window.devicePixelRatio || 1
|
|
|
canvas.width = viewport.width * dpr
|
|
|
canvas.height = viewport.height * dpr
|
|
|
canvas.style.width = "100%"
|
|
|
canvas.style.height = "auto"
|
|
|
ctx.scale(dpr, dpr)
|
|
|
-
|
|
|
canvas.className = 'pdf-page'
|
|
|
+
|
|
|
await page.render({ canvasContext: ctx, viewport }).promise
|
|
|
container.appendChild(canvas)
|
|
|
}
|
|
|
@@ -112,15 +226,21 @@
|
|
|
const pdfUrl = getPdfUrl()
|
|
|
if (!pdfUrl) {
|
|
|
container.innerHTML = '<div class="tip"></div>'
|
|
|
+ hideLoading()
|
|
|
return
|
|
|
}
|
|
|
try {
|
|
|
const blob = await loadPdfAsBlob(pdfUrl)
|
|
|
const blobUrl = URL.createObjectURL(blob)
|
|
|
+
|
|
|
+ // ✅ PDF 加载完成 立即隐藏 loading
|
|
|
pdfDoc = await pdfjsLib.getDocument(blobUrl).promise
|
|
|
+ hideLoading() // 👈 这里提前关,绝不卡顿
|
|
|
+
|
|
|
await renderAllPages()
|
|
|
} catch (e) {
|
|
|
container.innerHTML = '<div class="tip">PDF 加载失败</div>'
|
|
|
+ hideLoading()
|
|
|
console.error(e)
|
|
|
}
|
|
|
}
|