Canvas 简单实现分享海报

学习 · 2022-01-07

QQ截图20220107094712.png

前言

现存大部分系统中,用于引流分享必不可少的就是海报分享,海报分享的特性莫过于便捷的传播、新用户的了解和加入系统。在每次开发系统中,都需要重新编写一套海报生产代码,造成了大量时间的荒废,故此简单封装canvas生产海报的方法,如有bug请勿打扰!

实现

入参规范

  • 1.canvas 整体宽高 width height
  • 2.背景色
  • 3.渲染内容

completelyCanvas(750, 1334, '#fff', overly)

其中渲染内容是一个数组,数组内容包含背景图,二维码和相应文本内容等等...

字段说明
{ // 二维码图片
  type: 'image', // 绘制类型 text / image
  data: 'https://qiniu.lettered.cn/2022/01/06/100073.png', // 内容信息(图片使用的url)
  width: 175, // 绘制宽度
  height: 175,// 绘制高度度
  xAxis: 77, // x轴位置(起始点)
  yAxis: 1108 // y轴位置(起始点)
}
举个例子
let overly = [
  { // 底图背景
    type: 'image',
    data: 'https://qiniu.lettered.cn/2022/01/06/100076.jpg',
    width: 750,
    height: 1334,
    xAxis: 0,
    yAxis: 0
  },
  { // 二维码图片
    type: 'image',
    data: 'https://qiniu.lettered.cn/2022/01/06/100073.png',
    width: 175,
    height: 175,
    xAxis: 77,
    yAxis: 1108
  },
  {
    type: 'text',
    data: '许小宝 180-7868-7485',
    width: 406,
    height: 175,
    xAxis: 284,
    yAxis: 1198
  }
];

具体函数

completelyCanvas(width = 750, height = 1334, background = '#fff', overly = []) {

  if (overly.length === 0) return Promise.reject('空参数');

  // promise
  return new Promise((resolve, reject) => {
    let base64 = '',
        canvas = document.createElement('canvas'),
        ctx = canvas.getContext("2d");
    // 宽度高度
    canvas.width = width;
    canvas.height = height;
    // 填充颜色
    ctx.rect(0, 0, width, height);
    ctx.fillStyle = background;
    ctx.fill();

    // 迭代生成
    let _overly = [];
    _overly = overly.map( item => {
      // todo
      return {
        ...item
      }
    })

    // 开始绘画
    let drawing = idx => {
      // 判断当前索引 => 是否已绘制完毕
      if (idx < _overly.length) {
        let draw = _overly[idx];
        // type = image
        if (draw.type === 'image') {
          // 等图片预加载后画图
          let img = new Image(),
              timeStamp = new Date().getTime();
          // 防止跨域
          img.setAttribute('crossOrigin', 'anonymous')
          // 链接加上时间戳
          img.src = draw.data + '?' + timeStamp
          img.onload = function() {
            // 先把图片缩放成画布比例的大小,否则直接设置图片宽高图片展示不完整
            ctx.drawImage(img, draw.xAxis, draw.yAxis, draw.width, draw.height)
            // 递归
            drawing(idx + 1)
          }
        } else { // type = text
          ctx.font = draw.font || 'normal 400 32px 黑体';
          ctx.fillStyle = draw.fillStyle ||'#fff';
          ctx.textBaseline = 'bottom';
          ctx.fillText(draw.data, draw.xAxis, draw.yAxis);
          // 递归
          drawing(idx + 1)
        }
      } else {
        try {
          // 生成图片
          base64 = canvas.toDataURL("image/png")
          if (base64) {
            //
            resolve(base64)
          }
          reject('生产图片错误')
        }catch (err) {
          reject(err)
        }
      }
    }
    drawing(0)
  })
}

使用方法

completelyCanvas(750, 1334, '#fff', overly).then( res => {
  console.log('res', res)
  this.poster = res // base64图片内容
}).catch(err => {
  console.error(err)
})

成品展示

背景图片来源网络,侵权必删
下载.png

附加

实现自适应屏幕宽高

// 取得屏幕宽高
const { width, height } = window.screen;

// 比例计算 img 是背景图对象
let widthRate = width/img.width;
let heightRate = height/img.height;

// 设定背景图 - 按比例写入图片
ctx.drawImage(img, 0 * widthRate, 0 * heightRate, width, height)
js canvas 海报 分享
Theme Jasmine by Kent Liao | 桂ICP备15008025号-6