From 9fe61721610d2e783cdf3a0d30cd3bc1752873c4 Mon Sep 17 00:00:00 2001 From: igurielidze Date: Mon, 30 Mar 2026 21:38:41 +0400 Subject: [PATCH] Spur label: position at 90-degree side (x=0 to x=w2 rectangle) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 90-degree corners are at x=0 in local coords. The rectangular region from x=0 to x=min(w2,w) always fits inside the trapezoid. Text is centered in this safe zone — on the straight-edge side, not the angled side. Co-Authored-By: Claude Opus 4.6 (1M context) --- svelte-app/src/lib/canvas/renderer.ts | 11 ++++++----- svelte-app/src/lib/export.ts | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/svelte-app/src/lib/canvas/renderer.ts b/svelte-app/src/lib/canvas/renderer.ts index 4077556..301494e 100644 --- a/svelte-app/src/lib/canvas/renderer.ts +++ b/svelte-app/src/lib/canvas/renderer.ts @@ -556,11 +556,12 @@ 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 right-angle corner (w, h) where the most space is. - // The right edge at mid-height is at (w2+w)/2. Shift further right. - cx = sym.x + sym.w * 0.65; - cy = sym.y + sym.h * 0.65; - availW = sym.w; + // The 90° corners are at x=0 (left edge). The rectangular region + // from x=0 to x=min(w2,w) always fits inside the trapezoid. + const safeW = Math.min(w2, sym.w); + cx = sym.x + safeW / 2; + cy = sym.y + sym.h / 2; + availW = safeW; availH = sym.h; } else { cx = sym.x + sym.w / 2; diff --git a/svelte-app/src/lib/export.ts b/svelte-app/src/lib/export.ts index 0e18852..20f226d 100644 --- a/svelte-app/src/lib/export.ts +++ b/svelte-app/src/lib/export.ts @@ -43,8 +43,10 @@ function emitConveyanceLabelInner(lines: string[], sym: PlacedSymbol) { // Mirror: label follows the mirrored shape naturally textRotDeg = (textRotRad * 180) / Math.PI; } else if (isSpurType(sym.symbolId)) { - labelCx = sym.x + sym.w * 0.65; - labelCy = sym.y + sym.h * 0.65; + const w2 = sym.w2 ?? sym.w; + const safeW = Math.min(w2, sym.w); + labelCx = sym.x + safeW / 2; + labelCy = sym.y + sym.h / 2; availH = sym.h; } else if (isInductionType(sym.symbolId)) { const stripTopY = sym.y + sym.h * INDUCTION_CONFIG.stripTopFrac;