mpvue

微信小程序生成二维码分享朋友圈

2019-02-09  本文已影响37人  指尖轻敲

业务需求

开发过程中经常会遇到这样的需求,把指定的页面分享到朋友圈。这在H5页面是没有问题的,直接调用JSSDK的分享接口即可,但是小程序是无法直接分享到朋友圈的,所以我们只能通过分享一个小程序的二维码出去,其他人通过扫码进入指定页面。

节假日大家都会用携~旅行的等软件进行抢票,分享到朋友圈让好友帮忙加速,这里就是通过分享一个二维码,好友扫码进入小程序进行加速。查了一下发现确实有不少做过该功能的大佬。这里我也在实现并验证没问题之后做一个总结。

实现步骤

  1. 前端通过调用服务端的接口,把生成小程序二维码需要的参数传递过去。然后服务端去调小程序的接口获取二维码(因为前端无法直接调用该接口)。

  2. 前端把服务端返回的图片下载下来。

  3. 通过调用canvas的api把二维码图片和想要添加的元素绘制到画布上。(前面图片没有下载的话是画不上去的)

  4. 绘制完成之后,调用相关接口把画布专程图片

  5. 把转换成的图片保存到本地,然后就可以去朋友圈手动分享了。

代码实现

请求获取二维码接口,需要传递两个必须的参数:

获取到二维码路径,通过wx.downloadFile()API将图片下载到本地,然后就可以操作canvas了,根据自己的业务需求进行绘制。

  1. canvas标签要有一个canvas-id以便在js中通过这个id获取画布。

  2. 创建一个画布对象createCanvasContext(canvas-id),传入画布的id。

  3. 进行一系列绘制操作,具体可以查看对应的API。这里我只是简单的把二维码画上去,然后加了一行字。

需要注意的是,生成的图片背景是黑色,所以我最先画了一个和画布大小一样的白色矩形作为背景。

<canvas style="width: 100vw; height: 500px" canvas-id="shareImg"></canvas>

getImage() {
  util
    .request(
      `${api.ApiRootUrl}/wechat/codeUnlimit`,
      {
        scene: `${this.data.articleId}&${this.data.type}`,
        page: 'pages/detail/detail'
      },
      'POST'
    )
    .then(response => {
      wx.downloadFile({
        url: `${response.image}`,
        success: res => {
          const ctx = wx.createCanvasContext('shareImg');
          //绘制一个白色矩形,宽度为屏幕宽度
          ctx.setFillStyle('#fff');
          ctx.fillRect(0, 0, this.data.windowWidth, 500); 
          // 把二维码画上去
          ctx.drawImage(
            res.tempFilePath,
            this.data.windowWidth / 2 - 75,
            30,
            150,
            150
          );
          // 绘制想要的文字
          ctx.setTextAlign('center');
          ctx.setFontSize(24);
          ctx.setFillStyle('red');
          ctx.fillText('请手动分享到朋友圈', this.data.windowWidth / 2, 220);
          ctx.stroke();
          // 画(前面都是准备,这才是画的那一步)
          ctx.draw();
          this.canvasToImage();
        },
        fail() {
          wx.showToast({
            title: '获取二维码失败',
            duration: 2000
          });
        }
      });
    });
},

上面已经把想要的内容都画出来了,接着就是把画布转成图片。这里调用canvasToTempFilePathAPI,然后设置一些参数(画布的宽高、输出图片的宽高、类型等等),具体看文档。

这里需要注意的是要加一个延时操作,否则图片出不来的。

canvasToImage() {
  setTimeout(() => {
    wx.canvasToTempFilePath({
      canvasId: 'shareImg',
      width: 400,
      height: 500,
      destWidth: 400,
      destHeight: 500,
      fileType: 'jpg',
      success: res => {
        wx.showToast({
          title: '图片已生成',
          icon: 'success',
          duration: 2000
        });
        this.setData({
            resultImage: res.tempFilePath
        });
      },
      fail: () => {
        wx.showToast({
          title: '图片生成失败',
          icon: 'success',
          duration: 2000
        });
      }
    });
  }, 0);
},

最后就是保存图片到本地了,使用wx.saveImageToPhotosAlbum()API,将刚才转成图片获取到的路径传入。到此生成二维码并保存到本地就完成了。

saveImageToLocal() {
  wx.saveImageToPhotosAlbum({
    filePath: this.data.resultImage,
    success: res => {
      wx.showToast({
        title: '保存成功',
        icon: 'success',
        duration: 2000
      });
    },
    fail() {
      wx.showToast({
        title: '保存失败',
        duration: 2000
      });
    }
  });
}

但是,记得修改该页面对传入参数的操作。如果是通过扫码进来的,获取参数的方式是不一样的,所以要做处理。之前正常进入该页面直接从option中获取对应参数。这里改为判断option.scene字段存不存来区分是否是扫码进来的。

如果是扫码进来的,就根据之前你传给服务端scene字段时的格式去解析参数,在进行赋值。这里通过&来分割参数再分别获取。

onLoad: function(option) {
  let articleId, type;
  if (option.scene) {
    let scene = decodeURIComponent(option.scene);
    articleId = scene.split('&')[0];
    type = scene.split('&')[1];
  } else {
    articleId = option.id;
    type = option.type;
  }
}
上一篇 下一篇

猜你喜欢

热点阅读