响应式网站把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}&emsp;查看次数:{$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>

 

posted @ 2025-06-04 10:59  枫落曳  阅读(17)  评论(0)    收藏  举报