小程序截图功能uniapp+vue3

1,784 阅读1分钟
1.获取systemInfo
const systemInfo = uni.getSystemInfoSync();
2.需要截图的元素列表
const resultList = [
    { id: 1, z-index: 0, url: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png' },
    { id: 2, z-index: 10, url: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png' },
    { id: 3, z-index: 20, url: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png' },
    { id: 4, z-index: -1, url: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png' },
];
resultList.sort((a, b) => a.z_index - b.z_index);
3.使用canvas把所有元素统一截图保存
const drawCanvas = () => {
  const dpr = systemInfo.pixelRatio;
  console.log("systemInfo.pixelRatio", systemInfo.pixelRatio);
  // 获取canvas
  const query = wx.createSelectorQuery();
  query
    .select("#canvas-container")
    .fields({
      node: true,
      size: true,
    })
    .exec((res) => {
      const canvas = res[0].node;
      // 小程序版本现在只支持canvas2d,不能使用老版canvas截图了
      const ctx = canvas.getContext("2d");
      // 保存的截图宽高
      res[0].node.width = 216 * dpr;
      res[0].node.height = 384 * dpr;

      // 定义一个异步函数来处理每个元素
      async function processItem(item: any) {
        return new Promise((resolve) => {
          console.log("forEach", item.type);
          const img = canvas.createImage();
          img.src = item.url;
          img.onload = () => {
            console.log("类型", item.type);
            // 先保存一下设置
            ctx.save();
            // 最后画出来
            ctx.drawImage(
              img,
              item.x ? item.x * dpr : 0,
              item.y ? item.y * dpr : 0,
              item.width * dpr,
              item.height * dpr
            );
            // 不要忘记恢复之前的设置
            ctx.restore();
            resolve(true);
          };
          img.onerror = (err) => {
            console.log("onerror", err);
            resolve(true);
          };
        });
      }

      // 使用async函数来包裹整个循环
      async function processItems(arr) {
        for (const item of arr) {
          await processItem(item); // 等待当前异步操作完成
        }
      }

      // 调用函数
      processItems(resultList)
        .then(() => {
          console.log("All items processed.");
          // canvas转文件的临时路径 (本地路径)
          wx.canvasToTempFilePath({
            x: 0,
            y: 0,
            width: 216,
            height: 384,
            destWidth: 216 * dpr,
            destHeight: 384 * dpr,
            canvas,
            fileType: "jpg",
            quality: 1,
            success: (res) => {
              console.log("res.tempFilePath", res);
              // 将canvas图片上传到阿里oss云服务器(有接口就调用后端接口上传图片)
              uploadFileToOSS(res.tempFilePath, resultList);
            },
            fail: (err) => {
              console.log("err", err);
              uni.hideLoading();
            },
          });
        })
        .catch((error) => {
          console.error("Error processing items:", error);
          uni.hideLoading();
        });
    });
};
drawCanvas();
4.官方插件 wxml-to-canvas

如果想要使用截图库可以使用这个插件,只不过可能会有一些坑(比如不是原生小程序开发,使用uniapp的时候)。这个文章可以解决一部分问题:wxml-to-canvas使用过坑记录