美文网首页
封装常用的canvas工具类

封装常用的canvas工具类

作者: 小仙有毒_1991 | 来源:发表于2023-11-21 09:32 被阅读0次

    canvas绘图工具库

    一、引言

    一个canvas绘图工具库,在开发小程序时编写的用于绘制图形的工具函数。

    二、使用场景

    基于最新 Canvas 2D API封装,这个库包含一系列开箱即用的函数,它们非常适用于微信小程序上各种复杂的Canvas绘图场景,如文字、图形、图片的绘制,以及内容的清除和导出等。

    三、函数列表:

    1 drawAutoWrapText(ctx, x, y, content, maxWidth, lineHeight, fontFamily, fontSize, fontColor, isCenter = false)

    该函数用于在canvas上绘制带有自动换行功能的文本内容。
    参数描述:

    • ctx: canvas的绘图环境上下文

    • x,y: 文字的起始坐标

    • content: 需要绘制的文本内容

    • maxWidth: 文本内容的最大宽度

    • lineHeight: 文本行的高度

    • fontFamily: 字体家族

    • fontSize: 字体大小

    • fontColor: 字体颜色

    • isCenter(可选): 文本是否居中对齐,默认值为false

    2 drawRoundRectPathWithArc(ctx, x, y, width, height, radius)

    该函数致力于在canvas上使用arc()方法绘制圆角矩形路径。
    参数描述:

    • ctx: canvas的绘图环境上下文

    • x,y: 圆角矩形的左上角的坐标

    • width,height: 圆角矩形的宽和高

    • radius: 圆角的半径参数描述:

    3 drawRoundRectPathWithArcTo(ctx, x, y, width, height, radius)

    该函数的目标是在canvas上使用arcTo()方法绘制圆角矩形路径。
    参数描述:

    • ctx: canvas的绘图环境上下文

    • x,y: 圆角矩形的左上角的坐标

    • width,height: 圆角矩形的宽和高

    • radius: 圆角的半径

    4 fillRoundRectPath(ctx, x, y, width, height, radius, color)

    这个函数用于填充圆角矩形路径的背景颜色。
    参数描述:

    • ctx: canvas的绘图环境上下文

    • x,y: 圆角矩形的左上角的坐标

    • width,height: 圆角矩形的宽和高

    • radius: 圆角的半径

    • color: 需要填充的颜色

    5 drawRoundRectImg(ctx, x, y, width, height, radius, img)

    该函数专门用于在圆角矩形内填充图片。
    参数描述:

    • ctx: canvas的绘图环境上下文

    • x,y: 圆角矩形的左上角的坐标

    • width,height: 圆角矩形的宽和高

    • radius: 圆角的半径

    • img: 需要填充的图片源地址

    6 strokeRoundRectPath(ctx, x, y, width, height, radius)

    此函数用以在圆角矩形路径上创建一个虚框。
    参数描述:

    • ctx: canvas的绘图环境上下文

    • x,y: 圆角矩形的左上角的坐标

    • width,height: 圆角矩形的宽和高

    • radius: 圆角的半径

    7 drawCircle(ctx, x, y, radius, startAngle, endAngle, anticlockwise = false)

    该函数可以在canvas上绘制一个圆或圆弧。
    参数描述:

    • ctx: canvas的绘图环境上下文

    • x,y: 圆的中心坐标

    • radius: 圆的半径

    • startAngle,endAngle: 规定圆弧起始和结束的弧度

    • anticlockwise(可选): 是否逆时针绘制,默认为false

    8 clearRect(ctx, x, y, width, height)

    该函数可以清除canvas上特定区域的内容。
    参数描述:

    • ctx: canvas的绘图环境上下文

    • x,y: 需要清除区域的左上角的坐标

    • width,height: 需要清除的区域的宽和高

    9 wxGetImageInfo(url)

    此函数 Promise 形式返回,用于异步获取图片信息。
    参数描述:

    • url: 需要获取信息的图片的链接

    11-1 exportImg(canvas, w, h, calc = 2)

    此函数 Promise 形式返回,用于将当前canvas的特定区域导出,并生成指定大小的图片。
    参数描述:

    • canvas: 当前的canvas对象

    • w,h: 图片导出的宽和高

    • calc(可选): 图片质量,数值越高质量越好,默认为2,应小于3

    11 computeRender(o_w, o_h, r_w)

    此函数用于根据原始图片的宽高和渲染的宽度,从而计算出渲染的高度。
    参数描述:

    • o_w,o_h: 原始图片的宽和高

    • r_w: 渲染图片的宽度

    12 drawImage(canvas, ctx, bannerInfo, x, y, width, height)

    此函数 Promise 形式返回,用于在canvas上绘制图片。
    参数描述:

    • canvas: 当前的canvas对象

    • ctx: canvas的绘图环境上下文

    • bannerInfo: 包含图片信息的对象,例如图片 path

    • x,y: 图片的起始坐标

    • width,height: 需要绘制的图片的宽和高

    参考

    canvas | MDN

    微信小程序画布教程

    /*
     * @Author: 梁佩乐 liangpeile@vchangyi.com
     * @Date: 2023-11-10 16:00:56
     * @LastEditors: 梁佩乐 liangpeile@vchangyi.com
     * @LastEditTime: 2023-11-16 17:41:53
     * @FilePath: \activity-web-wx-app\src\pagesA\canvas-learn\canvas.js
     * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
     */
    /**
     * 该函数用于在canvas上绘制带有自动换行功能的文本内容。
     * @param {*} ctx: canvas的绘图环境上下文
     * @param {number} x,y : 文字的起始坐标
     * @param {string} content: 需要绘制的文本内容
     * @param {number} maxWidth: 文本内容的最大宽度
     * @param {number} lineHeight: 文本行的高度
     * @param {string} fontFamily: 字体家族
     * @param {number} fontSize: 字体大小
     * @param {string} fontColor: 字体颜色
     * @param {boolean} isCenter(可选): 文本是否居中对齐,默认值为false
     */
    function drawAutoWrapText(
      ctx,
      x,
      y,
      content,
      maxWidth,
      lineHeight,
      fontFamily,
      fontSize,
      fontColor,
      isCenter = false
    ) {
      ctx.font = `${fontSize}px ${fontFamily}`;
      ctx.fillStyle = fontColor;
      if (isCenter) ctx.textAlign = 'center';
      let words = content.split(''); // 将字符串分割成一个个字符
      let line = '';
      for (let n = 0; n < words.length; n++) {
        let testLine = line + words[n];
        let metrics = ctx.measureText(testLine);
        let testWidth = metrics.width;
        if (testWidth > maxWidth && n > 0) {
          ctx.fillText(line, x, y);
          line = words[n];
          y += lineHeight;
        } else {
          line = testLine;
        }
      }
      if (isCenter) ctx.fillText(line, (x + maxWidth) / 2, y);
      if (!isCenter) ctx.fillText(line, x, y);
    }
    
    /**
     * 该函数致力于在canvas上使用arc()方法绘制圆角矩形路径。
     * 使用arc()方式绘制弧线 按照canvas的弧度从 0 - 2PI 开始顺时针绘制
     * @param {*} ctx: canvas的绘图环境上下文
     * @param {number} x,y: 圆角矩形的左上角的坐标
     * @param {number} width,height: 圆角矩形的宽和高
     * @param {number} radius: 圆角的半径
     */
    function drawRoundRectPathWithArc(ctx, x, y, width, height, radius) {
      ctx.beginPath();
      // 从右下角顺时针绘制,弧度从0到1/2PI
      ctx.arc(x + width - radius, y + height - radius, radius, 0, Math.PI / 2);
    
      // 矩形下边线
      ctx.lineTo(x + radius, y + height);
    
      // 左下角圆弧,弧度从1/2PI到PI
      ctx.arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
    
      // 矩形左边线
      ctx.lineTo(x, y + radius);
    
      // 左上角圆弧,弧度从PI到3/2PI
      ctx.arc(x + radius, y + radius, radius, Math.PI, (Math.PI * 3) / 2);
    
      // 上边线
      ctx.lineTo(x + width - radius, y);
    
      //右上角圆弧
      ctx.arc(
        x + width - radius,
        y + radius,
        radius,
        (Math.PI * 3) / 2,
        Math.PI * 2
      );
    
      //右边线
      ctx.lineTo(x + width, y + height - radius);
      ctx.closePath();
    }
    /**
     * 该函数的目标是在canvas上使用arcTo()方法绘制圆角矩形路径。
     * 使用arc()方式 两个切线之间的弧
     * 根据控制点和半径绘制圆弧路径,使用当前的描点 (前一个 moveTo 或 lineTo 等函数的止点)。根据当前描点与给定的控制点 1 连接的直线,和控制点 1 与控制点 2 连接的直线,作为使用指定半径的圆的切线,画出两条切线之间的弧线路径
     * @param {*} ctx  canvas的绘图环境上下文
     * @param {number} x 圆角矩形的左上角的坐标
     * @param {number} y 圆角矩形的左上角的坐标
     * @param {number} width 圆角矩形的宽
     * @param {number} height 圆角矩形的高
     * @param {number} radius 圆角的半径
     */
    function drawRoundRectPathWithArcTo(ctx, x, y, width, height, radius) {
      ctx.beginPath();
    
      // 上边线
      ctx.lineTo(x + width - radius, y);
    
      // 右上弧线 控制点1(x + width, y) 、控制点2( x + width , y + radius, radius)  radius
      ctx.arcTo(x + width, y, x + width, y + radius, radius);
    
      //右边线
      ctx.lineTo(x + width, y + height - radius);
    
      // 从右下角顺时针绘制,弧度从0到1/2PI
      ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);
    
      // 矩形下边线
      ctx.lineTo(x + radius, y + height);
    
      // 左下角圆弧,弧度从1/2PI到PI
      ctx.arcTo(x, y + height, x, y + height - radius, radius);
    
      // 矩形左边线
      ctx.lineTo(x, y + radius);
    
      // 左上角圆弧,弧度从PI到3/2PI
      ctx.arcTo(x, y, x + radius, y, radius);
    
      ctx.closePath();
    }
    /**
     * 这个函数用于填充圆角矩形路径的背景颜色。
     * @param {*} ctx canvas的绘图环境上下文
     * @param {number} x 圆角矩形的左上角的坐标
     * @param {number} y
     * @param {number} width 圆角矩形的宽
     * @param {number} height 圆角矩形的高
     * @param {number} radius 圆角的半径
     * @param {string} color 需要填充的颜色
     */
    function fillRoundRectPath(ctx, x, y, width, height, radius, color) {
      ctx.save();
      this.drawRoundRectPathWithArc(ctx, x, y, width, height, radius);
      ctx.fillStyle = color;
      ctx.fill();
      ctx.restore();
    }
    /**
     * 该函数专门用于在圆角矩形内填充图片
     * @param {*} ctx  canvas的绘图环境上下文
     * @param {*} x 圆角矩形的左上角的坐标
     * @param {*} y
     * @param {*} width 圆角矩形的宽
     * @param {*} height 圆角矩形的高
     * @param {*} radius 圆角的半径
     * @param {*} img 需要填充的图片源地址
     * @returns
     */
    function drawRoundRectImg(ctx, x, y, width, height, radius, img) {
      if (!img) return;
      ctx.save();
      this.drawRoundRectPathWithArc(ctx, x, y, width, height, radius);
      // 剪切  原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
      ctx.clip();
      ctx.drawImage(img, x, y, width, height);
      ctx.restore();
    }
    /**
     * 此函数用以在圆角矩形路径上创建一个虚框。
     * @param {*} ctx  canvas的绘图环境上下文
     * @param {number} x 圆角矩形的左上角的坐标
     * @param {number} y
     * @param {number} width 圆角矩形的宽
     * @param {number} height 圆角矩形的高
     * @param {number} radius 圆角的半径
     */
    function strokeRoundRectPath(
      ctx,
      x,
      y,
      width,
      height,
      radius,
      borderWidth = 0.5,
      borderColor = '#ddd'
    ) {
      this.drawRoundRectPathWithArc(ctx, x, y, width, height, radius);
      ctx.strokeStyle = borderColor;
      ctx.lineWidth = borderWidth;
      ctx.setLineDash([6, 5]);
      ctx.stroke();
    }
    
    /**
     * 该函数可以在canvas上绘制一个圆或圆弧
     * @param {*} ctx canvas的绘图环境上下文
     * @param {number} xy 圆的中心坐标
     * @param {number} radius  圆的半径
     * @param {number} startAngle,x 轴方向开始计算,单位以弧度表示
     * @param {number} endAngle 结束的弧度
     * @param {boolean} anticlockwise(可选): 是否逆时针绘制,默认为false
     * drawCircle(ctx,100, 75, 50, 0, 2 * Math.PI)
     */
    function drawCircle(
      ctx,
      x,
      y,
      radius,
      startAngle,
      endAngle,
      anticlockwise = false
    ) {
      ctx.beginPath();
    
      ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
    
      ctx.stroke();
      ctx.closePath();
    }
    
    /**
     * 该函数可以清除canvas上特定区域的内容。
     * @param {*} ctx  canvas的绘图环境上下文
     * @param {number} x 需要清除区域的左上角的坐标
     * @param {number} y
     * @param {number} width 需要清除的区域的宽
     * @param {number} height 需要清除的区域的高
     */
    function clearRect(ctx, x, y, width, height) {
      ctx.clearRect(x, y, width, height);
    }
    
    /**
     * 此函数 Promise 形式返回,用于异步获取图片信息。
     * 获取图片信息方法。网络图片需先配置download域名才能生效
     * @param {String} url 图片的路径,支持网络路径、本地路径、代码包路径
     */
    const wxGetImageInfo = (url) => {
      return new Promise((resolve, reject) => {
        if (!url) resolve();
        wx.getImageInfo({
          src: url,
          success: function (res) {
            resolve(res);
          },
          fail: function (res) {
            wx.showToast({
              title: '获取图片信息失败!',
              icon: 'none',
              duration: 3000,
              mask: true
            });
            reject(res);
          }
        });
      });
    };
    
    /**
     * 画布导出图片
     * @param {*} canvas  画布
     * @param {number} x 指定的画布区域的左上角横x坐标
     * @param {number} y 指定的画布区域的左上角横y坐标
     * @param {number} width 指定的画布宽
     * @param {number} height 指定的画布高
     * @param {number} calc 导出画布的
     * @returns
     */
    const exportImg = (canvas, x, y, width, height, calc = 2) => {
      return new Promise((resolve, reject) => {
        wx.canvasToTempFilePath(
          {
            canvas,
            x: x,
            y: y,
            width: width,
            height: height,
            destWidth: width * calc,
            destHeight: height * calc,
            success: function ({ tempFilePath }) {
              wx.getImageInfo({
                src: tempFilePath,
                success: (res) => {
                  resolve(res);
                }
              });
            },
            fail(err) {
              reject(err);
            }
          },
          this
        );
      });
    };
    /**
     * 此函数用于根据原始图片的宽高和渲染的宽度,从而计算出渲染的高度。
     * @param {number} o_w 原始图片的宽
     * @param {number} o_h 原始图片的高
     * @param {number} r_w 需要渲染的宽
     * @returns
     */
    const computeRender = (o_w, o_h, r_w) => {
      return {
        width: r_w,
        height: (r_w * o_h) / o_w
      };
    };
    /**
     * 此函数 Promise 形式返回,用于在canvas上绘制图片。
     * 传入path(图片https路径),在画布绘制图片
     * @param {*} canvas 当前的canvas对象
     * @param {*} ctx canvas的绘图环境上下文
     * @param {string} path 包含图片的path
     * @param {number} x 图片的起始坐标x
     * @param {number} y 图片的起始坐标y
     * @param {number} width 需要绘制的图片的宽
     * @param {number} height 需要绘制的图片的高
     */
    function drawImage(canvas, ctx, path, x, y, width, height) {
      return new Promise(async (resolve, reject) => {
        const bannerReader = canvas.createImage();
        bannerReader.onload = () => {
          try {
            ctx.drawImage(bannerReader, x, y, width, height);
            resolve();
          } catch (e) {
            reject();
            console.error('绘制背景图', e);
          }
        };
        bannerReader.src = path;
      });
    }
    export default {
      computeRender,
      drawAutoWrapText,
      fillRoundRectPath,
      drawRoundRectPathWithArc,
      drawRoundRectPathWithArcTo,
      drawRoundRectImg,
      strokeRoundRectPath,
      drawCircle,
      clearRect,
      wxGetImageInfo,
      exportImg,
      drawImage
    };
    

    相关文章

      网友评论

          本文标题:封装常用的canvas工具类

          本文链接:https://www.haomeiwen.com/subject/agkvwdtx.html