带你实现用canavs画海报并且下载

766 阅读2分钟

分享海报的功能目前比较常见,尤其是电商公司,在实习期间接到了一个实现海报绘制并且下载的需求,于是开始动手开发,接下来带大家说一下具体思路:

1.封装常用的canavs API,方便复用

  • beginPath();
  • moveTo();
  • arc();
  • lineTo();
  • closePath();
  • clip();
  • stroke();
  • fill(); 这里列举了一些常见的API,具体参数可以参考官方文档 下面是常用方法封装
// 设置字体样式
function setStyle(_ctx, font, color, textAlign, textBaseline) {
  textAlign = textAlign || "left";
  textBaseline = textBaseline || "middle";
  _ctx.font = font;
  _ctx.fillStyle = color;
  _ctx.textAlign = textAlign;
  _ctx.textBaseline = textBaseline;
}

// 图片绘制方法
function drawImg(_ctx, img, x, y, w, h) {
  if (!img) return;
  _ctx.drawImage(img, x, y, w, h);
}
//头像圆角绘制
function drawImgRadius(_ctx, img, x, y, w, h, r) {
  _ctx.save();
  _ctx.beginPath();
  _ctx.moveTo(x + r, y);
  _ctx.arc(x + r, y + r, r, 1.5 * MATH_PI, 1 * MATH_PI, true);
  _ctx.lineTo(x, y + h - r);
  _ctx.arc(x + r, y + h - r, r, 1 * MATH_PI, 0.5 * MATH_PI, true);
  _ctx.lineTo(x + w - r, y + h);
  _ctx.arc(x + w - r, y + h - r, r, 0.5 * MATH_PI, 0 * MATH_PI, true);
  _ctx.lineTo(x + w, y + r);
  _ctx.arc(x + w - r, y + r, r, 0 * MATH_PI, 1.5 * MATH_PI, true);
  _ctx.closePath();
  _ctx.clip();
  drawImg(_ctx, img, x, y, w, h);
  _ctx.restore();
}

2.图片的预处理 (收集海报中需要使用的图片)

可以定一个对象用来收集图片

function prePainting(args1,args2,args3) {
  let imgObj = {
    bg: args1,
    logo: args2,
    qrcode: args3,
  };
  return imgObj;
}

3.图片的预加载 (加载canavs中使用的图片)

这里用promise处理图片加载过程,

function preLoadImgs(imgs) {
  let keysArr = Object.keys(imgs);
  let promiseArr = keysArr.map(key => {
    return new Promise(resolve => {
      let _img = new Image();
      _img.crossOrigin = "anonymous";
      _img.onload = () => {
        resolve({
          [key]: _img,
        });
      };
      _img.onerror = () => {
        resolve({
          [key]: null,
        });
      };
      _img.src = imgs[key];
    });
  });

  return Promise.all(promiseArr).then(resArr => {
    return resArr.reduce((accumulator, currentValue) => {
      return Object.assign({}, accumulator, currentValue);
    }, {});
  });
}

4.进行海报的绘制

去调用实现画图的具体实现的方法,绘制成功后调用toDataURL(),用于将canvas对象转换为base64位编码。

5.实现海报的下载功能

通过a的download属性进行图片下载

function doDownLink(imgCanvas) {
  // 创建隐藏的可下载链接
  const a = document.createElement('a') // 创建一个a标签
  a.href = imgCanvas; // a标签的src属性赋值
  a.download = '.jpg';
  // 触发点击
  document.body.appendChild(a);
  a.click();
  // 然后移除
  document.body.removeChild(a);
}