From 3e5aad12371dcbb150746bc09d36cb646a6f93b1 Mon Sep 17 00:00:00 2001 From: xudan Date: Tue, 12 Aug 2025 16:47:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E5=8C=BA=E6=96=87=E5=AD=97=E6=B8=B2=E6=9F=93=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E5=8A=A8=E6=80=81=E8=B0=83=E6=95=B4=E5=AD=97=E4=BD=93?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E4=BB=A5=E9=80=82=E5=BA=94=E5=8C=BA=E5=9F=9F?= =?UTF-8?q?=E5=B9=B6=E7=A1=AE=E4=BF=9D=E6=96=87=E6=9C=AC=E5=9E=82=E7=9B=B4?= =?UTF-8?q?=E5=B1=85=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/editor.service.ts | 57 ++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/services/editor.service.ts b/src/services/editor.service.ts index 11bfdd8..bad20d5 100644 --- a/src/services/editor.service.ts +++ b/src/services/editor.service.ts @@ -1466,38 +1466,47 @@ function drawArea(ctx: CanvasRenderingContext2D, pen: MapPen): void { // 如果是描述区且有描述内容,渲染描述文字 if (type === MapAreaType.描述区 && desc) { ctx.fillStyle = get(theme, 'color') ?? ''; - // 使用更大的字体显示描述文字 - const descFontSize = Math.min(w / 6, h / 1.5, 128); // 根据区域大小自适应字体大小,最大128px - ctx.font = `${descFontSize}px ${fontFamily}`; - ctx.textAlign = 'center'; - ctx.textBaseline = 'top'; // 使用 top 基准,便于精确计算 - // 文字换行处理 - const words = desc.split(''); - const maxCharsPerLine = Math.floor(w / (descFontSize * 0.6)); // 估算每行能容纳的字符数 - const lines: string[] = []; + // 动态计算字体大小,让文字填充区域 + let descFontSize = Math.min(w / 2, h / 2, 200); + let lines: string[] = []; - for (let i = 0; i < words.length; i += maxCharsPerLine) { - lines.push(words.slice(i, i + maxCharsPerLine).join('')); + while (descFontSize > 8) { + ctx.font = `${descFontSize}px ${fontFamily}`; + const maxCharsPerLine = Math.floor(w / (descFontSize * 0.8)); + + if (maxCharsPerLine < 1) { + descFontSize = Math.floor(descFontSize * 0.9); + continue; + } + + // 文字换行 + lines = []; + for (let i = 0; i < desc.length; i += maxCharsPerLine) { + lines.push(desc.slice(i, i + maxCharsPerLine)); + } + + // 计算文本高度 + const textMetrics = ctx.measureText('测试文字'); + const lineHeight = textMetrics.actualBoundingBoxAscent + textMetrics.actualBoundingBoxDescent; + const totalHeight = lines.length * lineHeight * 1.1; + + if (totalHeight <= h * 0.9) break; + descFontSize = Math.floor(descFontSize * 0.9); } - // 使用 measureText 精确计算字体高度 - const testText = '测试文字'; // 用于测量字体高度的测试文字 - const textMetrics = ctx.measureText(testText); - const actualFontHeight = textMetrics.actualBoundingBoxAscent + textMetrics.actualBoundingBoxDescent; - const lineSpacing = actualFontHeight * 0.2; // 行间距为字体高度的20% - const descLineHeight = actualFontHeight + lineSpacing; + // 渲染文字 + ctx.font = `${descFontSize}px ${fontFamily}`; + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; - // 计算整个文本块的总高度 - const totalHeight = lines.length * descLineHeight - lineSpacing; // 减去最后一行不需要的行间距 - - // 计算文本块的起始Y坐标,确保整个文本块在区域中垂直居中 + const textMetrics = ctx.measureText('测试文字'); + const lineHeight = textMetrics.actualBoundingBoxAscent + textMetrics.actualBoundingBoxDescent; + const totalHeight = lines.length * lineHeight * 1.1; const startY = y + h / 2 - totalHeight / 2; lines.forEach((line, index) => { - const lineY = startY + index * descLineHeight; - // 水平居中:x + w / 2,垂直居中:lineY - ctx.fillText(line, x + w / 2, lineY); + ctx.fillText(line, x + w / 2, startY + index * lineHeight * 1.1); }); } else if (type !== MapAreaType.描述区 && label) { // 非描述区才显示标签