基于pdfjs与PDFObject实现PDF指定文本动态高亮及标注tooltip方案咨询
基于PDF.js+PDFObject的文本高亮+自定义Tooltip实现方案
核心实现逻辑
你已经持有待标注文本的索引位置,无需额外做文本搜索匹配,直接复用PDF.js内置的标注层能力即可实现和HTML预览器一致的效果,整体逻辑和你现有HTML标注方案对齐,仅需要新增文本坐标获取、坐标转换两个环节。
可直接复用的实现代码
// 提前定义你的标注列表,可直接代入你已有的索引、tooltip内容数据 const customAnnotations = [ { pageIndex: 0, // PDF页码,从0开始计数 startCharIndex: 151, // 你已掌握的文本起始索引 endCharIndex: 169, // 你已掌握的文本结束索引 tooltipContent: `<table class='tooltiptable'>....</table>` // 自定义HTML格式的tooltip内容 } ] // 监听PDF.js页面渲染完成事件,逐页处理标注 document.addEventListener('pagerendered', async (e) => { const currentPageIndex = e.detail.pageNumber - 1 const currentPdfPage = e.detail.page const annotationLayer = e.detail.annotationLayer const currentPageAnnotations = customAnnotations.filter(ann => ann.pageIndex === currentPageIndex) // 1. 获取当前页所有文本块数据 const textContent = await currentPdfPage.getTextContent() const textItems = textContent.items let currentPageCharCount = 0 currentPageAnnotations.forEach(ann => { const matchedTextItems = [] // 2. 匹配索引范围内的文本块 for (let i = 0; i < textItems.length; i++) { const item = textItems[i] const itemCharLength = item.str.length const itemStartIdx = currentPageCharCount const itemEndIdx = currentPageCharCount + itemCharLength - 1 if (itemEndIdx < ann.startCharIndex) { currentPageCharCount += itemCharLength continue } if (itemStartIdx > ann.endCharIndex) break matchedTextItems.push(item) currentPageCharCount += itemCharLength if (itemEndIdx >= ann.endCharIndex) break } // 3. 转换坐标并渲染高亮元素 const viewport = currentPdfPage.getViewport({ scale: e.detail.viewport.scale }) matchedTextItems.forEach(item => { // 从文本块属性提取坐标参数:[x轴缩放, x轴倾斜, y轴倾斜, y轴缩放, x坐标, y坐标] const [scaleX, , , scaleY, x, y] = item.transform const itemWidth = item.str.length * scaleX const itemHeight = scaleY // 创建高亮DOM,参数和你现有HTML标注完全对齐 const highlightEl = document.createElement('div') highlightEl.className = 'marked hilite-on symp' highlightEl.setAttribute('data-toggle', 'tooltip') highlightEl.setAttribute('data-placement', 'bottom') highlightEl.setAttribute('data-html', 'true') highlightEl.setAttribute('data-original-title', ann.tooltipContent) // 适配PDF坐标系设置位置 highlightEl.style.cssText = ` position: absolute; left: ${x}px; top: ${viewport.height - y - itemHeight}px; width: ${itemWidth}px; height: ${itemHeight}px; background: rgba(255,255,0,0.3); pointer-events: auto; ` annotationLayer.appendChild(highlightEl) }) }) // 4. 初始化tooltip,和你现有HTML场景的逻辑完全一致 $('[data-toggle="tooltip"]').tooltip({html: true}) })
注意事项
- PDF.js默认坐标系原点为页面左下角,HTML页面坐标系原点为左上角,计算高亮元素top值时需要做对应转换,避免标注偏移
- 如果你的预览器支持缩放功能,需要监听PDF缩放事件,同步重新计算所有高亮元素的坐标即可适配
- 你现有HTML场景下的Tooltip样式、交互逻辑可直接复用,只需确保Tooltip的z-index层级高于PDF预览层即可正常展示
内容的提问来源于stack exchange,提问作者Daniel Cosio
相关产品推荐
相关产品推荐

