优化pdf 搜索

This commit is contained in:
cwchen 2025-11-28 10:33:29 +08:00
parent 4aa85dbf7b
commit f5ae85453c
1 changed files with 174 additions and 2 deletions

View File

@ -362,13 +362,18 @@ export default {
const viewport = page.getViewport({ scale: this.scale }) const viewport = page.getViewport({ scale: this.scale })
// viewport // viewport
this.ensureContainerDimensions(pageNumber, viewport, true) this.ensureContainerDimensions(pageNumber, viewport, true)
container.classList.add('is-loading')
// canvas
const oldCanvas = container.querySelector('.pdf-canvas') const oldCanvas = container.querySelector('.pdf-canvas')
if (oldCanvas) { if (oldCanvas) {
oldCanvas.remove() oldCanvas.remove()
} }
// is-loading loading
container.classList.add('is-loading')
// loading
this.showPageLoading(container)
const canvas = document.createElement('canvas') const canvas = document.createElement('canvas')
canvas.className = 'pdf-canvas' canvas.className = 'pdf-canvas'
const deviceScale = window.devicePixelRatio || 1 const deviceScale = window.devicePixelRatio || 1
@ -405,6 +410,8 @@ export default {
this.renderedPages.set(pageNumber, { container, viewport }) this.renderedPages.set(pageNumber, { container, viewport })
container.classList.remove('is-loading') container.classList.remove('is-loading')
// canvas loading
this.hidePageLoading(container)
return { page, viewport, container } return { page, viewport, container }
}, },
@ -475,6 +482,8 @@ export default {
const container = this.pageContainers[pageNumber - 1] const container = this.pageContainers[pageNumber - 1]
if (container) { if (container) {
container.classList.add('is-loading', 'is-loading-text') container.classList.add('is-loading', 'is-loading-text')
// loading
this.showPageLoading(container)
} }
try { try {
await this.renderTextLayer(pageNumber, { visible: true, force: true }) await this.renderTextLayer(pageNumber, { visible: true, force: true })
@ -489,6 +498,13 @@ export default {
scheduleRender(pageNumber, { priority = false } = {}) { scheduleRender(pageNumber, { priority = false } = {}) {
if (!pageNumber || pageNumber > this.totalPages || this.renderedPages.has(pageNumber)) return if (!pageNumber || pageNumber > this.totalPages || this.renderedPages.has(pageNumber)) return
if (this.renderQueue.includes(pageNumber)) return if (this.renderQueue.includes(pageNumber)) return
// loading
const container = this.pageContainers[pageNumber - 1]
if (container && !container.querySelector('.pdf-canvas')) {
this.showPageLoading(container)
}
if (priority) { if (priority) {
this.renderQueue.unshift(pageNumber) this.renderQueue.unshift(pageNumber)
} else { } else {
@ -1146,6 +1162,11 @@ export default {
if (entry.isIntersecting) { if (entry.isIntersecting) {
const page = Number(entry.target.dataset.page) const page = Number(entry.target.dataset.page)
if (page) { if (page) {
const container = entry.target
// loading
if (!this.renderedPages.has(page) && !container.querySelector('.pdf-canvas')) {
this.showPageLoading(container)
}
this.renderTextLayer(page, { visible: true, force: true }) this.renderTextLayer(page, { visible: true, force: true })
this.scheduleRender(page, { priority: true }) this.scheduleRender(page, { priority: true })
} }
@ -1180,6 +1201,127 @@ export default {
}) })
}, },
showPageLoading(container) {
if (!container) return
const pageNumber = Number(container.dataset.page)
// loading
if (pageNumber && this.renderedPages.has(pageNumber)) {
return
}
// canvas loading
const existingCanvas = container.querySelector('.pdf-canvas')
if (existingCanvas) {
return
}
// loading
const existingLoading = container.querySelector('.page-loading-wrapper')
if (existingLoading && getComputedStyle(existingLoading).display !== 'none') {
return
}
//
const containerHeight = container.offsetHeight || parseInt(container.style.height) || 0
const containerWidth = container.offsetWidth || parseInt(container.style.width) || 0
if (containerHeight < 100 || containerWidth < 100) {
// viewport
if (this.pageCache.has(pageNumber)) {
try {
const page = this.pageCache.get(pageNumber)
const viewport = page.getViewport({ scale: this.scale })
container.style.width = `${viewport.width}px`
container.style.height = `${viewport.height}px`
} catch (e) {
//
if (!container.style.width) container.style.width = '800px'
if (!container.style.height) container.style.minHeight = '1000px'
}
} else {
//
if (!container.style.width) container.style.width = '800px'
if (!container.style.height) container.style.minHeight = '1000px'
}
}
// relative
if (getComputedStyle(container).position === 'static') {
container.style.position = 'relative'
}
// loading
let loadingWrapper = container.querySelector('.page-loading-wrapper')
if (!loadingWrapper) {
loadingWrapper = document.createElement('div')
loadingWrapper.className = 'page-loading-wrapper'
const loadingIcon = document.createElement('i')
loadingIcon.className = 'el-icon-loading page-loading-icon'
loadingWrapper.appendChild(loadingIcon)
container.appendChild(loadingWrapper)
} else {
//
let loadingIcon = loadingWrapper.querySelector('.page-loading-icon')
if (!loadingIcon) {
loadingIcon = document.createElement('i')
loadingIcon.className = 'el-icon-loading page-loading-icon'
loadingWrapper.appendChild(loadingIcon)
}
}
// -
loadingWrapper.style.cssText = `
position: absolute !important;
top: 33% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
z-index: 1000 !important;
display: flex !important;
visibility: visible !important;
opacity: 1 !important;
align-items: center !important;
justify-content: center !important;
pointer-events: none !important;
`
//
const icon = loadingWrapper.querySelector('.page-loading-icon')
if (icon) {
icon.style.cssText = `
font-size: 24px !important;
color: #909399 !important;
display: block !important;
animation: pdf-page-spin 1s linear infinite !important;
`
}
// 使 requestAnimationFrame
this.$nextTick(() => {
requestAnimationFrame(() => {
if (loadingWrapper && loadingWrapper.parentNode) {
//
void loadingWrapper.offsetHeight
//
if (icon) {
//
icon.style.animation = 'none'
void icon.offsetHeight
icon.style.setProperty('animation', 'pdf-page-spin 1s linear infinite', 'important')
}
}
})
})
},
hidePageLoading(container) {
if (!container) return
const loadingWrapper = container.querySelector('.page-loading-wrapper')
if (loadingWrapper) {
loadingWrapper.style.setProperty('display', 'none', 'important')
}
},
disconnectObserver() { disconnectObserver() {
if (this.observer) { if (this.observer) {
this.observer.disconnect() this.observer.disconnect()
@ -1464,6 +1606,36 @@ export default {
letter-spacing: 0.4px; letter-spacing: 0.4px;
} }
.page-loading-wrapper {
position: absolute;
top: 33%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
display: none;
pointer-events: none;
visibility: visible;
opacity: 1;
align-items: center;
justify-content: center;
}
.page-loading-icon {
font-size: 24px;
color: #909399;
animation: pdf-page-spin 1s linear infinite;
}
.pdf-page.placeholder .page-loading-wrapper,
.pdf-page.prefetched .page-loading-wrapper,
.pdf-page.is-loading .page-loading-wrapper,
.pdf-page[data-status="placeholder"] .page-loading-wrapper,
.pdf-page[data-status="prefetched"] .page-loading-wrapper,
.pdf-page[data-status="text-ready"] .page-loading-wrapper,
.pdf-page .page-loading-wrapper[style*="display: flex"] {
display: flex !important;
}
.pdf-canvas { .pdf-canvas {
width: 100%; width: 100%;
display: block; display: block;