【微信小程序】小程序使用canvas画布生成分享朋友圈的海报

676 阅读5分钟

思路: 利用小程序组件canvas放置一个画布,然后再利用布局吧canvas画布隐藏,让其绘制成的图片显示在我们的前端页面上面就可以了,最后在利用API将图片保存到我们手机上面就完成了。

上代码!

wxml:

<!-- 画布大小按需定制 这里我按照背景图的尺寸定的  -->
<canvas canvas-id="shareImg" style="width:540px;height:771px"></canvas>
  
<!-- 预览区域  -->
<view hidden='{{hidden}}' class='preview'>
  <view class='sherimg_boxs'>
    <image src='{{prurl}}' mode='widthFix'></image>
    <button type='primary' size='mini' bindtap='save'>保存图片</button>
  </view>
</view>

wxss:

canvas{
  position: fixed;
  top: 0;
  left: 4000px;
}
.share{
  position: absolute;
  bottom: 100rpx;
  width: 70%;
  left: 15%;
  height: 100rpx;
  line-height: 100rpx;
}
.preview {
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,.9);
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2;
}
.sherimg_boxs{
  width: 70%;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  text-align: center;
}
.preview image{
  width: 100%;
  z-index: 3;
  border-radius: 24rpx;
}
.preview button{
  margin: 0;
  padding: 0;
  margin-top: 56rpx;
  width:230rpx;
  height:78rpx;
  background:linear-gradient(90deg,rgba(101,219,153,1) 0%,rgba(111,213,173,1) 100%);
  border-radius:48rpx;
  font-size:36rpx;
  font-weight:500;
  color:rgba(255,255,255,1);
  text-align: center;
  line-height: 78rpx;
  border: 0;
}

js:

