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) <noreply@anthropic.com>
This commit is contained in:
igurielidze 2026-03-30 17:58:17 +04:00
parent b0648f06b6
commit 94c57b4708

View File

@ -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(` <path ${idAttr} d="${d}" fill="#ffffff" stroke="#000000" stroke-width="0.5"${outerTransform ? ` transform="${outerTransform}"` : ''} />`);
} else if (isRectConveyanceType(sym.symbolId)) {
lines.push(` <rect ${idAttr} x="${sym.x}" y="${sym.y}" width="${sym.w}" height="${sym.h}" fill="#ffffff" stroke="#000000" stroke-width="0.5"${outerTransform ? ` transform="${outerTransform}"` : ''} />`);
} 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(` <path ${idAttr} d="${d}" fill="#ffffff" stroke="#000000" stroke-width="0.5"${outerTransform ? ` transform="${outerTransform}"` : ''} />`);
} 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(` <path ${idAttr} d="${d}" fill="#ffffff" stroke="#000000" stroke-width="0.5"${outerTransform ? ` transform="${outerTransform}"` : ''} />`);
} else {
// Regular SVG symbol
try {