前端快照,生成截图,前端拍照功能的实现

项目中要实现下载dom的快照,或者生产截图,可以使用html2canvas 这个库,

npm install --save html2canvas

封装成类可以在任何项目中使用

import html2canvas from "html2canvas";
class ImageSnapshot {
  constructor(dom, url) {
    this.dom = dom;
    this.url = url;
    this.loadingMessage = null; // 用于存储加载提示信息的 DOM 元素
  }

  handleDown() {
    this.showLoadingMessage(); // 显示加载提示信息

    // 转换传递过来的图片为 base64
    this.convertImageToBase64(this.url)
      .then((base64) => {
        // 找到所有 img 元素并设置 src 为 base64
        let images = this.dom.querySelectorAll("img");
        images.forEach((img) => {
          img.src = base64;
        });

        return html2canvas(this.dom, {
          useCORS: true,
          backgroundColor: "#002F4F", // 设置背景颜色为 #002F4F
          logging: true,
          onclone: (clonedDoc) => {
            // 处理克隆文档中的 SVG 元素或其他可能的问题
            let svgElements = clonedDoc.querySelectorAll("svg");
            svgElements.forEach((svg) => {
              let transform = svg.getAttribute("transform");
              if (transform) {
                svg.setAttribute(
                  "transform",
                  transform.replace(/rotate\(NaN\)/g, "")
                );
              }
            });
          },
        });
      })
      .then((canvas) => {
        // 创建链接元素
        const link = document.createElement("a");

        // 将 canvas 转换为 Blob 对象
        canvas.toBlob((blob) => {
          if (blob) {
            // 设置链接地址为生成的 Blob 对象 URL
            link.href = URL.createObjectURL(blob);

            // 设置下载的文件名和类型
            link.download = `snapshot_${Date.now().toString()}.png`;

            // 模拟点击下载链接
            link.dispatchEvent(new MouseEvent("click"));

            this.hideLoadingMessage(); // 隐藏加载提示信息
          } else {
            console.error("Canvas to Blob conversion failed.");
            this.hideLoadingMessage(); // 隐藏加载提示信息
          }
        }, "image/png");
      })
      .catch((error) => {
        console.error("html2canvas error:", error);
        this.handleImageError(); // 调用错误处理方法
        this.hideLoadingMessage(); // 隐藏加载提示信息
      });
  }

  convertImageToBase64(url) {
    return new Promise((resolve, reject) => {
      let img = new Image();
      img.crossOrigin = "Anonymous";
      img.onload = function () {
        let canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
        let ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);
        resolve(canvas.toDataURL("image/png"));
      };
      img.onerror = reject;
      img.src = url;
    });
  }

  handleImageError() {
    // 创建一个提示信息元素
    let errorMessage = document.createElement("div");
    errorMessage.textContent = "图片加载失败,请检查网络连接或图片地址。";
    errorMessage.style.color = "red";
    errorMessage.style.position = "absolute";
    errorMessage.style.top = "10px";
    errorMessage.style.left = "10px";
    errorMessage.style.backgroundColor = "white";
    errorMessage.style.padding = "5px";
    errorMessage.style.border = "1px solid red";

    // 将提示信息元素添加到 dom 中
    this.dom.appendChild(errorMessage);

    // 使用 html2canvas 捕获不含图片的 dom
    html2canvas(this.dom, {
      useCORS: true,
      backgroundColor: "#002F4F", // 设置背景颜色为 #002F4F
      logging: true,
    })
    .then((canvas) => {
      const link = document.createElement("a");
      canvas.toBlob((blob) => {
        if (blob) {
          link.href = URL.createObjectURL(blob);
          link.download = `snapshot_${Date.now().toString()}.png`;
          link.dispatchEvent(new MouseEvent("click"));

          this.hideLoadingMessage(); // 隐藏加载提示信息
        } else {
          console.error("Canvas to Blob conversion failed.");
          this.hideLoadingMessage(); // 隐藏加载提示信息
        }
      }, "image/png");
    })
    .catch((error) => {
      console.error("html2canvas error during fallback:", error);
      this.hideLoadingMessage(); // 隐藏加载提示信息
    });
  }

  showLoadingMessage() {
    // 创建一个加载提示信息元素
    this.loadingMessage = document.createElement("div");
    this.loadingMessage.textContent = "正在生成快照,请稍候...";
    this.loadingMessage.style.color = "blue";
    this.loadingMessage.style.position = "absolute";
    this.loadingMessage.style.top = "10px";
    this.loadingMessage.style.left = "10px";
    this.loadingMessage.style.backgroundColor = "white";
    this.loadingMessage.style.padding = "5px";
    this.loadingMessage.style.border = "1px solid blue";

    // 将加载提示信息元素添加到 dom 中
    this.dom.appendChild(this.loadingMessage);
  }

  hideLoadingMessage() {
    // 移除加载提示信息元素
    if (this.loadingMessage) {
      this.dom.removeChild(this.loadingMessage);
      this.loadingMessage = null;
    }
  }
}

// 导出 ImageSnapshot 类
export default ImageSnapshot;

// 使用示例
// const domElement = document.querySelector(".dialogWrap");
// const imageUrl = 'https://example.com/image.png';
// const snapshot = new ImageSnapshot(domElement, imageUrl);
// snapshot.handleDown();

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码农六六

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

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

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

打赏作者

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

抵扣说明:

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

余额充值