圆角矩形
/*** 绘制圆角矩形* @param {CanvasRenderingContext2D} ctx - 画布上下文* @param {Object} options - 配置选项* @param {number} options.x - 矩形左上角x坐标* @param {number} options.y - 矩形左上角y坐标* @param {number} options.width - 矩形宽度* @param {number} options.height - 矩形高度* @param {number} options.radius - 圆角半径* @param {string} [options.strokeStyle='#000'] - 描边颜色* @param {string} [options.fillStyle='#000'] - 填充颜色*/
const renderRoundRect = (ctx, {x, y, width, height, radius, strokeStyle = '#000', fillStyle = '#000'}) => {if(fillStyle) {ctx.fillStyle = fillStyle;}if(strokeStyle) {ctx.strokeStyle = strokeStyle;}ctx.beginPath();// 从左上角开始,顺时针绘制ctx.moveTo(x + radius, y);// 上边ctx.lineTo(x + width - radius, y);// 右上角ctx.arcTo(x + width, y, x + width, y + radius, radius);// 右边ctx.lineTo(x + width, y + height - radius);// 右下角ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);// 下边ctx.lineTo(x + radius, y + height);// 左下角ctx.arcTo(x, y + height, x, y + height - radius, radius);// 左边ctx.lineTo(x, y + radius);// 左上角ctx.arcTo(x, y, x + radius, y, radius);ctx.closePath();if(strokeStyle) {ctx.stroke();}if(fillStyle) {ctx.fill();}
}
文本
/*** 绘制文本到画布* @param {CanvasRenderingContext2D} ctx - 画布上下文* @param {string} value - 要绘制的文本内容* @param {Object} options - 绘制选项* @param {string} [options.type='fill'] - 绘制类型('fill'填充文本/'stroke'描边文本)* @param {number} options.x - 文本x坐标* @param {number} options.y - 文本y坐标* @param {string} [options.fillStyle='#000'] - 填充颜色* @param {string} [options.strokeStyle='#000'] - 描边颜色* @param {number} [options.maxWidth] - 文本最大宽度* @param {number} [options.fontSize=12] - 字体大小* @param {string} [options.fontFamily] - 字体家族* @param {string} [options.fontWeight] - 字体粗细* @param {string} [options.textAlign='start'] - 文本对齐方式*/
const text = (ctx, value, {type = 'fill', x, y, fillStyle = '#000', strokeStyle = '#000', maxWidth, fontSize = 12, fontFamily, fontWeight, textAlign ='start' }) => {if(fillStyle) {ctx.fillStyle = fillStyle;}if(strokeStyle) {ctx.strokeStyle = strokeStyle;}const fontConfigList = [fontSize,fontWeight,fontFamily].filter(i => !!i)ctx.font = fontConfigList.join(' ');ctx.textAlign = textAlign;if(type == 'stroke') {ctx.strokeText(value, x, y, maxWidth);} else {ctx.fillText(value,x,y,maxWidth);}
}
阴影
/*** 设置Canvas阴影效果* @param {CanvasRenderingContext2D} ctx - Canvas绘图上下文* @param {Object} options - 阴影配置选项* @param {number} [options.x=0] - 阴影水平偏移量* @param {number} [options.y=0] - 阴影垂直偏移量* @param {string} [options.color='#000'] - 阴影颜色* @param {number} [options.blur=0] - 阴影模糊程度*/
export const shadow = (ctx, {x = 0,y = 0,color = '#000', blur = 0}) => {ctx.shadowOffsetX = x;ctx.shadowOffsetY = y;ctx.shadowBlur = blur;ctx.shadowColor = color;
}
线性渐变
/*** 创建线性渐变对象* @param {CanvasRenderingContext2D} ctx - 画布上下文* @param {Object} config - 渐变配置* @param {Object} config.start - 渐变起点坐标 {x, y}* @param {Object} config.end - 渐变终点坐标 {x, y}* @param {Array} config.stops - 色标数组,每个元素包含value(位置0-1)和color(颜色值)* @returns {CanvasGradient} 返回创建的线性渐变对象*/
export const getLinearGradient = (ctx, {start, end,stops}) => {const {x: startX, y: startY} = start;const {x: endX, y: endY} = end;const linearGradient = ctx.createLinearGradient(startX, startY, endX, endY);stops.forEach(stop => {linearGradient.addColorStop(stop.value, stop.color);});return linearGradient;
}
径向渐变
/*** 创建径向渐变* @param {CanvasRenderingContext2D} ctx - 画布上下文* @param {Object} config - 渐变配置* @param {Object} config.start - 起始圆参数 {x, y, r}* @param {Object} config.end - 结束圆参数 {x, y, r}* @param {Array} config.stops - 色标数组 [{value, color}]* @returns {CanvasGradient} 返回创建的径向渐变对象*/
export const getRadialGradient = (ctx, {start, end,stops}) => {const {x: startX, y: startY, r: startR} = start;const {x: endX, y: endY, r: endR} = end;const radialGradient = ctx.createRadialGradient(startX, startY, startR, endX, endY, endR);stops.forEach(stop => {radialGradient.addColorStop(stop.value, stop.color);});return radialGradient;
}
图案(pattern)
/*** 创建并返回一个Canvas图案对象* @async* @param {CanvasRenderingContext2D} ctx - Canvas上下文对象* @param {Object} options - 配置选项* @param {string} options.src - 图案图片路径* @param {string} [options.repetition='repeat'] - 图案重复方式,可选值:'repeat', 'repeat-x', 'repeat-y', 'no-repeat'* @returns {Promise<CanvasPattern>} 返回一个解析为CanvasPattern对象的Promise* @throws {Error} 当图片加载失败时抛出错误*/
export const getPattern = async (ctx, {src, repetition ='repeat'}) => {const image = wx.createImage();image.src = src;await new Promise((resolve, reject) => {image.onload = () => {resolve()}image.onerror = (err) => {reject(err)}})const pattern = ctx.createPattern(image, repetition);return pattern;
}
- Canvas api文档:https://bucephalus.org/text/CanvasHandbook/CanvasHandbook.html