微信小程序-Wxml2canvas生成图片

使用前注意点:(若不添加,则无法渲染到canvas中)以下是我未注意踩到的坑:
1、当使用image时,一定要在image标签上添加data-type与data-url属性;
2、当使用文本时,一定要在文本标签上添加data-type与data-text属性;
3、若节点中的图片存在缩放,目前(v1.0.1)暂时对css3中的scale还不够友好,建议将计算好的放大倍数直接与目标图片的宽高相乘计算;
4、如果想通过id获取canvas的节点属性,一定要在设置canvas-id的同时也要设置id,目前我通过wx.createSelectorQuery.select(“canvas-id”)无法获取到想要的结果;select方法最好是选择id值;
5、data-delay:标签属性,用于控制渲染节点的顺序;

官方wxml2canvas文档地址:https://www.npmjs.com/package/wxml2canvas

指定节点生成图片并下载到本地:

npm i wxml2canvas

之后打开微信开发者中选择工具项—选择构建npm;(否则无法在小程序环境中使用)

import wxml2canvas from "wxml2canvas";
wxml:
<canvas canvas-id="myCanvas" id="canvasId"></canvas>
<view id="my-canvas" class="my_canvas>
    <view class="header draw_pnode">
    	<!-- data-delay: 可以控制节点渲染的层级 -->
        <image class="headerImg draw_cnode" src="{{order.headerImg}}" data-type="image" data-url="{{order.headerImg}}" data-delay={{1}}></image>
        <text class="headerTitle draw_cnode" data-type="text" data-text="您的订单详情">您的订单详情</text>
    </view>
</view>
划重点:我现在的目标是绘制class="headerImg"下的所有节点信息,注意每个节点标签上的类名;后面会提到;
js:
获取canvas的宽高后开始绘制
  drawMyCanvas() {
    wx.showLoading();
    const that = this;
    const query = wx.createSelectorQuery().in(this);
    query
      .select("#canvasId")
      .fields({
        // 选择需要生成canvas的范围
        size: true,
        node: true, // 获取节点信息
      })
      .exec((data) => {
        let cvsWidth = data.width;
        let cvsHeight = data.height;
        that.setData({
          cvsWidth,
          cvsHeight,
        });
        setTimeout(() => {
          that.startDraw();
        }, 500);
      });
  },
开始绘制canvas画布并保存图片
startDraw() {
    let that = this;
    // 创建wxml2canvas对象
    let drawMyImage = new Wxml2Canvas(
      {
        element: "canvasId", // canvas的id,
        obj: that, // 传入当前组件的this
        width: that.data.width, // canvas画布宽度
        height: that.data.height, // canvas画布高度
        background: "#fff", // 生成图片的背景色
        progress(percent) {
          // 进度
          // console.log(percent);
        },
        finish(url) {
          // 生成的图片
          wx.hideLoading();
          that.savePoster(url);
        },
        error(res) {
          // 失败原因
          console.log(res);
          wx.hideLoading();
        },
      },
      this
    );
    let data = {
      // 获取wxml数据
      list: [
        {
          type: "wxml",
          class: ".draw_pnode .draw_node", // draw_pnode要绘制的wxml元素根类名, draw_node单个元素的类名(所有要绘制的单个元素都要添加该类名)
          limit: ".draw_pnode", // 要绘制的wxml元素根类名,也就是指定要绘制哪些父级中的元素
          x: 0,
          y: 0,
        },
        {
          type: "text",
          text: "添加你需要的文案",
          delay: true, // 延迟渲染,确保渲染在别的节点上方
          x: 40, // 相对于画布的x轴位置
          y: 275, // 相对于画布的y轴位置
          style: {
            fontSize: 14,
            lineHeight: 20,
            fontFamily: "PingFangSC-Regular",
          },
        }
      ],
    };
    // 绘制canvas
    drawMyImage.draw(data, this);
  },

属性解读:
class: “.draw_pnode .draw_node”:draw_pnode 要绘制的wxml元素根类名, draw_node单个元素的类名(所有要绘制的单个元素都要添加该类名)

保存图片并请求用户授权
savePoster(url) {
    const that = this;
    wx.saveImageToPhotosAlbum({
      filePath: url,
      success: function () {
        wx.showToast({
          title: "保存成功",
          icon: "none",
          duration: 1500,
        });
      },
      fail(err) {
        if (
          err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
          err.errMsg === "saveImageToPhotosAlbum:fail auth deny" ||
          err.errMsg === "saveImageToPhotosAlbum:fail authorize no response"
        ) {
          wx.showModal({
            title: "提示",
            content: "需要您授权保存相册",
            showCancel: false,
            success: (modalSuccess) => {
              wx.openSetting({
                success(settingdata) {
                  if (settingdata.authSetting["scope.writePhotosAlbum"]) {
                    wx.saveImageToPhotosAlbum({
                      filePath: that.data.imgUrl,
                      success: function () {
                        wx.showToast({
                          title: "保存成功",
                          icon: "success",
                          duration: 2000,
                        });
                      },
                    });
                  } else {
                    wx.showToast({
                      title: "授权失败,请稍后重新获取",
                      icon: "none",
                      duration: 1500,
                    });
                  }
                },
              });
            },
          });
        }
      },
    });
  },
   /**
   * 获取用户保存相册权限
   */
  getPhotosAuthorize: function () {
    let self = this;
    wx.getSetting({
      success(res) {
        console.log(res);
        if (!res.authSetting["scope.writePhotosAlbum"]) {
          wx.authorize({
            scope: "scope.writePhotosAlbum",
            success() {
              console.log("授权成功");
              self.saveImg();
            },
            //用户拒绝
            fail() {
              console.log("用户再次拒绝");
            },
          });
        } else {
          self.saveImg();
        }
      },
    });
  },
   /**
   * 保存到相册
   */
  async saveImg() {
    let self = this;
    const query = wx.createSelectorQuery();
    const canvasObj = await new Promise((resolve, reject) => {
      query
        .select("#canvasId")
        .fields({ node: true, size: true })
        .exec(async (res) => {
          resolve(res[0].node);
        });
    });
    console.log(canvasObj);
    wx.canvasToTempFilePath(
      {
        //fileType: 'jpg',
        //canvasId: 'posterCanvas', //之前的写法
        canvas: canvasObj, //现在的写法
        success: (res) => {
          console.log(res);
          self.setData({ canClose: true });
          //保存图片
          wx.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            success: function (data) {
              wx.showToast({
                title: "已保存到相册",
                icon: "success",
                duration: 2000,
              });
            fail: function (err) {
              console.log(err);
              if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
                console.log("当初用户拒绝,再次发起授权");
              } else {
                util.showToast("请截屏保存");
              }
            },
            complete(res) {
              wx.hideLoading();
              console.log(res);
            },
          });
        },
        fail(res) {
          console.log(res);
        },
      },
      this
    );
  },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

折木泛舟

我干了,你们随意。

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

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

打赏作者

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

抵扣说明:

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

余额充值