Refactor symbols app: split large files (max 300 lines)
- Split styles.css (1319 lines) into 6 CSS modules: - base.css, layout.css, modal.css, text-generator.css, components.css, legend.css - Split app.js (1219 lines) into 8 JS modules: - core.js, custom.js, dxf.js, export.js, legend.js, legend-export.js, path-parser.js, utils.js - Split symbols.js (870 lines) into 10 JS modules: - index.js, schaeden.js, werkzeuge.js, bauteile.js, moebel.js, sanitaer.js, vermessung.js, vermessung-infra.js, vermessung-topo.js, init.js - Updated index.html to load new modular files All files now comply with 300-line maximum rule. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
183
symbols/js/app/dxf.js
Normal file
183
symbols/js/app/dxf.js
Normal file
@@ -0,0 +1,183 @@
|
||||
// ============================================
|
||||
// DXF - AutoCAD R12 Export
|
||||
// ============================================
|
||||
|
||||
function svgToDxf(svgString, scaleFactor = 1) {
|
||||
const parser = new DOMParser();
|
||||
const svg = parser.parseFromString(svgString, 'image/svg+xml').documentElement;
|
||||
|
||||
const viewBox = svg.getAttribute('viewBox')?.split(' ').map(Number) || [0, 0, 64, 64];
|
||||
const height = viewBox[3];
|
||||
|
||||
let entities = '';
|
||||
|
||||
function flipY(y) {
|
||||
return (height - y) * scaleFactor;
|
||||
}
|
||||
|
||||
function scaleX(x) {
|
||||
return x * scaleFactor;
|
||||
}
|
||||
|
||||
function processElement(el) {
|
||||
const tag = el.tagName?.toLowerCase();
|
||||
if (!tag) return;
|
||||
|
||||
switch(tag) {
|
||||
case 'line':
|
||||
const x1 = parseFloat(el.getAttribute('x1') || 0);
|
||||
const y1 = parseFloat(el.getAttribute('y1') || 0);
|
||||
const x2 = parseFloat(el.getAttribute('x2') || 0);
|
||||
const y2 = parseFloat(el.getAttribute('y2') || 0);
|
||||
entities += createDxfLine(scaleX(x1), flipY(y1), scaleX(x2), flipY(y2));
|
||||
break;
|
||||
|
||||
case 'rect':
|
||||
const rx = parseFloat(el.getAttribute('x') || 0);
|
||||
const ry = parseFloat(el.getAttribute('y') || 0);
|
||||
const rw = parseFloat(el.getAttribute('width') || 0);
|
||||
const rh = parseFloat(el.getAttribute('height') || 0);
|
||||
entities += createDxfLine(scaleX(rx), flipY(ry), scaleX(rx + rw), flipY(ry));
|
||||
entities += createDxfLine(scaleX(rx + rw), flipY(ry), scaleX(rx + rw), flipY(ry + rh));
|
||||
entities += createDxfLine(scaleX(rx + rw), flipY(ry + rh), scaleX(rx), flipY(ry + rh));
|
||||
entities += createDxfLine(scaleX(rx), flipY(ry + rh), scaleX(rx), flipY(ry));
|
||||
break;
|
||||
|
||||
case 'circle':
|
||||
const cx = parseFloat(el.getAttribute('cx') || 0);
|
||||
const cy = parseFloat(el.getAttribute('cy') || 0);
|
||||
const r = parseFloat(el.getAttribute('r') || 0);
|
||||
entities += createDxfCircle(scaleX(cx), flipY(cy), r * scaleFactor);
|
||||
break;
|
||||
|
||||
case 'ellipse':
|
||||
const ecx = parseFloat(el.getAttribute('cx') || 0);
|
||||
const ecy = parseFloat(el.getAttribute('cy') || 0);
|
||||
const erx = parseFloat(el.getAttribute('rx') || 0);
|
||||
const ery = parseFloat(el.getAttribute('ry') || 0);
|
||||
entities += createDxfCircle(scaleX(ecx), flipY(ecy), ((erx + ery) / 2) * scaleFactor);
|
||||
break;
|
||||
|
||||
case 'polygon':
|
||||
case 'polyline':
|
||||
const points = el.getAttribute('points');
|
||||
if (points) {
|
||||
const pts = points.trim().split(/[\s,]+/).map(Number);
|
||||
for (let i = 0; i < pts.length - 2; i += 2) {
|
||||
entities += createDxfLine(
|
||||
scaleX(pts[i]), flipY(pts[i+1]),
|
||||
scaleX(pts[i+2]), flipY(pts[i+3])
|
||||
);
|
||||
}
|
||||
if (tag === 'polygon' && pts.length >= 4) {
|
||||
entities += createDxfLine(
|
||||
scaleX(pts[pts.length-2]), flipY(pts[pts.length-1]),
|
||||
scaleX(pts[0]), flipY(pts[1])
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'path':
|
||||
const d = el.getAttribute('d');
|
||||
if (d) {
|
||||
const pathEntities = parseSvgPath(d, scaleX, flipY);
|
||||
entities += pathEntities;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'text':
|
||||
const tx = parseFloat(el.getAttribute('x') || 0);
|
||||
const ty = parseFloat(el.getAttribute('y') || 0);
|
||||
const textContent = el.textContent || '';
|
||||
const fontSize = parseFloat(el.getAttribute('font-size') || 10);
|
||||
entities += createDxfText(scaleX(tx), flipY(ty), textContent, fontSize * scaleFactor * 0.7);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'svg':
|
||||
Array.from(el.children).forEach(child => processElement(child));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
processElement(svg);
|
||||
|
||||
const dxf = [
|
||||
'0', 'SECTION',
|
||||
'2', 'HEADER',
|
||||
'9', '$ACADVER',
|
||||
'1', 'AC1009',
|
||||
'9', '$INSBASE',
|
||||
'10', '0.0',
|
||||
'20', '0.0',
|
||||
'30', '0.0',
|
||||
'9', '$EXTMIN',
|
||||
'10', '0.0',
|
||||
'20', '0.0',
|
||||
'30', '0.0',
|
||||
'9', '$EXTMAX',
|
||||
'10', String(height * scaleFactor),
|
||||
'20', String(height * scaleFactor),
|
||||
'30', '0.0',
|
||||
'0', 'ENDSEC',
|
||||
'0', 'SECTION',
|
||||
'2', 'TABLES',
|
||||
'0', 'TABLE',
|
||||
'2', 'LAYER',
|
||||
'70', '1',
|
||||
'0', 'LAYER',
|
||||
'2', '0',
|
||||
'70', '0',
|
||||
'62', '7',
|
||||
'6', 'CONTINUOUS',
|
||||
'0', 'ENDTAB',
|
||||
'0', 'ENDSEC',
|
||||
'0', 'SECTION',
|
||||
'2', 'ENTITIES',
|
||||
entities,
|
||||
'0', 'ENDSEC',
|
||||
'0', 'EOF'
|
||||
].join('\r\n');
|
||||
|
||||
return dxf;
|
||||
}
|
||||
|
||||
function createDxfLine(x1, y1, x2, y2) {
|
||||
return [
|
||||
'0', 'LINE',
|
||||
'8', '0',
|
||||
'10', x1.toFixed(4),
|
||||
'20', y1.toFixed(4),
|
||||
'30', '0.0',
|
||||
'11', x2.toFixed(4),
|
||||
'21', y2.toFixed(4),
|
||||
'31', '0.0',
|
||||
''
|
||||
].join('\r\n');
|
||||
}
|
||||
|
||||
function createDxfCircle(cx, cy, r) {
|
||||
return [
|
||||
'0', 'CIRCLE',
|
||||
'8', '0',
|
||||
'10', cx.toFixed(4),
|
||||
'20', cy.toFixed(4),
|
||||
'30', '0.0',
|
||||
'40', r.toFixed(4),
|
||||
''
|
||||
].join('\r\n');
|
||||
}
|
||||
|
||||
function createDxfText(x, y, text, height) {
|
||||
return [
|
||||
'0', 'TEXT',
|
||||
'8', '0',
|
||||
'10', x.toFixed(4),
|
||||
'20', y.toFixed(4),
|
||||
'30', '0.0',
|
||||
'40', height.toFixed(4),
|
||||
'1', text,
|
||||
''
|
||||
].join('\r\n');
|
||||
}
|
||||
Reference in New Issue
Block a user