uniapp使用canvas画海报

uniapp使用canvas画海报

文章将介绍canvas的基本使用,提供各种形状,canvas画网络图片、二维码,保存图片到手机的方法。

dom部分

<canvas
	style="width: 100vw; height: 500px; margin: 0 auto"
	:style="{ height: 1267 * rpx + 'px' }"
	canvas-id="Canvas"
	id="CanvasId"
></canvas>

<view class="sharePosterBtn">
   <view class="sharePosterBtn1" @click="saveImage">保存图片</view>
    <button open-type="share" class="sharePosterBtn2">名片转发</button>
  </view>

画图的方法

async drawCanvas() {
      uni.showLoading({
        title: "加载中",
      });
      let res = uni.getSystemInfoSync();
      let rpx = res.screenWidth / 750;
      let ctx = uni.createCanvasContext("Canvas", this);
      let phone = "../../static/shouji.png";
      let email = "../../static/youxiang2.png";
      let location = "../../static/daohangdizhi.png";
      
      
      let infoRes = await api("businessCardInfo", {
        params: {
          staff_id: this.staff_id
        }
      });
       if (infoRes.code == 0) {
        this.company_info = infoRes.data.company_info;
        this.staff_info = infoRes.data.staff_info;
        this.template_info = infoRes.data.template_info;
      }
      console.log(infoRes, "海报详情");
      let avatar = await this.getImage(this.staff_info.avatar.full_url)
     
      let Qrcode = await this.getQrCode()
      

      this.drawRoundedRect(
        ctx,
        0 * rpx,
        0 * rpx,
        750 * rpx,
        846 * rpx,
        0 * rpx,
        true,
        "#5C606A"
      );

      ctx.setFontSize(34 * rpx);
      ctx.setFillStyle("#ffffff");
      ctx.fillText( "HI,很高兴认识您", 38 * rpx, 110 * rpx);

      ctx.setFontSize(34 * rpx);
      ctx.setFillStyle("#ffffff");
      ctx.fillText( "这是我的名片。", 38 * rpx, 176 * rpx);
    
    //   二维码
      this.drawRoundedRect(
        ctx,
        556 * rpx,
        74 * rpx,
        160 * rpx,
        160 * rpx,
        24 * rpx,
        true,
        "#ffffff"
      );
      ctx.drawImage(Qrcode, 564 * rpx, 84 * rpx, 140 * rpx, 140 * rpx);
      // this.circleImgOne(ctx, firmLogo, 560 * rpx,84 * rpx ,24 * rpx, 160 * rpx, 160 * rpx)

    // 标语 上白线 
      this.drawRoundedRect(
        ctx,
        32 * rpx,
        294 * rpx,
        688 * rpx,
        12 * rpx,
        0 * rpx,
        true,
        "#ffffff"
      );
    //标语 左边
    ctx.setFontSize(66 * rpx);
    ctx.setFillStyle("#ffffff");
    ctx.fillText("#", 50 * rpx, 464 * rpx);

    //   介绍 及 换行处理
      ctx.setFontSize(46 * rpx);
      ctx.setFillStyle("#ffffff");
      let textResult =  this.breakLinesForCanvas(
        ctx,
        this.template_info.params.title,
        510 * rpx,
        46 * rpx
      );
      
      textResult.map((item,index)=>{
        index += index * 70 
        ctx.fillText(item, 122 * rpx, (415 + index) * rpx)
      })

    //标语 右边
    ctx.setFontSize(66 * rpx);
    ctx.setFillStyle("#ffffff");
    ctx.fillText("#", 670 * rpx, 464 * rpx);

    // 标语 下白线 
    this.drawRoundedRect(
      ctx,
      32 * rpx,
      570 * rpx,
      688 * rpx,
      12 * rpx,
      0 * rpx,
      true,
      "#ffffff"
    );

    ctx.setFontSize(30 * rpx);
    ctx.setFillStyle("#ffffff");
    ctx.fillText(this.company_info.name, 484 * rpx, 685 * rpx);

    // 中间白框
      this.drawRoundedRect(
        ctx,
        0 * rpx,
        710 * rpx,
        750 * rpx,
        526 * rpx,  //436+90 填充了底部的footer
        0 * rpx,
        true,
        "#5C606A"
      );
      this.drawRoundedRect(
        ctx,
        0 * rpx,
        710 * rpx,
        750 * rpx,
        436 * rpx,
        60 * rpx,
        true,
        "#ffffff"
      );

    //   // 头像
      this.drawRoundedRect(
        ctx,
        46 * rpx,
        686 * rpx,
        166 * rpx,
        166 * rpx,
        82 * rpx,
        true,
        "#ffffff"
      );
      this.circleImgOne(ctx, avatar, 50 * rpx,690 * rpx ,80 * rpx, 160 * rpx, 160 * rpx)

      ctx.setFontSize(36 * rpx);
      ctx.setFillStyle("#5C606A");
      this.textBold(ctx, this.staff_info.name, 230 * rpx, 782 * rpx);

      ctx.setFontSize(26 * rpx);
      ctx.setFillStyle("#5C606A");
      ctx.fillText(this.staff_info.department_name, 230 * rpx, 835 * rpx);

      ctx.setFontSize(26 * rpx);
      ctx.setFillStyle("#5C606A");
      ctx.fillText(this.staff_info.position, 370 * rpx, 835 * rpx);

    // 分割线
      this.drawRoundedRect(
        ctx,
        0 * rpx,
        890 * rpx,
        750 * rpx,
        1 * rpx,
        0 * rpx,
        true,
        "#E9E9E9"
      );

      ctx.drawImage(phone, 46 * rpx, 945 * rpx, 25 * rpx, 36 * rpx);
      ctx.drawImage(email, 46 * rpx, 1010 * rpx, 35 * rpx, 22 * rpx);
      ctx.drawImage(location, 46 * rpx, 1060 * rpx, 28 * rpx, 36 * rpx);

      ctx.setFontSize(30 * rpx);
      ctx.setFillStyle("#5C606A");
      ctx.fillText(this.staff_info.phone, 110 * rpx, 970 * rpx);
      ctx.setFontSize(30 * rpx);
      ctx.setFillStyle("#5C606A");
      ctx.fillText(this.staff_info.email, 110 * rpx, 1025 * rpx);
      ctx.setFontSize(30 * rpx);
      ctx.setFillStyle("#5C606A");
      ctx.fillText(
        this.company_info.name,
        110 * rpx,
        1086 * rpx
      );

      ctx.setFontSize(20 * rpx);
      ctx.setFillStyle("#737885");
      ctx.fillText("一步云智能营销系统", 34 * rpx, 1206 * rpx);

      ctx.setFontSize(20 * rpx);
      ctx.setFillStyle("#737885");
      ctx.fillText("step technology cloud", 462 * rpx, 1206 * rpx);

      ctx.clip();
      ctx.restore();
      ctx.draw();
      uni.hideLoading();
    }

