封装常用的canvas工具类
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
: 需要绘制的图片的宽和高
参考
/*
* @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
};