前端pdf-阅读器-3d版

目录

一、基于pdf.js、turnjs4封装的3d翻页效果pdf文件阅读器、pdf文件url拼接地址栏就可以展示、兼容pc端、H5端

二、效果展示图

三、部分源码

四、点赞关注加收藏私信我发源码(记得私信我、发邮箱哈)


一、基于pdf.js、turnjs4封装的3d翻页效果pdf文件阅读器、pdf文件url拼接地址栏就可以展示、兼容pc端、H5端

二、效果展示图

 

三、部分源码

<script>
    /*定义变量参数 */
    // 定义一个空字符串变量用于存储PDF文件的URL
    var pdfurl = "";
    // 获取flipbook元素,该元素将被用来呈现翻页效果
    var flipbook = $("#flipbook");
    // 初始化当前页码为1
    var pageCurrent = 0;
    // 设置书本ID,可以根据需要进行更改
    var bid = 1;
    // 初始化缩放比例和旋转角度为1(即不缩放、不旋转)
    var scale = 1;
    var rotate = 1;
    // 初始化画布宽度和高度为空值,在后续代码中会动态设置这些值
    var canvasWidth = null;
    var canvasHeight = null;

    const getUrlParam = (name) => {
      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
      var r = window.location.search.substring(1).match(reg); //匹配目标参数
      if (r != null) return decodeURI(r[2]);
      return null; //返回参数值
    };

    const isMobile = () => {
      // 检查用户代理是否包含“Mobi”子字符串
      return /Mobi/.test(navigator.userAgent);
    };

    const disableScroll = () => {
      // 获取当前垂直滚动位置
      let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
      // 禁用默认的窗口滚动行为
      const preventDefault = (e) => {
        e.preventDefault();
      };
      // 在触摸设备上,禁用touchmove事件来防止页面滑动。
      document.body.addEventListener("touchmove", preventDefault, {
        passive: false,
      });
      //在非触摸设备上,阻止窗口滚动事件并将其替换为preventDefault函数。
      window.addEventListener("scroll", preventDefault);
      // 将body元素的样式设置为固定,并将其上一个滚动位置应用于它。
      document.body.style.position = "fixed";
      document.body.style.top = -scrollTop + "px";
    };

    const preloadPdf = async (url) => {
      const response = await fetch(url);
      const arrayBuffer = await response.arrayBuffer();
      return pdfjsLib.getDocument(arrayBuffer);
    };

    // 在页面加载时就开始预加载PDF文件
    window.addEventListener("load", async () => {
      if (getUrlParam("pdfurl") != null) {
        pdfurl = getUrlParam("pdfurl");
        getpdf(pdfurl);
        var vConsole = new VConsole();
        disableScroll();
        console.log(pdfurl);
      } else {
        alert("文件为空");
      }
    });

    const getpdf = async (url) => {
      const loadingTask = pdfjsLib.getDocument(url);
      const pdf = await loadingTask.promise;
      // 获取第一页的视图,并根据其宽度设置 flipbook 的宽度
      const firstPage = await pdf.getPage(1);
      const viewport = firstPage.getViewport({ scale: scale });
      const mobieWidth = viewport.width * 2;
      const pcWidth = viewport.width * 2;
      const pdfWidth = isMobile() ? mobieWidth : pcWidth;
      const canvasCache = {};
      // 一次性获取所有页面的canvas对象,并将其缓存起来
      for (let i = 1; i <= pdf.numPages; i++) {
        const id = "canvaspage" + i;
        const div = document.createElement("div");
        div.innerHTML = `<canvas id="${id}" class="page"></canvas>`;
        flipbook.append(div);
        const page = await pdf.getPage(i);
        const canvas = await setcanvas(page, id);
        canvasCache[id] = canvas;
      }
      // 加载turn.js并设置参数
      await new Promise((resolve) => {
        yepnope({
          test: Modernizr.csstransforms,
          yep: ["./JS/turnjs4/lib/turn.js"],
          complete: () => {
            $("#flipbook").turn({
              width: pdfWidth,
              height: viewport.height,
              elevation: 50,
              display: isMobile() ? "single" : "double",
              autoCenter: true,
              duration: 1000,
              gradients: true,
              disable: true,
              // 添加turn.js的turned事件回调函数,用于预加载相邻页面
              // 预加载相邻页面的数量可以根据实际情况调整
              turned: async function (event, page = 1) {
                console.log(event, page, "33333333333333");
                const prevPage = page - 1;
                const nextPage = page + 1;
                // 预加载当前页面的相邻页面
                if (prevPage > 0 && !canvasCache[prevPage]) {
                  const id = "canvaspage" + prevPage;
                  const div = document.createElement("div");
                  div.innerHTML = `<canvas id="${id}" class="page"></canvas>`;
                  flipbook.append(div);
                  const page = await pdf.getPage(prevPage);
                  const canvas = await setcanvas(page, id);
                  canvasCache[prevPage] = canvas;
                }
                if (nextPage <= pdf.numPages && !canvasCache[nextPage]) {
                  const id = "canvaspage" + nextPage;
                  const div = document.createElement("div");
                  div.innerHTML = `<canvas id="${id}" class="page"></canvas>`;
                  flipbook.append(div);
                  const page = await pdf.getPage(nextPage);
                  const canvas = await setcanvas(page, id);
                  canvasCache[nextPage] = canvas;
                }
                // 移除未缓存的旧页面
                const unloadPage = isMobile() ? page + 2 : page + 4;
                const unloadPage2 = isMobile() ? page - 2 : page - 4;
                if (canvasCache[unloadPage]) {
                  const canvas = canvasCache[unloadPage];
                  delete canvasCache[unloadPage];
                  canvas.parentNode.remove();
                }
                if (canvasCache[unloadPage2]) {
                  const canvas = canvasCache[unloadPage2];
                  delete canvasCache[unloadPage2];
                  canvas.parentNode.remove();
                }
              },
            });
            resolve();
          },
        });
      });

      // 预加载所有canvas对象的图像数据
      Object.values(canvasCache).forEach((canvas) => {
        const context = canvas.getContext("2d");
        const imageData = context.getImageData(
          0,
          0,
          canvas.width,
          canvas.height
        );
      });
      // 使用pdf.js库解析PDF文档并返回Promise对象,在解析完成后隐藏遮罩层。
      const response = await fetch(url);
      const arrayBuffer = await response.arrayBuffer();
      const pdfData = new Uint8Array(arrayBuffer);
      await pdfjsLib.getDocument(pdfData).promise;
      $("#overlay").hide();
    };

    const canvasCache = {};

    const setcanvas = async (page, id) => {
      const canvas = document.getElementById(id);
      const canvasRect = canvas.getBoundingClientRect();
      const isVisible =
        canvasRect.bottom > 0 &&
        canvasRect.top < window.innerHeight &&
        canvasRect.right > 0 &&
        canvasRect.left < window.innerWidth;
      if (isVisible) {
        // 如果 canvas 可见,则将其添加到缓存中
        canvasCache[id] = canvas;
      } else {
        // 如果 canvas 不可见,则从缓存中删除它
        delete canvasCache[id];
      }
      if (!canvas) {
        console.log("Canvas element with ID " + id + " not found.");
        return;
      }
      const context = canvas.getContext("2d");
      if (!context) {
        console.log("Could not get 2D context for canvas element.");
        return;
      }
      const viewport = page.getViewport({ scale: scale });
      const screenWidth = Math.min(window.innerWidth, window.innerHeight);
      const newScale = screenWidth / viewport.width;
      const newViewport = page.getViewport({ scale: newScale });
      const outputScale = window.devicePixelRatio;
      canvas.width = Math.floor(newViewport.width * outputScale);
      canvas.height = Math.floor(newViewport.height * outputScale);
      canvas.style.width = "100%";
      canvas.style.height = "100%";
      const transform =
        outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
      const renderContext = {
        canvasContext: context,
        transform: transform,
        viewport: newViewport,
      };
      await page.render(renderContext).promise;
      return canvas;
    };

    $(function () {
      $(".flip_button_left").bind("click", function () {
        $("#flipbook").turn("previous");
      });
      $(".flip_button_right").bind("click", function () {
        $("#flipbook").turn("next");
      });
    });
  </script>

四、点赞关注加收藏私信我发源码(记得私信我、发邮箱哈)

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web_icon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值