From 5ac96e1f9f045fa77ad02e39d7de79bcff914a0d Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Mon, 10 Nov 2025 15:35:58 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=8A=A0=E8=BD=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/common/DocumentSearch.vue | 65 +++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/src/views/common/DocumentSearch.vue b/src/views/common/DocumentSearch.vue index 3dfea02..81bf3ff 100644 --- a/src/views/common/DocumentSearch.vue +++ b/src/views/common/DocumentSearch.vue @@ -247,6 +247,12 @@ export default { if (this.$refs.pdfWrapper && !this.$refs.pdfWrapper.style.minWidth) { this.$refs.pdfWrapper.style.minWidth = `${Math.ceil(viewport.width)}px` } + + if (!container.querySelector('.page-loader')) { + const loader = document.createElement('div') + loader.className = 'page-loader' + container.appendChild(loader) + } }, async ensurePageCached(pageNumber) { @@ -324,10 +330,12 @@ export default { const viewport = page.getViewport({ scale: this.scale }) this.ensureContainerDimensions(pageNumber, viewport) + container.classList.add('is-loading-text') const existing = container.querySelector('.textLayer') if (existing && !force && this.pageTextDivs[index]?.length) { existing.style.display = '' + container.classList.remove('is-loading-text') return } if (existing) { @@ -359,6 +367,8 @@ export default { this.pageTextDivs[index] = textDivs } catch (error) { console.warn(`加载第 ${pageNumber} 页文本失败`, error) + } finally { + container.classList.remove('is-loading-text') } if (container.dataset.status !== 'rendered') { @@ -370,8 +380,20 @@ export default { }, async renderSinglePage(pageNumber) { - await this.renderCanvas(pageNumber) - await this.renderTextLayer(pageNumber, { visible: true, force: true }) + const container = this.pageContainers[pageNumber - 1] + if (container) { + container.classList.add('is-loading', 'is-loading-text') + this.renderingSet.add(pageNumber) + } + try { + await this.renderTextLayer(pageNumber, { visible: true, force: true }) + await this.renderCanvas(pageNumber) + } finally { + if (container) { + container.classList.remove('is-loading', 'is-loading-text') + } + this.renderingSet.delete(pageNumber) + } }, scheduleRender(pageNumber, { priority = false } = {}) { @@ -852,23 +874,9 @@ export default { -webkit-user-select: text; } -.pdf-page.is-loading::before { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: 48px; - height: 48px; - margin: -24px 0 0 -24px; - border-radius: 50%; - border: 4px solid rgba(86, 119, 196, 0.25); - border-top-color: rgba(86, 119, 196, 0.9); - animation: pdf-page-spin 0.9s linear infinite; - z-index: 5; -} - .pdf-page.is-loading::after { opacity: 0.5; + background: rgba(255, 255, 255, 0.7); } .pdf-page.is-loading .textLayer, @@ -876,6 +884,29 @@ export default { opacity: 0.35; } +.pdf-page .page-loader { + position: absolute; + top: 50%; + left: 50%; + width: 36px; + height: 36px; + margin: -18px 0 0 -18px; + border-radius: 50%; + display: none; + background: + radial-gradient(circle closest-side, rgba(140, 148, 160, 0.85) 92%, transparent 100%) top center/6px 6px no-repeat, + conic-gradient(from 0deg, rgba(140, 148, 160, 0.85) 0deg 30deg, rgba(140, 148, 160, 0.1) 30deg 360deg); + -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 6px)); + mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 6px)); + animation: pdf-page-spin 1s steps(12) infinite; + z-index: 6; +} + +.pdf-page.is-loading .page-loader, +.pdf-page.is-loading-text .page-loader { + display: block; +} + @keyframes pdf-page-spin { 0% { transform: rotate(0deg);