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:
architeur
2025-12-14 21:34:03 +01:00
parent c0ae55a597
commit d707c5001d
28 changed files with 3514 additions and 3411 deletions

156
symbols/js/app/export.js Normal file
View File

@@ -0,0 +1,156 @@
// ============================================
// EXPORT - Bild kopieren, SVG/DXF Download
// ============================================
// ========== BILD KOPIEREN (transparent) ==========
async function copyAsImage(id) {
const item = findSymbol(id);
if (!item) return;
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const size = 256;
canvas.width = size;
canvas.height = size;
const img = new Image();
const svgBlob = new Blob([item.svg], { type: 'image/svg+xml;charset=utf-8' });
const url = URL.createObjectURL(svgBlob);
await new Promise((resolve, reject) => {
img.onload = resolve;
img.onerror = reject;
img.src = url;
});
ctx.drawImage(img, 0, 0, size, size);
URL.revokeObjectURL(url);
canvas.toBlob(async (blob) => {
try {
await navigator.clipboard.write([
new ClipboardItem({ 'image/png': blob })
]);
showNotification('Bild in Zwischenablage kopiert!');
} catch (err) {
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = item.filename.replace('.svg', '.png');
link.click();
showNotification('PNG heruntergeladen (Kopieren nicht unterstützt)');
}
}, 'image/png');
} catch (err) {
console.error('Fehler beim Bild-Export:', err);
showNotification('Fehler beim Kopieren', 'error');
}
}
// ========== SVG DOWNLOAD ==========
function downloadSVG(id) {
const item = findSymbol(id);
if (!item) return;
const blob = new Blob([item.svg], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = item.filename;
link.click();
URL.revokeObjectURL(url);
showNotification('SVG heruntergeladen!');
}
// ========== DXF DOWNLOAD ==========
function downloadDXF(id) {
const item = findSymbol(id);
if (!item) return;
const dxf = svgToDxf(item.dxfSvg || item.svg, 1);
const blob = new Blob([dxf], { type: 'application/dxf' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = item.filename.replace('.svg', '.dxf');
link.click();
URL.revokeObjectURL(url);
showNotification('DXF heruntergeladen!');
}
// ========== PNG/JPG DOWNLOAD ==========
async function downloadSymbolPNG(id) {
var symbol = findSymbol(id);
if (!symbol) return;
try {
var canvas = await svgToCanvas(symbol.svg, 2);
canvas.toBlob(function(blob) {
var link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = symbol.id + '.png';
link.click();
URL.revokeObjectURL(link.href);
showNotification('PNG heruntergeladen!');
}, 'image/png');
} catch (err) {
console.error('Fehler:', err);
showNotification('Fehler beim PNG-Export', 'error');
}
}
async function downloadSymbolJPG(id) {
var symbol = findSymbol(id);
if (!symbol) return;
try {
var canvas = await svgToCanvas(symbol.svg, 2);
var tempCanvas = document.createElement('canvas');
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
var tempCtx = tempCanvas.getContext('2d');
tempCtx.fillStyle = '#FFFFFF';
tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
tempCtx.drawImage(canvas, 0, 0);
tempCanvas.toBlob(function(blob) {
var link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = symbol.id + '.jpg';
link.click();
URL.revokeObjectURL(link.href);
showNotification('JPG heruntergeladen!');
}, 'image/jpeg', 0.95);
} catch (err) {
console.error('Fehler:', err);
showNotification('Fehler beim JPG-Export', 'error');
}
}
// ========== ZIP EXPORT ==========
async function downloadAllAsZip() {
showNotification('ZIP wird erstellt...', 'info');
const files = [];
Object.keys(SYMBOLS).forEach(categoryKey => {
const category = SYMBOLS[categoryKey];
category.items.forEach(item => {
files.push({
name: `${categoryKey}/${item.filename}`,
content: item.svg
});
files.push({
name: `${categoryKey}/${item.filename.replace('.svg', '.dxf')}`,
content: svgToDxf(item.svg, 1)
});
});
});
const info = `Symbolbibliothek enthält ${files.length / 2} Symbole in ${Object.keys(SYMBOLS).length} Kategorien.\n\n` +
`Für den ZIP-Download empfehlen wir, die Symbole einzeln herunterzuladen.`;
alert(info);
showNotification('ZIP-Export: Siehe Hinweis', 'info');
}