/** * 绘制圆角矩形 * @param {Object} context - canvas组件的绘图上下文 * @param {Number} x - 矩形的x坐标 * @param {Number} y - 矩形的y坐标 * @param {Number} w - 矩形的宽度 * @param {Number} h - 矩形的高度 * @param {Number} r - 矩形的圆角半径 * @param {String} [c = 'transparent'] - 矩形的填充色 */ const roundRect = (context, x, y, w, h, r, c = 'transparent') => { if (w < 2 * r) { r = w / 2; } if (h < 2 * r) { r = h / 2; } context.beginPath(); context.fillStyle = c; context.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5); context.moveTo(x + r, y); context.lineTo(x + w - r, y); context.lineTo(x + w, y + r); context.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2); context.lineTo(x + w, y + h - r); context.lineTo(x + w - r, y + h); context.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5); context.lineTo(x + r, y + h); context.lineTo(x, y + h - r); context.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI); context.lineTo(x, y + r); context.lineTo(x + r, y); context.fill(); context.closePath(); }; /** * 绘制圆角图片 * @param {Object} context - canvas组件的绘图上下文 * @param {Number} r - 圆角半径 * @param {String} path - 图片地址 * @param {Number} sx - 源图像的矩形选择框的左上角 x 坐标 * @param {Number} sy - 源图像的矩形选择框的左上角 y 坐标 * @param {Number} sWidth - 源图像的矩形选择框的宽度 * @param {Number} sHeight - 源图像的矩形选择框的高度 * @param {Number} dx - 图像的左上角在目标 canvas 上 x 轴的位置 * @param {Number} dy - 图像的左上角在目标 canvas 上 y 轴的位置 * @param {Number} dWidth - 在目标画布上绘制图像的宽度,允许对绘制的图像进行缩放 * @param {Number} dHeight - 在目标画布上绘制图像的高度,允许对绘制的图像进行缩放 * @param {String} c - 矩形的填充色 */ const roundImage = (context, r, path, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, c) => { context.save(); roundRect(context, dx, dy, dWidth, dHeight, r, c); context.fill(); context.clip(); context.drawImage(path, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); context.restore(); }; /** * 绘制圆形图片 * @param {Object} context - canvas组件的绘图上下文 * @param {String} path - 图片地址 * @param {Number} x - 图片的x坐标 * @param {Number} y - 图片的y坐标 * @param {Number} r - 图片的半径 */ const circleImage = (context, path, x, y, r) => { let d = 2 * r; let cx = x + r; let cy = y + r; context.save(); context.beginPath(); context.arc(cx, cy, r, 0, 2 * Math.PI); context.fill(); context.clip(); context.drawImage(path, x, y, d, d); context.restore(); }; /** * 多行文本溢出 * @param {Object} context - canvas组件的绘图上下文 * @param {String} text - 文本内容 * @param {Number} maxWidth - 文本最大宽度 * @param {Number} maxRow - 文本最多显示行数 * @param {String} font - 字体样式 * @param {String} color - 文本颜色 * @param {Number} lineHeight - 文本行高 * @param {Number} x - 文本的x坐标 * @param {Number} y - 文本的y坐标 * @param {String} align - 文本居左居右 * @param {String} decoration - 文字装饰,支持 underline、 overline、 line-through */ const drawTextOverflow = (context, text, maxWidth, maxRow, font, color, lineHeight, x, y,align='left',decoration='') => { let arr = []; let temp = ''; let row = []; text = text.replace(/[\r\n]/g, ''); // 去除回车换行符 arr = text.split(''); //context.font = font; // 注意:一定要先设置字号,否则会出现文本变形 context.setFontSize(font); context.setFillStyle(color); context.setTextAlign(align); if (context.measureText(text).width <= maxWidth) { row.push(text); } else { for (let i = 0; i < arr.length; i++) { // 超出最大行数且字符有剩余,添加... if (row.length == maxRow && i < arr.length - 1) { row[row.length - 1] += '...'; break; } // 字符换行计算 if (context.measureText(temp).width < maxWidth) { temp += arr[i]; // 遍历到最后一位字符 if (i === arr.length - 1) { row.push(temp); } } else { i--; // 防止字符丢失 row.push(temp); temp = ''; } } } // 绘制文本 for (let i = 0; i < row.length; i++) { context.fillText(row[i], x, y + i * lineHeight, maxWidth); } let measuredWith = context.measureText(text).width if (decoration) { context.beginPath(); if (/\bunderline\b/.test(decoration)) { context.moveTo(x, y); context.lineTo(x + measuredWith, y); } if (/\boverline\b/.test(decoration)) { context.moveTo(x, y - font); context.lineTo(x + measuredWith, y - font); } if (/\bline-through\b/.test(decoration)) { context.moveTo(x, y - font / 3); context.lineTo(x + measuredWith, y - font / 3); } context.closePath(); context.strokeStyle = color; context.stroke(); } context.save() return row.length * lineHeight; // 返回文本高度 }; module.exports = { roundRect, roundImage, circleImage, drawTextOverflow }