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) { // 非描述区才显示标签