画各种形状的方法

圆角矩形

/**
    * 绘制圆角矩形
    * @param {*} ctx CanvasContext
    * @param {*} x x轴 坐标
    * @param {*} y y轴 坐标
    * @param {*} width 宽
    * @param {*} height 高
    * @param {*} r r 圆角
    * @param {boolean} fill 是否填充颜色
    */
   drawRoundedRect(ctx, x, y, width, height, r, fill, fillColor) {
     ctx.beginPath();
     ctx.arc(x + r, y + r, r, Math.PI, (Math.PI * 3) / 2);
     ctx.lineTo(width - r + x, y);
     ctx.arc(width - r + x, r + y, r, (Math.PI * 3) / 2, Math.PI * 2);
     ctx.lineTo(width + x, height + y - r);
     ctx.arc(width - r + x, height - r + y, r, 0, (Math.PI * 1) / 2);
     ctx.lineTo(r + x, height + y);
     ctx.arc(r + x, height - r + y, r, (Math.PI * 1) / 2, Math.PI);
     ctx.closePath();
     if (fill) {
       ctx.fillStyle = fillColor;
       ctx.fill();
     }
   },

圆形

// 绘制圆形
    circle(ctx, img, x, y, r) {
      ctx.save();
      let d = r * 2;
      let cx = x + r;
      let cy = y + r;
      ctx.arc(cx, cy, r, 0, 2 * Math.PI);
      ctx.setFillStyle("#FFFFFF");
      ctx.fill();
      ctx.restore();
    },

圆形图片

// 绘制圆形图片
circleImgOne(ctx, img, x, y, r, width, height) {
    ctx.save();
    ctx.beginPath();
    let cx = x + r;
    let cy = y + r;
    ctx.arc(cx, cy, r, 0, 2 * Math.PI);
    ctx.clip();
    ctx.drawImage(img, x, y, width, height);
    ctx.restore();
  },

文本换行

 /**
     * canvas 文本换行计算
     * @param {*} context CanvasContext
     * @param {string} text 文本
     * @param {number} width 内容宽度
     * @param {font} font 字体(字体大小会影响宽)
     */
breakLinesForCanvas(context, text, width, font) {
   
  const 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;
  }
  var result = [];
  var textArray = text.split("\r\n");
  for (let i = 0; i < textArray.length; i++) {
    let item = textArray[i];
    var breakPoint = 0;
    while ((breakPoint = findBreakPoint(item, width, context)) !== -1) {
      result.push(item.substr(0, breakPoint));
      item = item.substr(breakPoint);
    }
    if (item) {
      result.push(item);
    }
  }
  return result;
  
},

字体加粗

 // 字体加粗
    textBold(ctx, v, x, y, width = "") {
      ctx.fillText(v, x, y, width);
      ctx.fillText(v, x + 0.5, y, width);
    },

canvas画网络图片

使用网络图片需要先使用uni.downloadFile下载才能在canvas中渲染

getImage(url){
return new Promise((resolve,reject)=>{
      uni.downloadFile({
      url,
      success: (res) => {
          if (res.statusCode === 200) {
              resolve(res.tempFilePath)
          }
      }
  });
  })
},

然后在绘图方法中使用await,使先获取到图片再进行canvas绘制

let avatar = await this.getImage(this.staff_info.avatar.full_url)

canvas画二维码

渲染二维码也一样需要使用uni.downloadFile,带上token获取二维码

getQrCode(){
     const token = uni.getStorageSync("token");
     return new Promise((resolve,reject)=>{
         uni.downloadFile({
         url:  `https://wxopen.hzyibu.cn/xcx/crm.Card/staffCardQrcode?staff_id=${this.staff_id}`, 
         header: {
             token
         },
         success: (res) => {
             if (res.statusCode === 200) {
                 resolve(res.tempFilePath)
             }
         }
     });
     })
 },

在绘图方法中使用await使先获取到二维码后再进行canvas绘制

let Qrcode = await this.getQrCode()

保存图片

saveImage() {
 uni.canvasToTempFilePath({
    canvasId: "Canvas",
    success: function (res) {
      uni.saveImageToPhotosAlbum({
        filePath: res.tempFilePath,
        success: function () {
          uni.showToast({
            title: "保存成功!",
            icon: "none",
          });
        },
      });
    },
  });
},
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值