Canvas绘图:如何绘制不覆盖文本的二次曲线?
解决Canvas曲线与文本重叠的问题
针对你遇到的曲线和中心文本重叠的问题,这里提供两种实用的解决思路:
方法一:调整绘制层级(曲线在文本下方)
最简单的方式是改变绘制顺序,通过合成模式让曲线显示在文本下方,避免覆盖:
// 先绘制文本 const text = 'text on curve'; const textMeasurement = ctx.measureText(text); const middlePoints = this._getControlPoints(); const textXPoint = middlePoints[0] - textMeasurement.width / 2; ctx.fillText(text, textXPoint, middlePoints[1]); // 设置合成模式,让后续绘制的内容显示在已有内容下方 ctx.globalCompositeOperation = 'destination-over'; // 绘制曲线 const startPoints = this._getStartPoints(); const endPoints = this._getEndPoints(); ctx.moveTo(...startPoints); ctx.quadraticCurveTo(...this.getControlPoints(), ...endPoints); ctx.stroke(); // 恢复默认合成模式 ctx.globalCompositeOperation = 'source-over';
方法二:拆分曲线绕开文本区域(曲线在文本两侧断开)
如果需要曲线完全避开文本区域,不穿过文本位置,可以计算文本的边界范围,将二次曲线拆分为两段绘制:
const text = 'text on curve'; const textMeasurement = ctx.measureText(text); const middlePoints = this._getControlPoints(); const textXStart = middlePoints[0] - textMeasurement.width / 2; const textXEnd = middlePoints[0] + textMeasurement.width / 2; // 文本垂直范围(行高按字体大小1.2倍估算,可按需调整) const fontSize = parseInt(ctx.font); const textYRange = fontSize * 0.6; // 定义文本两侧的曲线过渡点(可根据曲线形态微调位置) const leftCurveEnd = [textXStart - 10, middlePoints[1]]; const rightCurveStart = [textXEnd + 10, middlePoints[1]]; // 绘制左侧曲线段 const startPoints = this._getStartPoints(); ctx.moveTo(...startPoints); ctx.quadraticCurveTo(middlePoints[0], middlePoints[1], ...leftCurveEnd); ctx.stroke(); // 绘制右侧曲线段 const endPoints = this._getEndPoints(); ctx.moveTo(...rightCurveStart); ctx.quadraticCurveTo(middlePoints[0], middlePoints[1], ...endPoints); ctx.stroke(); // 最后绘制文本 ctx.fillText(text, textXStart, middlePoints[1]);
说明:方法二中的过渡点可以根据你的实际曲线形态进一步优化,若需要更精准的路径,可通过数学方法求解二次曲线与文本边界矩形的交点坐标。
内容的提问来源于stack exchange,提问作者mediumgoal
相关产品推荐
相关产品推荐

