Uniapp编写微信小程序,使用canvas进行绘图

一、canvas文档:

https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial

二、数据绘制(单位是像素):

1、绘制文本:

文字的长度超过设置的最大宽度,文字会缩在一起

① 填充文本(实心):

html 复制代码
ctx.fillText("这里是文字", 开始绘制文本的点的 x 轴坐标, 开始绘制文本的点的 y 轴坐标[, 文字的最大宽度]);

② 边框文本(空心):

html 复制代码
ctx.strokeText("这里是文字", 开始绘制文本的点的 x 轴坐标, 开始绘制文本的点的 y 轴坐标[, 文字的最大宽度]);

③ 文本超过最大宽度想要换行:

javascript 复制代码
/**
* ctx:canvas元素
* x:开始绘制文本的点的 x 轴坐标
* y:开始绘制文本的点的 y 轴坐标
* lineHeight: 文本的行高
* maxWidth:文字的最大宽度
* 返回值:下一行文字的起始位置y坐标
**/ 
function drawWrappedText(ctx, text, x, y, lineHeight, maxWidth) {
    // Split text into words using spaces, filtering out empty strings
    const words = text.split(/\s+/g).filter(word => word.length > 0);
    let line = '';
    const lines = [];
    
    for (const word of words) {
        // Check if adding the word (with space) exceeds maxWidth
        const testLine = line ? line + ' ' + word : word;
        const metrics = ctx.measureText(testLine);
        
        if (metrics.width > maxWidth) {
            if (line === '') {
                // Word is too long; split it
                let splitIndex = 1;
                while (splitIndex < word.length) {
                    const part = word.substring(0, splitIndex);
                    if (ctx.measureText(part).width > maxWidth) break;
                    splitIndex++;
                }
                splitIndex = Math.max(1, splitIndex - 1); // Adjust to fit
                lines.push(word.substring(0, splitIndex));
                line = word.substring(splitIndex); // Remaining part
            } else {
                // Push current line and start new line with the word
                lines.push(line);
                line = word;
            }
        } else {
            line = testLine; // Add word to current line
        }
    }
    if (line) lines.push(line); // Add the last line
    
    // Draw each line and calculate nextStart
    lines.forEach((line, index) => {
        ctx.fillText(line, x, y + index * lineHeight, maxWidth);
    });
    
    return y + lines.length * lineHeight; // Next starting Y position
}

④ 文本样式:

javascript 复制代码
ctx.font="文字大小 粗细 颜色 字体名称..."

2、绘制矩形:

① 填充矩形(实心):

html 复制代码
ctx.fillStyle = '颜色'  // 这个是填充的颜色
ctx.fillRect(矩形左上角的起始点x, 矩形左上角的起始点y, 矩形的宽, 矩形的高); // 这个是填充矩形

② 边框矩形(空心):

html 复制代码
ctx.strokeRect(边框左上角的起始点x, 边框左上角的起始点y, 边框的宽, 边框的高);
ctx.strokeStyle = '颜色' // 这个是矩形线条边框的颜色

3、绘制路径:

① 新建一条路径:ctx.beginPath()

② 移动笔触设置起点:ctx.moveTo(路径的起点x,路径的起点y);

③ 绘制路径:

(1)直线:

ctx.lineTo(直线结束点x,直线结束点y);

  • 只要线条轮廓:ctx.stroke()
  • 需要填充:ctx.fill()
(2)闭合路径绘制(连接起点和终点):

ctx.closePath()

(3)指定线条的宽度:
javascript 复制代码
ctx.lineWidth = 数字

4、绘制图片:

图片尽量使用临时路径,即使用uni.canvasToTempFilePath()函数生成

① 微信小程序不允许使用new Image()

使用 canvas.createImage()

② 绘制图片是一个异步过程,要使用async\await进行处理

三、简单的使用代码:

1、 模版代码:

html 复制代码
<canvas 
  id="myCanvas" 
  type="2d" 
  :style="{ position: 'fixed', top: '-9999px', left: '-9999px', width: canvasWidth + 'px', height: canvasHeight + 'px' }"
></canvas>

2、js代码:

javascript 复制代码
// 初始化canvas
async createCanvas(width, height) {
	return new Promise((resolve) => {
	  const query = uni.createSelectorQuery().in(this);
	  query.select('#myCanvas').fields({ node: true, size: true }).exec(res => {
		const canvas = res[0].node;
		// const dpr = uni.getSystemInfoSync().pixelRatio;
		// canvas.width = width * dpr;
		// canvas.height = height * dpr;
		canvas.width = width
		canvas.height = height
		resolve(canvas);
	  });
	});
},
// 点击某个按钮进行模版的绘制
async saveImg() {
	const that = this
	// 首先初始化canvas
	const canvas = await that.createCanvas(图片的宽, 图片的高);
	const ctx = canvas.getContext('2d');
	// 拿到当前设备的像素比
	const dpr = uni.getSystemInfoSync().pixelRatio;
	// 绘制内容:
	await that.drawImage(canvas, ctx, 图片的临时路径, 221,58, 108, 108);
},
async drawImage(canvas,ctx, imagePath, x, y, width, height) {
	return new Promise((resolve) => {
	  const img = canvas.createImage();
	  img.src = imagePath;
	  img.onload = () => {
		ctx.drawImage(img, x, y, width, height);
		resolve();
	  };
	});
}
相关推荐
耶啵奶膘3 小时前
uniapp——地图路线绘制map
uni-app
shadouqi3 小时前
uniapp实现图片预览,懒加载,下拉刷新等
uni-app
唐青枫4 小时前
C#.NET log4net 详解
c#·.net
走,带你去玩5 小时前
uniapp 微信小程序水印
微信小程序·小程序·uni-app
是一碗螺丝粉5 小时前
🔥 微信H5视频自动播放终极秘籍:WeixinJSBridge竟是官方“通行证”?
微信小程序
一笑code6 小时前
vue/微信小程序/h5 实现react的boundary
微信小程序·vue·react
菌菇汤7 小时前
uni-app实现单选,多选也能搜索,勾选,选择,回显
前端·javascript·vue.js·微信小程序·uni-app·app
Nemo_XP10 小时前
HttpHelper类处理两种HTTP POST请求
c#
某公司摸鱼前端14 小时前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
lijingguang17 小时前
在C#中根据URL下载文件并保存到本地,可以使用以下方法(推荐使用现代异步方式)
开发语言·c#