小程序canvas生成海报 - 新闻资讯 - 云南小程序开发|云南软件开发|云南网站建设-昆明葵宇信息科技有限公司

159-8711-8523

云南网建设/小程序开发/软件开发

知识

不管是网站,软件还是小程序,都要直接或间接能为您产生价值,我们在追求其视觉表现的同时,更侧重于功能的便捷,营销的便利,运营的高效,让网站成为营销工具,让软件能切实提升企业内部管理水平和效率。优秀的程序为后期升级提供便捷的支持!

您当前位置>首页 » 新闻资讯 » 小程序相关 >

小程序canvas生成海报

发表时间:2020-9-29

发布人:葵宇科技

浏览次数:65

小程序canvas生成海报

  • 先看看效果图 以下↓
    • 使用场景
    • 前提
    • wxml
    • js
      • drawCanvas.js
      • 在Canvas.js引入drawCanvas.js
    • 希望大家能够用到!

如果文章中有出现纰漏、错误之处,还请看到的小伙伴多多指教,先行谢过

先看看效果图 以下↓

在这里插入图片描述

使用场景

  • 分享小程序的,绘制分享图
  • 不同商品分享的是后生成不同的图片,每个商品的信息图片不同,小程序默认分享的是页面默认截图
  • 小程序分享朋友圈,生成海报

前提

  • 根据上面图片需要一个背景图片(上面是750*777),大家可根据实际情况进行改变
  • 本文用的是小程序canvas最新api,大家可以阅读小程序canvas文档

wxml

<canvas style="width:750px;height:777px;position:absolute;top:0px;left:-2000px;" id="canvas" type="2d"></canvas>

js

drawCanvas.js

[单独创建drawCanvas.js存放一些公共函数,里面封装了图片渲染文字换行等一些方法(由于画布无法直接使用网络图片,所以需要 wx.downloadFile或者wx.getImageInfo把它下载回来才能使用,本文使用wx.downloadFile)]


export default {
  // 下载图片函数
  downloadImg(img) {
    return new Promise((resolve, reject) => {
      //将网络图片转成本地路径     
      // wx.getImageInfo({
      //   src: img,
      //   success: function (res) {
      //     resolve(res.path)

      //   }
      // })
      //方法二
      wx.downloadFile({
        url: img,
        success: (res) => {
          let cover = res.tempFilePath;
          resolve(cover)
        },
        fail: (err) => {

          reject(err)
        },
      })
    })
  },
  //图片渲染
  drawImage(canvas, ctx, imgUrl, x, y, w, h) {
    ctx.save();
    const img = canvas.createImage();
    img.src = imgUrl
    img.onload = () => ctx.drawImage(img, x, y, w, h);
    ctx.closePath();
  },

  //文字换行
  drawTxt: function (ctx, _str, _x, _y, _total, _lineh, _linenum) {
    if (_str == "" || _str == undefined) {
      return;
    }
    var total = _total ? _total : 15; //每行字数(数字算半个)
    var lineH = _lineh ? _lineh : 20; //行间距
    var lineNum = _linenum ? _linenum : 4; //最大显示行数

    /*
    拆解字符串到数组,按行,每行15个(判断数字占半个,其他占1个)
    */
    var lineArray = [];
    var len = 0; //数字算半个,中文算一个
    for (var i = 0; i < _str.length; i++) {
      var line = '';
      if (Math.ceil(len) % total == 0) {
        if (lineArray[lineArray.length - 1] != "") {
          lineArray.push("");
        }
      }
      var index = Math.floor(len / total); //
      lineArray[index] = lineArray[index] + _str[i];

      if (!isNaN(_str[i])) {
        //是数字
        len = len + 0.5;
      } else {
        len = len + 1;
      }
    }

    for (var i = 0; i < lineArray.length; i++) {
      var t_str = lineArray[i];
      if (lineArray.length > lineNum && i == (lineNum - 1)) {
        //如果总行数大于设定的行数,则到最大设定行时,加省略号,退出
        t_str = t_str + '...'
        ctx.fillText(t_str, _x, _y + lineH * i);
        break;
      } else {
        ctx.fillText(t_str, _x, _y + lineH * i);
      }
    }
  },

  //裁切圆角  
  drawRoundRect: function (cxt, x, y, width, height, radius) {
    cxt.save()
    cxt.beginPath();
    cxt.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
    cxt.lineTo(width - radius + x, y);
    cxt.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2);
    cxt.lineTo(width + x, height + y - radius);
    cxt.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2);
    cxt.lineTo(radius + x, height + y);
    cxt.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI);
    cxt.closePath();
  }
}

