小程序之分享朋友圈

背景:shareAppMessage只能分享到个人与群组,不能分享到朋友圈,所以需要另辟蹊径,将带有文章信息的元素保存到手机,再在朋友圈发图片,识别其中的小程序即可访问该文章

需求:将文章帖子或者关键信息+该文章的二维码链接,保存为一张图片上,保存到相册

思路简述:

  1. 获取太阳码
  2. 获取文章信息
  3. 利用canvas将元素画上去
  4. draw成临时图片
  5. 下载保存到用户相册

详细代码

1. 页面元素一个canvas和一个button,点击button要触发js方法

<canvas  canvas-id="shareCanvas" style='width:{{windowWidth}}px;height:{{windowHeight}}px'></canvas>
<view class="addfav" bindtap="saveImage" style='margin-left:7px;'>↓ 分享至朋友圈</view>

canvas样式要放到屏幕外面,加个绝对定位,使得画布不显示出来
canvas{
  position:absolute;
  left:-429px;
  top:-721px;
}

2. 按钮触发saveImage方法,由后端请求getWXACodeUnlimit(查看文档的api),php后端根据appid和appsecret获取access_token,拼接上获取code的url,这里的scene参数就是帖子id;该api会返回图片的二进制流,将它写入图片

小程序:

saveImage:function() {
    wx.showLoading({
      title: '正在生成海报',
    })
    var that = this;
    var access_token = '';
    //进行与后端api交互
    var codeImageUrl = app.globalData.HostCodeUrl;
    wx.request({
      url: codeImageUrl +'mod=code_image', //仅为示例,并非真实的接口地址
      data: {
        tid: that.data.nowtid,
        path: 'pages/viewthread/viewthread',
      },
      header: {
        'content-type': 'application/json' // 默认值
      },
      success(res) {
        that.data.codePagePath = res.data;
        //画海报内容
        that.canvasMake();
      }
    });
  },

php处理:

$appId = 'xxx';
$appSecret = 'aaa';
$getCodeUrl = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=';
$getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appId&secret=$appSecret";
$rootPath = 'https://www.demo.info/minapp/3.0/';
if (isset($_GET['tid'])){
    if(file_exists($rootPath.'code_mage/'.$_GET['tid'].'_.png')){ //该帖子的太阳码存在就直接返回这个图片路径
        echo $rootPath.'code_image/'.$_GET['tid'].'_.png';
        exit();
    }
    $data['scene'] = $_GET['tid'];
    $data['page'] = $_GET['path'];
    $re_data = json_decode(getCurl($getAccessTokenUrl),true); //curl get请求,返回access_token
    $accessToken = $re_data['access_token'];
    $getCodeUrl .= $accessToken;

    $ret = postUrl($getCodeUrl,json_encode($data));//curl post 返回图片二进制流
    $path = 'code_image/'.$_GET['tid'].'_.png';

    $file = fopen($path,"w+"); //写入图片
    fwrite($file,$ret);
    fclose($file);

    echo $rootPath.$path;  //返回图片路径
}

3.铺一张背景图片和帖子标题和帖子详情,自适应手机宽高比例,并判断是否有图片

canvasMake:function(){
    var that = this;
    const ctx = wx.createCanvasContext('shareCanvas')

    //背景图片填充画布
    that.canvasMakeWords(ctx);

    //判断是否有图片 
    var ifImage = false;
    //如果有图片,宽高需要调整,
    //判断图片是否存在,而且第一张图片是否是白名单的图片
    if (!that.isEmptyObj(that.data.PostList[0].piclist)){
      ifImage = true;
    }
    if (ifImage && (that.data.PostList[0].piclist[0].indexOf('白名单域') >0 )) {
      var offset = 1.5 / 9 ; //偏移比例
      var imageViewSrc = that.data.PostList[0].piclist[0];
      console.log('文章有第一张图->' + imageViewSrc);
      //获取文章第一张图画到画布上
      wx.getImageInfo({
        src: imageViewSrc,
        success(res) {
          ctx.drawImage(res.path, that.data.windowWidth * 0.1, that.data.windowHeight * 4.5 / 9, that.data.windowWidth * 8 / 10, that.data.windowHeight * 2.2 / 9);
          console.log('imageViewSrc-success->  ' + imageViewSrc);
          //绘制小程序码
          that.canvasMakeCode(ctx,offset);
        },
        fail(res){
          console.log('fail' + res);
        }
      })
    }else{
      var offset =  0;
      //绘制小程序码
      that.canvasMakeCode(ctx,offset);
    }
    console.log('end-getImageInfo');
  },

4. 画上太阳码,draw完后图片保存到临时路径,再下载画好的图

canvasMakeCode: function (ctx,offset){
    var that = this ;
    //画上小程序码
    wx.getImageInfo({
      src: that.data.codePagePath,   //获取到php返回的太阳码路径
      success(ress) {
        console.log(offset);
        ctx.drawImage(ress.path, that.data.windowWidth * 0.1, that.data.windowHeight * (5.5 / 9 + offset), that.data.windowWidth * 3 / 10, that.data.windowHeight * 1.5 / 9);
        //长按图片识别二维码
        ctx.setTextAlign('left')
        ctx.setFillStyle('#708090')  // 文字颜色:黑色
        ctx.setFontSize(15)         // 文字字号:22px
        ctx.fillText('长按图片识别二维码', that.data.windowWidth * 5 / 10, that.data.windowHeight * (6 / 9 + offset))
        ctx.fillText('查看文章详情', that.data.windowWidth * 5 / 10, that.data.windowHeight * (6 / 9 + offset) + 20)
        ctx.stroke();

        ctx.draw();
        //draw保存画布为临时路径
        wx.canvasToTempFilePath({
          canvasId: 'shareCanvas',
          success: function (res) {
            that.setData({
              prurl: res.tempFilePath,
              hidden: false
            })
            //将保存的临时路径保存到系统相册
            wx.saveImageToPhotosAlbum({
              filePath: res.tempFilePath,
              success: function (resss) {
                wx.hideLoading();
                wx.showToast({
                  title: '海报已保存到相册,请发布到朋友圈',
                  icon: 'none',
                });
                console.log(resss)
              },
            })
          },
          fail: function (err) {
            wx.hideLoading();
            wx.showToast({
              title: '保存失败',
              icon: 'none',
            });
          }
        })
      }
    })
  },

注意事与坑

注意事项:

  1. canvas画布在屏幕外,主要浏览帖子生成图片的时候不会挡住帖子
  2. 该代码只是主要的代码,比如太阳码图片路径什么的在page的data就不全贴出来了,还有变量的精简等等;

坑:

  1. draw的回调方法开发工具不执行,只能真机测试;

最后

如果有不足或者更好的想法,请不吝赐教,坚持开源坚持分享 :)

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 3年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!