收藏
回答

canvas 2d发布线上后,出现部分无法生成的情况?

将老方式的生成海报修改为canvas 2d,在模拟器以及公司的真机都生成没问题,发布上线后,出现好多用户反馈,无法生成海报的情况,能联系的机型包括:iphone 11,华为鸿蒙系统2.0(微信8.0.19),iphone 12max, iphone 13, 华为p40,华为mate40pro,iphone 12, 华为mate 3pro等

是canvas 2d这种方式还存在缺陷吗?

回答关注问题邀请回答
收藏

1 个回答

  • TNT
    TNT
    2022-02-24

    代码有么。。

    2022-02-24
    有用
    回复 7
    • Spider的故事
      Spider的故事
      2022-02-24
      这是生成海报的js
      2022-02-24
      回复
    • Spider的故事
      Spider的故事
      2022-02-24回复Spider的故事
      function sharePic(spuInfo, mpoId, success, fail) {
        const query = wx.createSelectorQuery();
        query.select('#canvasDetail')
          .fields({
            node: true,
            size: false
          }).exec((res) => {
            const canvas = res[0].node;
            const ctx = canvas.getContext('2d');
            canvas.width = 750;
            canvas.height = 1331;
            let userInfo = wx.getStorageSync("userInfo");
            new Promise(function (resolve) { //商品主图
              const img = canvas.createImage();
              img.src = spuInfo.pdItem.picUrlAll + '?x-oss-process=image/resize,w_750';
              img.onload = () => {
                ctx.drawImage(img, 48, 176, 654, 654);
                resolve();
              }
            }).then(function () { //门店头像
              return new Promise(function (resolve) {
                const img = canvas.createImage();
                img.src = spuInfo.spShop.picUrlAll;
                if (spuInfo.spShop.picUrlAll == undefined) {
                  img.src = '../../../images/spu/home_shop_default.png';
                }
                img.onload = () => {
                  ctx.drawImage(img, 48, 64, 88, 88);
                  resolve();
                }
              })
            }).then(function () { //海报背景图
              return new Promise(function (resolve) {
                const img = canvas.createImage();
                img.src = '../../../images/spu/spu_share_back.png';
                img.onload = () => {
                  ctx.drawImage(img, 0, 0, 750, 1331);
                  ctx.restore()
                  resolve();
                }
              })
            }).then(function () { //小程序码 和 头尾文案
              return new Promise(function (resolve) {
                ctx.textAlign = 'left';
                ctx.textBaseline = 'top';
                ctx.font = 'bold 32px PingFang-SC';
                ctx.fillStyle = '#1A1A1A';
                ctx.fillText(spuInfo.spShop.name, 152, 68, 550);

                ctx.font = '26px PingFang-SC';
                ctx.fillStyle = '#868686';
                ctx.fillText(spuInfo.spShop.greeting, 152, 114, 550);

                let temStr = '';
                if (spuInfo.pdItem.groupType == 23) {
                  temStr = "正品保证 · 售后无忧";
                } else if (spuInfo.pdItem.type == 10) {
                  temStr = "官方授权 · 假一赔十 · 售后无忧"
                } else {
                  temStr = "100%正品 · 假一赔十 · 售后无忧";
                }
                ctx.fillStyle = '#B2B2B2';
                ctx.fillText(temStr, 257, 1242, 445);

                const img = canvas.createImage();
                let scene = "a_" + spuInfo.pdItem.pdItemId + "_" + userInfo.ucUserShopinfo.customerShopId + "_" + userInfo.ucUserId;
                if (mpoId != null) {
                  scene = scene + "_" + mpoId;
                }
                img.src = 'https://app.kkid.vip/kshop-appc/weixincode.htm?scene=' + encodeURIComponent(scene) + '&width=250&isHyaline=true',
                  img.onload = () => {
                    ctx.drawImage(img, 490, 855, 212, 212);
                    resolve();
                  }
              })
            }).then(function () { //拼团用户头像
              return new Promise(function (resolve) {
                if (spuInfo.pdItem.itemType == "PINTUAN") {
                  const img = canvas.createImage();
                  img.src = '../../../images/order/comment-default_icon.png';
                  if (userInfo.headUrl != undefined && userInfo.headUrl.length > 10) {
                    img.src = userInfo.headUrl;
                  }
                  img.onload = () => {
                    ctx.drawImage(img, 80, 725, 68, 68);
                    ctx.restore()
                    const img1 = canvas.createImage();
                    img1.src = '../../../images/spu/spu_share_pin.png';
                    img1.onload = () => {
                      ctx.drawImage(img1, 72, 720, 223, 78);
                      let temStr = "访客"
                      if (userInfo.headUrl != undefined && userInfo.headUrl.length > 10) {
                        temStr = userInfo.name;
                      }
                      for (let j = 0; j < temStr.length; j++) {
                        if (ctx.measureText(temStr.substring(0, j)).width > 102) {
                          temStr = temStr.substring(0, j - 1) + '...';
                          break;
                        }
                      }
                      ctx.textAlign = 'left';
                      ctx.font = 'bold 30px PingFang-SC';
                      ctx.fillStyle = '#363636';
                      ctx.fillText(temStr, 164, 732, 110);
                      resolve();
                    }
                  }
                } else {
                  resolve();
                }
              })
            }).then(function () { //商品信息
              return new Promise(function (resolve) {

                //商品标题
                let titleHigh = 868;
                if (spuInfo.pdItem.itemType == "PINTUAN" || spuInfo.pdItem.itemType == "GIFTPACK") {
                  titleHigh = 1038;
                }
                ctx.font = 'bold 28px PingFang-SC';
                ctx.fillStyle = '#363636';
                let temStr = spuInfo.pdItem.title;
                let temStr1 = '';
                for (let j = 0; j < temStr.length; j++) {
                  if (ctx.measureText(temStr.substring(0, j)).width > 410) {
                    temStr1 = temStr.substring(0, j - 1);
                    temStr = temStr.substring(j - 1);
                    break;
                  }
                  if (j == temStr.length - 1) {
                    temStr1 = temStr;
                    temStr = '';
                  }
                }
                ctx.fillText(temStr1, 48, titleHigh, 410);
                temStr1 = '';
                for (let j = 0; j < temStr.length; j++) {
                  if (ctx.measureText(temStr.substring(0, j)).width > 410) {
                    temStr1 = temStr.substring(0, j - 1) + '...';
                    break;
                  }
                  if (j == temStr.length - 1) {
                    temStr1 = temStr;
                  }
                }
                ctx.fillText(temStr1, 48, titleHigh + 40, 410);

                //商品价格
                let priceHigh = 974;
                if (spuInfo.pdItem.itemType == "PINTUAN" || spuInfo.pdItem.itemType == "GIFTPACK") {
                  priceHigh = 864;
                }
                let priceLeft = 48;

                ctx.font = 'bold 40px PingFang-SC';
                ctx.fillStyle = '#FF2F2F';
                ctx.fillText('¥', priceLeft, priceHigh + 30, 100);
                priceLeft += 40;
                let itemSku = spuInfo.itemSku;
                if (spuInfo.pdItem.itemType == "PINTUAN") {
                  itemSku = spuInfo.pintuanItemSku;
                }
                temStr = itemSku.retailPrice.toString();
                ctx.font = 'bold 76px PingFang-SC';
                ctx.fillText(temStr, priceLeft, priceHigh, 200);
                priceLeft += (ctx.measureText(temStr).width + 4);
                if (itemSku.retailPriceMax > itemSku.retailPrice) {
                  ctx.font = 'bold 32px PingFang-SC';
                  ctx.fillText('起', priceLeft, priceHigh + 32, 200);
                  priceLeft += (32 + 4);
                }
                if (itemSku.retailPriceLined != undefined) {
                  temStr = '¥' + itemSku.retailPriceLined;
                  ctx.font = '32px PingFang-SC';
                  ctx.fillStyle = '#9B9B9B';
                  ctx.fillText(temStr, priceLeft, priceHigh + 34, 200);

                  ctx.strokeStyle = '#9B9B9B';
                  ctx.beginPath()
                  ctx.lineWidth = 2;
                  ctx.moveTo(priceLeft, priceHigh + 34 + 15)
                  ctx.lineTo(priceLeft + ctx.measureText(temStr).width, priceHigh + 34 + 16)
                  ctx.stroke();
                }
                ctx.restore()

                if (spuInfo.pdItem.itemType == "PINTUAN") {
                  const img = canvas.createImage();
                  img.src = '../../../images/spu/spu_share_pintuan.png';
                  img.onload = () => {
                    ctx.drawImage(img, 48, 944, 316, 56);
                    ctx.textAlign = 'center'
                    ctx.font = 'bold 28px PingFang-SC';
                    ctx.fillStyle = '#FF2F2F';
                    temStr = '立省' + (spuInfo.pintuanItemSku.economize) + '元';
                    ctx.fillText(temStr, 272, 944 + 14, 168);
                    resolve();
                  }
                } else if (spuInfo.pdItem.itemType == "GIFTPACK") {
                  const img = canvas.createImage();
                  img.src = '../../../images/spu/spu_share_gift.png';
                  img.onload = () => {
                    ctx.drawImage(img, 48, 944, 292, 56);
                    resolve();
                  }
                } else {
                  // 标签
                  ctx.textAlign = 'center'
                  let tagLeft = 48;
                  let tagHigh = 1056;
                  for (let j = 0; j < spuInfo.pdItem.shareTagObjs.length; j++) {
                    let temTag = spuInfo.pdItem.shareTagObjs[j];
                    ctx.font = '18px PingFang-SC';
                    let temWidth = ctx.measureText(temTag.name).width + 16;
                    if (temWidth + tagLeft > 410) {
                      break;
                    }
                    ctx.fillStyle = temTag.bgColor;
                    ctx.fillRect(tagLeft, tagHigh, temWidth, 32);
                    ctx.fillStyle = temTag.color;
                    ctx.fillText(temTag.name, tagLeft + temWidth / 2, tagHigh + 7, temWidth);
                    tagLeft += (temWidth + 10);
                  }
                  resolve();
                }
              })
            }).then(function () {
              wx.canvasToTempFilePath({
                canvas: canvas,
                success(res) {
                  typeof success === 'function' && success(res.tempFilePath)
                },
                fail() {
                  if (fail != null && fail) {
                    typeof fail === 'function' && fail()
                  }
                  wx.showToast({
                    title: '海报生成失败,请稍后再试!',
                    icon: "none"
                  })
                }
              })
            })
          })
      }
      2022-02-24
      回复
    • TNT
      TNT
      2022-02-24回复Spider的故事
      本地图片 没有调用 wx.getImageInfo转为本地图片再绘制?
      2022-02-24
      回复
    • TNT
      TNT
      2022-02-24回复Spider的故事
      可以尝试海报组件
      https://github.com/Kujiale-Mobile/Painter
      2022-02-24
      回复
    • Spider的故事
      Spider的故事
      2022-02-24
      可能是这个原因吗,我以为onload就能解决本地图片这个问题,在大部分机型上是好的
      2022-02-24
      回复
    查看更多(2)
登录 后发表内容