pdf 搜索优化
This commit is contained in:
parent
add19a94aa
commit
f341e1822b
|
|
@ -73,7 +73,7 @@ if (resolvedWorkerSrc) {
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc = null
|
pdfjsLib.GlobalWorkerOptions.workerSrc = null
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_SCALE = 1
|
const DEFAULT_SCALE = 1.1
|
||||||
const DEFAULT_PDF_URL = 'http://192.168.0.14:9090/smart-bid/technicalSolutionDatabase/2025/10/30/fe5b46ea37554516a71e7c0c486d3715.pdf'
|
const DEFAULT_PDF_URL = 'http://192.168.0.14:9090/smart-bid/technicalSolutionDatabase/2025/10/30/fe5b46ea37554516a71e7c0c486d3715.pdf'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -867,6 +867,9 @@ export default {
|
||||||
|
|
||||||
this.currentResultIndex = index
|
this.currentResultIndex = index
|
||||||
this.scheduleActiveHighlightRefresh()
|
this.scheduleActiveHighlightRefresh()
|
||||||
|
|
||||||
|
// 等待高亮更新完成
|
||||||
|
await this.$nextTick()
|
||||||
|
|
||||||
const performScroll = () => {
|
const performScroll = () => {
|
||||||
const target = this.searchResults[this.currentResultIndex]?.element
|
const target = this.searchResults[this.currentResultIndex]?.element
|
||||||
|
|
@ -876,24 +879,83 @@ export default {
|
||||||
const container = target.closest('.pdf-page') || target
|
const container = target.closest('.pdf-page') || target
|
||||||
if (!container) return
|
if (!container) return
|
||||||
|
|
||||||
// 不做平滑动画,直接把匹配所在的 pdf-page 翻到可视区域
|
// 手动计算位置并滚动,确保目标元素在视口中可见
|
||||||
if (!useSmoothScroll) {
|
if (!useSmoothScroll) {
|
||||||
|
// 获取目标元素和容器的位置信息
|
||||||
|
const targetRect = target.getBoundingClientRect()
|
||||||
|
const wrapperRect = wrapper.getBoundingClientRect()
|
||||||
|
const containerRect = container.getBoundingClientRect()
|
||||||
|
|
||||||
|
// 计算目标元素相对于 wrapper 的绝对位置
|
||||||
|
const targetTop = container.offsetTop + (targetRect.top - containerRect.top)
|
||||||
|
const targetLeft = container.offsetLeft + (targetRect.left - containerRect.left)
|
||||||
|
const targetHeight = targetRect.height || 20
|
||||||
|
const targetWidth = targetRect.width || 50
|
||||||
|
|
||||||
|
// 计算视口尺寸和边距
|
||||||
|
const viewportHeight = wrapper.clientHeight
|
||||||
|
const viewportWidth = wrapper.clientWidth
|
||||||
|
const verticalPadding = 80 // 上下留出空间
|
||||||
|
const horizontalPadding = 40 // 左右留出空间
|
||||||
|
|
||||||
|
// 垂直滚动:确保目标元素在视口中
|
||||||
|
let scrollTop = wrapper.scrollTop
|
||||||
|
const targetTopInViewport = targetTop - wrapper.scrollTop
|
||||||
|
|
||||||
|
if (targetTopInViewport < verticalPadding) {
|
||||||
|
// 目标元素在视口上方,向上滚动
|
||||||
|
scrollTop = targetTop - verticalPadding
|
||||||
|
} else if (targetTopInViewport + targetHeight > viewportHeight - verticalPadding) {
|
||||||
|
// 目标元素在视口下方,向下滚动
|
||||||
|
scrollTop = targetTop + targetHeight - viewportHeight + verticalPadding
|
||||||
|
}
|
||||||
|
|
||||||
|
// 水平滚动:确保目标元素在视口中(如果 canvas 很宽)
|
||||||
|
let scrollLeft = wrapper.scrollLeft
|
||||||
|
const targetLeftInViewport = targetLeft - wrapper.scrollLeft
|
||||||
|
|
||||||
|
if (targetLeftInViewport < horizontalPadding) {
|
||||||
|
// 目标元素在视口左侧,向左滚动
|
||||||
|
scrollLeft = targetLeft - horizontalPadding
|
||||||
|
} else if (targetLeftInViewport + targetWidth > viewportWidth - horizontalPadding) {
|
||||||
|
// 目标元素在视口右侧,向右滚动
|
||||||
|
scrollLeft = targetLeft + targetWidth - viewportWidth + horizontalPadding
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接跳转到目标位置
|
||||||
this.cancelScrollAnimation()
|
this.cancelScrollAnimation()
|
||||||
wrapper.scrollTop = container.offsetTop
|
wrapper.scrollTop = Math.max(0, Math.min(scrollTop, wrapper.scrollHeight - viewportHeight))
|
||||||
|
wrapper.scrollLeft = Math.max(0, Math.min(scrollLeft, wrapper.scrollWidth - viewportWidth))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 平滑滚动
|
||||||
const wrapperOffsetTop = container.offsetTop
|
const wrapperOffsetTop = container.offsetTop
|
||||||
const containerHeight = container.offsetHeight || target.offsetHeight || 0
|
const containerHeight = container.offsetHeight || target.offsetHeight || 0
|
||||||
const desired = wrapperOffsetTop - Math.max((wrapper.clientHeight - containerHeight) / 2, 0)
|
const desired = wrapperOffsetTop - Math.max((wrapper.clientHeight - containerHeight) / 2, 0)
|
||||||
this.smoothScrollTo(wrapper, desired)
|
this.smoothScrollTo(wrapper, desired)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useSmoothScroll) {
|
// 等待 DOM 更新和元素渲染完成后再滚动
|
||||||
this.$nextTick(() => performScroll())
|
await this.$nextTick()
|
||||||
} else {
|
// 使用双重 requestAnimationFrame 确保元素位置已完全计算
|
||||||
performScroll()
|
requestAnimationFrame(() => {
|
||||||
}
|
requestAnimationFrame(() => {
|
||||||
|
// 再次检查元素是否存在(可能在渲染过程中被更新)
|
||||||
|
const currentTarget = this.searchResults[this.currentResultIndex]?.element
|
||||||
|
if (currentTarget && currentTarget.isConnected) {
|
||||||
|
performScroll()
|
||||||
|
} else {
|
||||||
|
// 如果元素不存在,尝试从 elements 数组中获取
|
||||||
|
const result = this.searchResults[this.currentResultIndex]
|
||||||
|
if (result && result.elements && result.elements.length > 0) {
|
||||||
|
// 更新 element 引用
|
||||||
|
result.element = result.elements[0]
|
||||||
|
performScroll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
applyHighlightsToPage(pageIndex) {
|
applyHighlightsToPage(pageIndex) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue