canvas --画布生成证书,并导出图片

1,181 阅读1分钟

今天我也给别人发一次证书。在公益项目中用户的捐款需求中希望获得捐款的证书。在项目中使用了canvas ,思路是将设计的证书图片画到画布上,然后将用户名和感谢语等信息写到画布上。并且将二维码和公章也画到画布上, 最终生成图片。方便用户下载

<canvas style="display: none" id="myCanvas" width=""></canvas>
  1. 首先初始化画板
makeCanvas(width, height) { // 初始化画板
    this.myCanvas = document.getElementById('myCanvas');  // 画板id
    this.myCanvas.width = width;  //尺寸
    this.myCanvas.height = height;
    this.ctx = this.myCanvas.getContext('2d');
    this.ctx.fillStyle = '#ffffff';
    this.ctx.fillStyle = '#fff';
    this.ctx.fillRect(0, 0, this.myCanvas.width, this.myCanvas.height);
},
  1. 初始化背景
makeImage(url, x, y, width,callback) {
      // 初始化背景
        let image = new Image();
        image.setAttribute('crossOrigin', 'anonymous')
        
        image.onload = () => {
          console.log(image.width,image.height);
            this.ctx.drawImage(image, x, y, width, image.height * width / image.width); //图像等比进行缩放
            callback()
        }
        image.src = url;
    },
  1. 将文字写到画布上
makeText(text, x, y, align, color, font) { //文字
    this.ctx.font = !font ? '14px Arial' : font;
    this.ctx.fillStyle = !color ? '#4a4a4a' : color;
    this.ctx.textAlign = align;
    this.ctx.fillText(text, x, y);
},
  1. 在写文字的过程中需要判断是否折行
findBreakPoint(text, width, context) {
      var min = 0;
      var max = text.length - 1;

      while (min <= max) {
          var middle = Math.floor((min + max) / 2);
          var middleWidth = context.measureText(text.substr(0, middle)).width;
          var oneCharWiderThanMiddleWidth = context.measureText(text.substr(0, middle + 1)).width;
          if (middleWidth <= width && oneCharWiderThanMiddleWidth > width) {
              return middle;
          }
          if (middleWidth < width) {
              min = middle + 1;
          } else {
              max = middle - 1;
          }
      }

      return -1;
    },
    breakLinesForCanvas(text, width, font) {
      var result = [];
      var breakPoint = 0;
      // if (font) {
      //     this.ctx.font = 14;
      // }
      while ((breakPoint = this.findBreakPoint(text, width,  this.ctx)) !== -1) {
          result.push(text.substr(0, breakPoint));
          text = text.substr(breakPoint);
      }

      if (text) {
          result.push(text);
      }

      return result;
    },
    var result = this.breakLinesForCanvas(cateText,370*2, self.contentFontSize);
    // 结果是一个数组,将一整段文字按需要折行拆分为一个数组
    
  1. 将画完的canvas 导出为图片
imagePut(type) {
        this.img_src = this.myCanvas.toDataURL('image/png');
        
    },
  1. 需要注意的两点
  • 在操作图片的时候,需要操作同一个域下的图片,或者图片允许跨域操作。
  • 一般情况,在高清屏的设备下,任何绘制canvas中的图像、文字、线条、形状都可能会出现模糊的问题。 在 drawImage( ) 中,将 width 和 height 乘以 ratio;
  • 如果 image.src 是 base64 格式文件,不要设置 image.crossOrigin = "anonymous",可能会出现 image.onload 无法执行的问题,从而无法正常画图。