小程序 canvas 2d 绘制海报

效果图

在这里插入图片描述

canvas api 准备

绘制图片

context.drawImage(image, dx, dy, dWidth, dHeight);

image:绘制在Canvas上的元素,可以是各类Canvas图片资源(见CanvasImageSource),如图片,SVG图像,Canvas元素本身等。
dx:在Canvas画布上规划一片区域用来放置图片,dx就是这片区域的左上角横坐标。
dy:在Canvas画布上规划一片区域用来放置图片,dy就是这片区域的左上角纵坐标。
dWidth:在Canvas画布上规划一片区域用来放置图片,dWidth就是这片区域的宽度。
dHeight:在Canvas画布上规划一片区域用来放置图片,dHeight就是这片区域的高度。

绘制文字

context.fillText(text, x, y [, maxWidth]);

text:用来填充的文本信息
x:填充文本的起点横坐标。
y:填充文本的起点纵坐标。
maxWidth:填充文本的最大宽度,超出会压缩文本宽度而非换行

绘制圆

context.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);

x:圆弧对应的圆心横坐标。
y:圆弧对应的圆心纵坐标。
radius:圆弧的半径大小。
startAngle:圆弧开始的角度,单位是弧度。
endAngle:圆弧结束的角度,单位是弧度。
anticlockwise:弧度的开始到结束的绘制是按照顺时针来算,还是按时逆时针来算。如何设置为true,则表示按照逆时针方向从startAngle绘制到endAngle。

裁切

context.clip();

比例:用来适配不同屏幕

比例 = 可使用窗口宽度 / 设计稿宽度

const ratio = wx.getSystemInfoSync()?.windowWidth / 750;

解决 canvas 绘制不清晰

const dpr = wx.getSystemInfoSync().pixelRatio;
canvas.width = width * dpr;
canvas.height = height * dpr;
context.scale(dpr, dpr);

说明绘制圆的参数如何得到

context.arc(122 * ratio, 100 * ratio, 30 * ratio, 0, (Math.PI / 180) * 360);

头像半径 30
头像距左边 92
头像距上边 70
x = 92 + 30
y = 70 + 30
r = 30
startAngle = 0
endAngle = (Math.PI / 180) * 360) 弧度转换为角度相对友好
在这里插入图片描述

完整代码

html

<canvas type="2d" id="myCanvas"></canvas>

css

#myCanvas{
  margin: 50rpx auto;
  width: 422rpx;
  height: 338rpx;
}

js

initCanvas() {
    let that = this;
    const query = wx.createSelectorQuery();
    query
      .select("#myCanvas")
      .fields({ node: true, size: true })
      .exec(async (res) => {
        const width = res[0].width;
        const height = res[0].height;
        const canvas = res[0].node;

        const context = canvas.getContext("2d");
        // 比例
        const ratio = wx.getSystemInfoSync()?.windowWidth / 750;

        const dpr = wx.getSystemInfoSync().pixelRatio;
        canvas.width = width * dpr;
        canvas.height = height * dpr;
        context.scale(dpr, dpr);

        that.setData({
          canvas,
        });

        // 绘制背景
        context.beginPath();
        await that.loadImg(
          "/pages/serviceChain/img/auth_share.png",
          canvas,
          context,
          0,
          0,
          422 * ratio,
          338 * ratio
        );

        // 绘制文字
        let name = wx.getStorageSync(
          `${wx.getStorageSync("currentUid")}_userInfo`
        )?.name;
        if (name.length > 5) {
          name = name.slice(0, 5) + "...";
        }
        context.beginPath();
        context.font = `22*${ratio}`;
        context.textAlign = "center";
        context.fillText(name, 60 * ratio, 212 * ratio, 70 * ratio);

        // 绘制圆
        context.beginPath();
        context.arc(
          60 * ratio,
          158 * ratio,
          30 * ratio,
          0,
          (Math.PI / 180) * 360
        );
        context.fill();
        context.clip();

        // 绘制头像
        context.beginPath();
        const avatar = wx.getStorageSync(
          `${wx.getStorageSync("currentUid")}_userInfo`
        )?.image;
        await that.loadImg(
          avatar,
          canvas,
          context,
          30 * ratio,
          128 * ratio,
          60 * ratio,
          60 * ratio
        );
      });
  },

  save() {
    return new Promise((resolve, reject) => {
      wx.canvasToTempFilePath({
        canvas: this.data.canvas,
        success: (res) => {
          return resolve(res.tempFilePath);
          // wx.saveImageToPhotosAlbum({
          //   filePath: res.tempFilePath,
          //   success(res) {
          //     wx.showToast({
          //       title: "保存成功,请在相册中查看",
          //     });
          //   },
          // });
        },
        fail(error) {
          return reject(error);
        },
      });
    });
  },

  loadImg(src, canvas, context, x, y, width, height) {
    return new Promise((resolve, reject) => {
      try {
        const img = canvas.createImage();
        img.src = src;
        img.onload = function () {
          context.drawImage(img, x, y, width, height);
          resolve(canvas.toDataURL("image/png"));
        };
      } catch (error) {
        reject(error);
      }
    });
  },

  async onShareAppMessage() {
    const res = await this.save();
    return {
      path: `/pages/`,
      imageUrl: res,
    };
  },
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值