微信canvas生成分享海报

819 阅读2分钟

效果预览

这里写了一个微信代码片段 developers.weixin.qq.com/s/HSJqczme7…直接截图 上代码

文字自动换行

//数据结构
{
        type: "text",
        x: 10,
        y: 360,
        width: 340,
        fontSize: "14px",
        lineHeight: "18px",
        fontColor: "#000000",
        text: "a我们输入过多的文字来测试看看它会不会换行试看看它会不会换行"
}

/**
 * @description: 基本画文字
 * @param {*} ctx 画布上下文
 * @param {*} rect 参数对象
 * { //基本格式
 *  fontSize 字体大小
 *  fontColor 字体颜色
 *  text 文本
 *  x,t,width, height//基本属性
 * }
 * @return {*}
 */
export function fontRext(ctx, rect) {
  ctx.save();
  ctx.font = `${rect.fontSize || "14px"} Microsoft YaHei`;
  ctx.fillStyle = rect.fontColor || "#000000";
  ctx.textAlign = "left";
  ctx.textBaseline = "top";
  ctx.fillText(rect.text, rect.x, rect.y);
  ctx.restore();
}


数据处理
function drawText(rect) {
        const newRect = JSON.parse(JSON.stringify(rect));
        let textWidth = 0; //累计宽度
        let substringIndex = 0; //截取位置

        for (let index = 0; index < rect.text.length; index++) {
          const element = rect.text[index];

          // 获取字体实际高度
          textWidth += element.charCodeAt(0) > 255 ? parseInt(rect.fontSize) : Math.ceil(ctx.measureText(element).width);
          //ctx.measureText(element).width
          // textWidth += 14;
          // 字体累计宽度大于文字宽度
          if (textWidth > (rect.width || option.width)) {
            //画截取字段
            newRect.text = rect.text.substring(substringIndex, index);
            fontRext(ctx, newRect);

            //设置开始下标 和 枢轴 y
            substringIndex = index;
            textWidth = 0;
            //计算得出每行间距
            const lineHeight = parseInt(newRect.lineHeight || newRect.fontSize) - parseInt(newRect.fontSize);
            newRect.y = newRect.y + parseInt(newRect.fontSize) + lineHeight;
          }

          //绘画剩余部分
          if (index === rect.text.length - 1) {
            newRect.text = rect.text.substring(substringIndex, index + 1);
            fontRext(ctx, newRect);
          }
        }
}

绘画图片圆角图片


//数据结构
 {
        type: "image",
        x: 0,
        y: 0,
        width: 350,
        height: 350,
        img: "https://image.huayixh.com/commodity/Banner/ca031f4ab0134ceb9e6d3e081ecadcfc.jpg"
},
const Point = function (x, y) {
  return { x: x, y: y };
};
/**
 * @description: 画圆角
 * @param {*} ctx 画布上下文
 * @param {*} rect
 * {
 * round //圆角大小
 * x,t,width, height//基本属性
 * }
 * @return {*}
 */
export function arcToRect(ctx, rect) {
  var ptA = Point(rect.x + rect.round, rect.y);
  var ptB = Point(rect.x + rect.width, rect.y);
  var ptC = Point(rect.x + rect.width, rect.y + rect.height);
  var ptD = Point(rect.x, rect.y + rect.height);
  var ptE = Point(rect.x, rect.y);
  ctx.beginPath();
  ctx.moveTo(ptA.x, ptA.y);
  ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, rect.round);
  ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, rect.round);
  ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, rect.round);
  ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, rect.round);
  ctx.closePath();
}

/**
 * @description: 画图片
 * @param {*} ctx 画布上下文
 * @param {*} rect
 *  {
 *   round //圆角
 *   x,t,width, height//基本属性
 * }
 * @return {*}
 */
export function imageRect(ctx, rect) {
  ctx.save();
  if (rect.round) {
    arcToRect(ctx, rect);
    ctx.clip();
  }
  ctx.drawImage(rect.img, 0, 0, rect.img.width, rect.img.height, rect.x, rect.y, rect.width, rect.height);
  ctx.restore();
}

//画图像数据处理
function drawImgs(rect) {
        let poster = canvas.createImage(); // 创建一个图片对象
        poster.src = rect.img;
        poster.onload = function () {
          // 监听图片加载完成
          rect.img = poster;
          imageRect(ctx, rect);

          //判断图片是否绘画完成
          imageLength = imageLength - 1;
          if (imageLength === 0) {
            wx.canvasToTempFilePath({
              canvas: canvas,
              fileType: "jpg",
              success(res) {
                resolve(res.tempFilePath);
              },
              fail(err) {
                reject(err);
              }
            });
          }
        };
}