一、canvas
文檔:
https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial
二、數據繪制(單位是像素):
1、繪制文本:
文字的長度超過設置的最大寬度,文字會縮在一起
① 填充文本(實心):
ctx.fillText("這里是文字", 開始繪制文本的點的 x 軸坐標, 開始繪制文本的點的 y 軸坐標[, 文字的最大寬度]);
② 邊框文本(空心):
ctx.strokeText("這里是文字", 開始繪制文本的點的 x 軸坐標, 開始繪制文本的點的 y 軸坐標[, 文字的最大寬度]);
③ 文本超過最大寬度想要換行:
/**
* 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 stringsconst 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 maxWidthconst testLine = line ? line + ' ' + word : word;const metrics = ctx.measureText(testLine);if (metrics.width > maxWidth) {if (line === '') {// Word is too long; split itlet 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 fitlines.push(word.substring(0, splitIndex));line = word.substring(splitIndex); // Remaining part} else {// Push current line and start new line with the wordlines.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 nextStartlines.forEach((line, index) => {ctx.fillText(line, x, y + index * lineHeight, maxWidth);});return y + lines.length * lineHeight; // Next starting Y position
}
④ 文本樣式:
ctx.font="文字大小 粗細 顏色 字體名稱..."
2、繪制矩形:
① 填充矩形(實心):
ctx.fillStyle = '顏色' // 這個是填充的顏色
ctx.fillRect(矩形左上角的起始點x, 矩形左上角的起始點y, 矩形的寬, 矩形的高); // 這個是填充矩形
② 邊框矩形(空心):
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)指定線條的寬度:
ctx.lineWidth = 數字
4、繪制圖片:
圖片盡量使用臨時路徑,即使用uni.canvasToTempFilePath()
函數生成
① 微信小程序不允許使用new Image()
:
使用 canvas.createImage()
② 繪制圖片是一個異步過程,要使用async\await
進行處理
三、簡單的使用代碼:
1、 模版代碼:
<canvas id="myCanvas" type="2d" :style="{ position: 'fixed', top: '-9999px', left: '-9999px', width: canvasWidth + 'px', height: canvasHeight + 'px' }"
></canvas>
2、js
代碼:
// 初始化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 = widthcanvas.height = heightresolve(canvas);});});
},
// 點擊某個按鈕進行模版的繪制
async saveImg() {const that = this// 首先初始化canvasconst 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();};});
}