如何在pdf.js渲染的Canvas显示前添加自定义文本?
问题原因与解决方案
问题根源
- canvas无法嵌套HTML元素:canvas是独立的位图绘制容器,它内部不能直接放置div、span等HTML元素,浏览器只会渲染canvas自身的绘制内容,忽略其DOM子节点。
- 文本被PDF渲染覆盖:pdf.js渲染PDF页面时,会对canvas的上下文进行全区域的像素重绘(比如通过
drawImage绘制PDF的光栅数据),如果先调用fillText画文本,后续的PDF渲染会完全覆盖这些像素,导致文本不可见。
可行解决方法
1. 调整绘制顺序:先渲染PDF,再叠加文本
把自定义文本的绘制逻辑放在PDF渲染完成的回调中,确保文本绘制在PDF内容之上:
function renderPage(page) { const viewport = page.getViewport({ scale: 1.5 }); const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; // 先渲染PDF page.render({ canvasContext: ctx, viewport: viewport }).promise.then(() => { // PDF渲染完成后绘制文本 ctx.fillStyle = '#ff0000'; ctx.font = '24px sans-serif'; ctx.fillText('Hello World', 50, 50); // 调整坐标控制文本位置 }); document.body.appendChild(canvas); }
2. 用容器包裹canvas,叠加HTML文本元素
不需要修改canvas,给每个canvas套一个相对定位的容器,再在容器内添加绝对定位的文本元素,实现文本与PDF内容的视觉叠加:
function renderPage(page) { const viewport = page.getViewport({ scale: 1.5 }); const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; // 创建容器并设置定位 const container = document.createElement('div'); container.style.position = 'relative'; container.style.display = 'block'; container.style.marginBottom = '10px'; // 创建文本元素 const textEl = document.createElement('span'); textEl.textContent = 'Hello World'; textEl.style.position = 'absolute'; textEl.style.top = '50px'; textEl.style.left = '50px'; textEl.style.color = 'red'; textEl.style.fontSize = '24px'; // 渲染PDF并组装容器 page.render({ canvasContext: ctx, viewport }).promise.then(() => { container.appendChild(canvas); container.appendChild(textEl); document.body.appendChild(container); }); }
3. 将canvas转为图片后再编辑(适合静态导出场景)
如果需要生成带文本的静态内容,可以先把渲染好的PDF canvas转为图片,再绘制到新canvas上并添加文本:
function renderPage(page) { const viewport = page.getViewport({ scale: 1.5 }); const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; page.render({ canvasContext: ctx, viewport }).promise.then(() => { // 将PDF canvas转为图片 const pdfImg = new Image(); pdfImg.src = canvas.toDataURL('image/png'); pdfImg.onload = () => { // 创建新canvas const finalCanvas = document.createElement('canvas'); const finalCtx = finalCanvas.getContext('2d'); finalCanvas.width = canvas.width; finalCanvas.height = canvas.height; // 绘制PDF图片 finalCtx.drawImage(pdfImg, 0, 0); // 绘制自定义文本 finalCtx.fillStyle = 'red'; finalCtx.font = '24px Arial'; finalCtx.fillText('Hello World', 50, 50); document.body.appendChild(finalCanvas); }; }); }
内容的提问来源于stack exchange,提问作者Mastas
相关产品推荐
相关产品推荐

