From 94c57b4708c3e71459633d16edcbcf5aa56c59e6 Mon Sep 17 00:00:00 2001 From: igurielidze Date: Mon, 30 Mar 2026 17:58:17 +0400 Subject: [PATCH] Export conveyors/extendos/photoeyes as programmatic SVG paths Replaces embedded SVG export (which used non-uniform scale transforms that stretched strokes) with programmatic path/rect elements matching the canvas renderer. Consistent 0.5px stroke at any size. Co-Authored-By: Claude Opus 4.6 (1M context) --- svelte-app/src/lib/export.ts | 42 +++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/svelte-app/src/lib/export.ts b/svelte-app/src/lib/export.ts index bda235e..4e91010 100644 --- a/svelte-app/src/lib/export.ts +++ b/svelte-app/src/lib/export.ts @@ -1,5 +1,5 @@ import { layout } from './stores/layout.svelte.js'; -import { isEpcType, isInductionType, isSpurType, isCurvedType, getSymbolGroup, EPC_CONFIG, INDUCTION_CONFIG, getCurveGeometry } from './symbols.js'; +import { isEpcType, isInductionType, isSpurType, isCurvedType, isRectConveyanceType, isExtendoType, isPhotoeyeType, getSymbolGroup, EPC_CONFIG, INDUCTION_CONFIG, PHOTOEYE_CONFIG, getCurveGeometry } from './symbols.js'; import { deserializeSymbol } from './serialization.js'; import type { PlacedSymbol } from './types.js'; @@ -74,6 +74,46 @@ export async function exportSVG() { const w2 = sym.w2 ?? sym.w; const d = `M ${sym.x},${sym.y} L ${sym.x + w2},${sym.y} L ${sym.x + sym.w},${sym.y + sym.h} L ${sym.x},${sym.y + sym.h} Z`; lines.push(` `); + } else if (isRectConveyanceType(sym.symbolId)) { + lines.push(` `); + } else if (isExtendoType(sym.symbolId)) { + const bracketW = 10.6 / 31.07 * 73; + const x = sym.x, y = sym.y, w = sym.w, h = sym.h; + const pts = [ + [x + bracketW * 0.44, y + h * 0.085], + [x + bracketW, y + h * 0.085], + [x + bracketW, y + h * 0.222], + [x + w, y + h * 0.222], + [x + w, y + h * 0.780], + [x + bracketW, y + h * 0.780], + [x + bracketW, y + h * 0.917], + [x + bracketW * 0.44, y + h * 0.916], + [x + bracketW * 0.34, y + h * 0.985], + [x, y + h * 0.980], + [x, y + h * 0.017], + [x + bracketW * 0.34, y + h * 0.016], + ]; + const d = `M ${pts[0][0]},${pts[0][1]} ` + pts.slice(1).map(p => `L ${p[0]},${p[1]}`).join(' ') + ' Z'; + lines.push(` `); + } else if (isPhotoeyeType(sym.symbolId)) { + const { leftCap, rightCap } = PHOTOEYE_CONFIG; + const x = sym.x, y = sym.y, w = sym.w, h = sym.h; + const pts = [ + [x + leftCap, y + h * 0.42], + [x + leftCap, y + h * 0.248], + [x, y + h * 0.05], + [x, y + h * 0.948], + [x + leftCap, y + h * 0.744], + [x + leftCap, y + h * 0.585], + [x + w - rightCap, y + h * 0.585], + [x + w - rightCap, y + h * 0.826], + [x + w, y + h * 0.826], + [x + w, y + h * 0.181], + [x + w - rightCap, y + h * 0.181], + [x + w - rightCap, y + h * 0.42], + ]; + const d = `M ${pts[0][0]},${pts[0][1]} ` + pts.slice(1).map(p => `L ${p[0]},${p[1]}`).join(' ') + ' Z'; + lines.push(` `); } else { // Regular SVG symbol try {