响应式网站把pdf文档嵌入canvas
效果图:

(移动端)
(PC端 )
完整代码:
<!DOCTYPE html> <html> <head>
<meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>响应式网站把pdf文档嵌入canvas</title> <meta name="keywords" content=""> <meta name="description" content="">
<style> #prev-page, #next-page,.download { padding: 4px 10px; margin: 2px; font-size: 12px; background-color: #55ae98; color: white!important; border: none; border-radius: 5px; cursor: pointer; } #pdf-canvas { position: relative; max-width: 100%;height: auto; border:1px solid #eee; margin: 20px 0; } .loading { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 16px; color: #55ae98; } #tips { position: absolute; bottom:46px; left:12px; line-height: 1.5; font-size:12px; color:#55ae98; } #prev-page:active, #next-page:active,.download:active { background-color: #449d88; } @media(min-width:992px) { #prev-page, #next-page,.download { padding: 10px 20px; margin: 5px; font-size: 16px; } #prev-page:hover, #next-page:hover,.download:hover { background-color: #449d88; } } </style> </head> <body> <div class="infopage"> <div class="container"> <div class="newsinfo"> <div class="title"> <h1 class="t1">{$article.title}</h1> <div class="t2"> 发布时间:{$article.create_time} 查看次数:{$article.click}次</div> </div> <div class="content"> <div class="position-relative text-center"> <div class="loading">PDF加载中..</div> <canvas id="pdf-canvas"></canvas> <div> <!-- 分页控件 --> <button id="prev-page">上一页</button> <span id="page-num">1</span> / <span id="page-count">0</span> <button id="next-page">下一页</button> <a href="{:get_content_pdfurl($article.content)}" download="{$article.title}.pdf" class="download" title="{$article.title}">下载</a> </div> <div id="tips" class="d-lg-none"> 提示:左右滑动或点击按钮翻页 </div> </div> </div> </div> </div> </div> <script src="jquery.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script> <script> // 初始化变量 let pdfDoc = null, pageNum = 1, pageRendering = false, pageNumPending = null, scale = 1.5; // 缩放比例(根据屏幕调整) // 获取DOM元素 const canvas = document.getElementById('pdf-canvas'), ctx = canvas.getContext('2d'), pageNumEl = document.getElementById('page-num'), pageCountEl = document.getElementById('page-count'), prevBtn = document.getElementById('prev-page'), nextBtn = document.getElementById('next-page'); // 显示loading提示 $('.loading').show(); pdfjsLib.getDocument('pdf链接地址').promise.then(function (pdf) { $('.loading').hide(); pdfDoc = pdf; pageCountEl.textContent = pdf.numPages; // 显示总页数 // 初始渲染第一页 renderPage(pageNum); }); // 渲染指定页 function renderPage(num) { pageRendering = true; pdfDoc.getPage(num).then(function (page) { const viewport = page.getViewport({ scale: scale }); canvas.width = viewport.width; canvas.height = viewport.height; // 渲染PDF页面到Canvas page.render({ canvasContext: ctx, viewport: viewport }).promise.then(function () { pageRendering = false; if (pageNumPending !== null) { renderPage(pageNumPending); // 处理排队中的渲染请求 pageNumPending = null; } }); pageNumEl.textContent = num; // 更新当前页码 }); } // 翻页逻辑 function queueRenderPage(num) { if (pageRendering) { pageNumPending = num; // 如果正在渲染,排队等待 } else { renderPage(num); } } // 上一页按钮事件 prevBtn.addEventListener('click', function () { if (pageNum <= 1) return; pageNum--; queueRenderPage(pageNum); }); // 下一页按钮事件 nextBtn.addEventListener('click', function () { if (pageNum >= pdfDoc.numPages) return; pageNum++; queueRenderPage(pageNum); }); //移动端适配 let touchStartX = 0; canvas.addEventListener('touchstart', (e) => { touchStartX = e.touches[0].clientX; }); canvas.addEventListener('touchend', (e) => { const touchEndX = e.changedTouches[0].clientX; const deltaX = touchStartX - touchEndX; if (deltaX > 50 && pageNum < pdfDoc.numPages) { // 向左滑动:下一页 pageNum++; queueRenderPage(pageNum); } else if (deltaX < -50 && pageNum > 1) { // 向右滑动:上一页 pageNum--; queueRenderPage(pageNum); } }); </script> </body> </html>