在Canvas.js引入drawCanvas.js

import drawCanvas from 'drawCanvas.js';
Page(Object.assign({},drawCanvas, {
 /**
   * 页面的初始数据
   */
  data: {
    canvasImg: 'https://dss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2635355882,2630309952&fm=218&app=2&f=JPEG?w=121&h=75&s=FF7204C5C0615D0773AD7CD103003098' // 实例
  },
 /**
   * 生命周期函数--监听页面加载
   */
 >: function (options) {
    this.shareCreate()
  },
  //分享微信朋友圈
  async shareCreate() {
    var self = this;
    //self.downloadImg是drawCanvas.js里面方法
    let imgUrl = await self.downloadImg(self.data.canvasImg);
    wx.nextTick(() => { self.drawAll(imgUrl) })
  },
    drawAll(imgUrl) {
    const query = wx.createSelectorQuery()
    const node = query.select('#canvas').node();
    var self = this;
    node.exec(async res => {
      const canvas = res[0].node;
      //设置宽高
      canvas.width = canvas._width
      canvas.height = canvas._height
      const ctx = canvas.getContext('2d');
      //背景图
      await self.drawImage(canvas, ctx, "/images/shareImg.png", 0, 0, 750, 777);

      //cover
      await self.drawImage(canvas, ctx, imgUrl, 0, 0, 750, 460);

      //logo
      await self.drawImage(canvas, ctx, imgUrl, 50, 525, 363, 45);


      setTimeout(async () => {
        //背景透明
        ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';
        ctx.fillRect(0, 0, 750, 460);
        //绘制空心矩形
        ctx.strokeStyle = 'rgba(0, 0, 0, 0.6)';
        ctx.strokeRect(0, 0, 750, 460);
        ctx.save();
        //title
        ctx.textAlign = 'left';
        ctx.fillStyle = 'rgba(255, 255, 255, 1)';
        ctx.font = "normal bold 41px PingFangSC-Regular";
        self.drawTxt(ctx, "测试卡片", 50, 390, 30, 50, 1);

        //desc
        ctx.textAlign = 'left';
        ctx.fillStyle = "#1e1e1e";
        ctx.font = "normal normal 28px PingFangSC-Regular";
        self.drawTxt(ctx, "测试卡片测试卡片测试卡测试卡片片测试卡片测试卡片测试卡片测试卡片测试卡片测试卡片片测试卡片测试卡片", 159, 661, 18, 43, 2);
        //裁切圆角 
        self.drawRoundRect(ctx, 50, 625, 92, 92, 46);
        ctx.clip();
        ctx.stroke();
        //头像
        await self.drawImage(canvas, ctx, imgUrl, 50, 625, 92, 92);
        ctx.restore();
        ctx.closePath();
        //canvas转成图片
        self.previewHB(canvas)
      }, 500)


    })
  },
   //图片预览
  previewHB(canvas) {
    var self = this;
    wx.nextTick(() => {
      //转换图片
      wx.canvasToTempFilePath({
        canvas: canvas,
        success:async (res)=> {
          let img=res.tempFilePath
          //预览
          wx.previewImage({
            urls: [img]
          })
        }
      })
    })
  },
}})

希望大家能够用到!

相关案例查看更多