var util = require('../../utils/util.js');  //存放网络请求的JS
var config = require('../../utils/config.js'); //存放下面所需获取到的url_3的后台请求路径的JS
Page({
  /**
   * 页面的初始数据
   */
  data: {
    imgSaveBell: false, //图片保存成功开关
  },
 
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    // 获取分享朋友圈的图片
    var pathUrl = 'pages/detail/detail'; //路径是为了传给后台返回对应页面的小程序二维码
    var url_3 = config.DOMAIN_API.shareQacode;
    //请求内容
    var data = {
      user_id: app.globalData.uid,
      url: pathUrl,
    }
    util.ajaxPost(url_3, data).then((res) => { //成功处理
      console.log(res);
      var resUrl = res;
      wx.downloadFile({
        url: resUrl, //仅为示例,并非真实的资源
        success: function (res) {
          // 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
          if (res.statusCode === 200) {
            wx.getImageInfo({
              src: res.tempFilePath,
              success: function (res) {
                console.log(res.path) //打印图片的本地路径
                that.setData({
                  friendImg: res.path
                });
                that.sening();
              }
            })
          }
        }
      })
      
    }).catch((errMsg) => { //错误处理,已统一处理,此处可以不需要
      console.log(errMsg);
    });
  },
  //分享到朋友圈
  goshareFriend: function(e) {
    var that = this;
    wx.showLoading({
      title: '努力生成中...'
    })
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 545,
      height: 771,
      destWidth: 545,
      destHeight: 771,
      canvasId: 'shareImg',
      success: function(res) {
        console.log(res.tempFilePath);
        that.setData({
          prurl: res.tempFilePath,
          hidden: false
        })
        wx.hideLoading()
      },
      fail: function(res) {
        console.log(res)
      }
    })
  },
  //生成分享朋友圈图片
  sening: function(e) {
    var that = this;
    wx.getSystemInfo({
      success: function(res) {
        console.log(res.windowHeight)
        console.log(res.windowWidth)
        that.setData({
          windowHeight: res.windowHeight,
          windowWidth: res.windowWidth
        })
      },
    })
    var windowWidth = that.data.windowWidth;
    const ctx = wx.createCanvasContext('shareImg')
    //主要就是计算好各个图文的位置
    //头部绿色图片
    let topGreen = '../../images/fenxiang_kapian.png';
    ctx.drawImage(topGreen, 0, 0, 540, 215)
 
    //底部白色图片
    let botWhite = '../../images/zhongliuyisheng_kapian_baidi.png';
    ctx.drawImage(botWhite, 0, 210, 540, 562)
 
    //二维码图片
    var qacode = that.data.friendImg;
    ctx.drawImage(qacode, 26, 570, 124, 124);
 
    // 设置文字大小
    ctx.setTextAlign('center')
    ctx.setFontSize(45)
    ctx.fillStyle = '#FFFFFF';
    var hedetxt = '资讯';
    // 填充文字
    ctx.fillText(hedetxt, 540 / 2, 100)
 
    // 设置文字大小
    ctx.setTextAlign('center')
    ctx.setFontSize(28)
    ctx.fillStyle = '#FFFFFF';
    var hedbt = 'ONCOLOGY INFORMATION';
    // 填充文字
    ctx.fillText(hedbt, 540 / 2, 150)
 
    ctx.setTextAlign('left')
    ctx.setFontSize(36)
    ctx.fillStyle = '#1F2C3A';
    var position = that.data.arr.title;
    var chr = position.split(""); //这个方法是将一个字符串分割成字符串数组
    var temp = "";
    var row = [];
    for (var a = 0; a < chr.length; a++) {
      if (ctx.measureText(temp).width < windowWidth + 50) {
        temp += chr[a];
      } else {
        a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比
        row.push(temp);
        temp = "";
      }
    }
    row.push(temp);
    //如果数组长度大于2 则截取前两个
    if (row.length > 2) {
      var rowCut = row.slice(0, 3);
      // 这个参数就可以判断显示几行
      var rowPart = rowCut[1];
      var test = "";
      var empty = [];
      for (var a = 0; a < rowPart.length; a++) {
        if (ctx.measureText(test).width < windowWidth) {
          test += rowPart[a];
        } else {
          break;
        }
      }
      empty.push(test);
      var group = empty[0] //这里只显示两行,超出的用...表示
      rowCut.splice(1, 1, group);
      row = rowCut;
 
    }
    for (var b = 0; b < row.length; b++) {
      ctx.fillText(row[b], 26, 320 + b * 50);
    }
 
 
    // 设置文字大小
    ctx.setTextAlign('center')
    ctx.setFontSize(26)
    ctx.fillStyle = '#1F2C3A';
    var rtt = '我正在读这篇文章,推荐给你';
    // 填充文字
    ctx.fillText(rtt, 540 / 2 + 68, 590)
 
    // 设置文字大小
    ctx.setFontSize(24)
    ctx.fillStyle = '#9DA8B2';
    var rct = '长按小程序码,';
    // 填充文字
    ctx.fillText(rct, 540 / 2 - 20, 650)
 
    // 设置文字大小
    ctx.setFontSize(24)
    ctx.fillStyle = '#9DA8B2';
    var rbl = '进入';
    // 填充文字
    ctx.fillText(rbl, 540 / 2 - 80, 690)
 
    // 设置文字大小
    ctx.setFontSize(24)
    ctx.fillStyle = '#61DC98';
    var rbc = '';
    // 填充文字
    ctx.fillText(rbc, 540 / 2 + 20, 690)
 
 
    // 设置文字大小
    ctx.setFontSize(24)
    ctx.fillStyle = '#9DA8B2';
    var rbr = '查看';
    // 填充文字
    ctx.fillText(rbr, 540 / 2 + 120, 690)
    ctx.draw()
  },
  save: function() {
    var that = this
    //生产环境时 记得这里要加入获取相册授权的代码
    wx.saveImageToPhotosAlbum({
      filePath: that.data.prurl,
      success(res) {
        wx.showModal({
          content: '图片已保存到相册,赶紧晒一下吧~',
          showCancel: false,
          confirmText: '好哒',
          confirmColor: '#61DC98',
          success: function(res) {
            if (res.confirm) {
              console.log('用户点击确定');
              that.setData({
                hidden: true
              });
            }
          }
        })
      },
      fail: function(err) {
        console.log(err);
        if (err.errMsg && err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg) { //重新授权弹框确认
          wx.showModal({
            title: '提示',
            content: '需要获取相册访问权限,请到小程序设置页面打开授权',
            success(res) {
              if (res.confirm) { //重新授权弹框用户点击了确定
                wx.openSetting({ //进入小程序授权设置页面
                  success(settingdata) {
                    console.log(settingdata)
                    if (settingdata.authSetting['scope.writePhotosAlbum']) { //用户打开了保存图片授权开关
                      wx.saveImageToPhotosAlbum({
                        filePath: that.data.prurl,
                        success: function(data) {
                          that.setData({
                            hidden: true
                          });
                        },
                      })
                    } else { //用户未打开保存图片到相册的授权开关
                      wx.showModal({
                        title: '温馨提示',
                        content: '授权失败,请稍后重新获取',
                        showCancel: false,
                      })
                    }
                  }
                })
              } else if (res.cancel){
                that.setData({
                  hidden: true
                })
              }
            },
 
          })
        }
      }
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
 
  onReady: function() {},
 
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {
 
  },
 
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function() {
 
  },
 
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {
 
  },
 
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function() {
 
  },
 
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function() {
 
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function(res) {
    
  }
})

总结:

小程序canvas画布之前没做的时候感觉超级难,画的总是不在预想的位置。不过做过一次之后就简单多了,so 简单!哈哈哈哈,定好画布之后开始画图就行,画图所使用的的API链接地址:developers.weixin.qq.com/miniprogram…

————————————————

版权声明:本文为CSDN博主「前端小张」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/qq_37949737…