From 3adbfffb9d69fcc15eb6e14e2624a8061307c7e2 Mon Sep 17 00:00:00 2001 From: igurielidze Date: Mon, 30 Mar 2026 21:32:23 +0400 Subject: [PATCH] Spur label: position at 75% height in the wide bottom portion Center text at 75% of trapezoid height where the shape is widest, using the actual width at that height for proper fit. Co-Authored-By: Claude Opus 4.6 (1M context) --- svelte-app/src/lib/canvas/renderer.ts | 13 +++++++------ svelte-app/src/lib/export.ts | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/svelte-app/src/lib/canvas/renderer.ts b/svelte-app/src/lib/canvas/renderer.ts index 44cdcfb..0518702 100644 --- a/svelte-app/src/lib/canvas/renderer.ts +++ b/svelte-app/src/lib/canvas/renderer.ts @@ -556,12 +556,13 @@ function drawConveyanceLabel(ctx: CanvasRenderingContext2D, sym: PlacedSymbol) { let cx: number, cy: number, availW: number, availH: number; if (isSpurType(sym.symbolId)) { const w2 = sym.w2 ?? sym.w; - // Center text at the wide end of the trapezoid - const wideEnd = Math.max(w2, sym.w); - cx = sym.x + wideEnd / 2; - cy = sym.y + sym.h / 2; - availW = wideEnd - pad * 2; - availH = sym.h - pad * 2; + // Center in the wider half of the trapezoid (bottom half where w > w2) + // At 75% height, width = w2 + 0.75*(w-w2) = w2*0.25 + w*0.75 + const widthAt75 = w2 * 0.25 + sym.w * 0.75; + cx = sym.x + widthAt75 / 2; + cy = sym.y + sym.h * 0.75; + availW = widthAt75 - pad * 2; + availH = sym.h * 0.45; } else { cx = sym.x + sym.w / 2; cy = sym.y + sym.h / 2; diff --git a/svelte-app/src/lib/export.ts b/svelte-app/src/lib/export.ts index 8fde604..4d24ebe 100644 --- a/svelte-app/src/lib/export.ts +++ b/svelte-app/src/lib/export.ts @@ -44,10 +44,10 @@ function emitConveyanceLabelInner(lines: string[], sym: PlacedSymbol) { textRotDeg = (textRotRad * 180) / Math.PI; } else if (isSpurType(sym.symbolId)) { const w2 = sym.w2 ?? sym.w; - const wideEnd = Math.max(w2, sym.w); - labelCx = sym.x + wideEnd / 2; - labelCy = sym.y + sym.h / 2; - availH = sym.h - 4; + const widthAt75 = w2 * 0.25 + sym.w * 0.75; + labelCx = sym.x + widthAt75 / 2; + labelCy = sym.y + sym.h * 0.75; + availH = sym.h * 0.45; } else if (isInductionType(sym.symbolId)) { const stripTopY = sym.y + sym.h * INDUCTION_CONFIG.stripTopFrac; const stripBottomY = sym.y + sym.h * INDUCTION_CONFIG.stripBottomFrac;