- 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>
105 lines
3.5 KiB
JavaScript
105 lines
3.5 KiB
JavaScript
// ============================================
|
|
// LEGEND EXPORT - Legenden SVG/PNG Export
|
|
// ============================================
|
|
|
|
function exportLegendSVG() {
|
|
if (legendItems.length === 0) {
|
|
showNotification('Legende ist leer', 'error');
|
|
return;
|
|
}
|
|
|
|
const itemHeight = 50;
|
|
const width = 400;
|
|
const height = legendItems.length * itemHeight + 60;
|
|
|
|
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">
|
|
<rect width="${width}" height="${height}" fill="white"/>
|
|
<text x="20" y="30" font-family="Arial" font-size="18" font-weight="bold">Legende</text>
|
|
<line x1="20" y1="40" x2="${width - 20}" y2="40" stroke="#ccc" stroke-width="1"/>`;
|
|
|
|
legendItems.forEach((item, index) => {
|
|
const y = 60 + index * itemHeight;
|
|
svg += `<g transform="translate(20, ${y})">
|
|
<g transform="scale(0.5)">${item.svg.replace(/<svg[^>]*>/, '').replace('</svg>', '')}</g>
|
|
<text x="50" y="20" font-family="Arial" font-size="14" font-weight="bold">${escapeHtml(item.name)}</text>
|
|
${item.description ? `<text x="50" y="35" font-family="Arial" font-size="11" fill="#666">${escapeHtml(item.description)}</text>` : ''}
|
|
</g>`;
|
|
});
|
|
|
|
svg += '</svg>';
|
|
|
|
const blob = new Blob([svg], { type: 'image/svg+xml' });
|
|
const url = URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = 'legende.svg';
|
|
link.click();
|
|
URL.revokeObjectURL(url);
|
|
showNotification('Legende als SVG exportiert!');
|
|
}
|
|
|
|
function exportLegendPNG() {
|
|
if (legendItems.length === 0) {
|
|
showNotification('Legende ist leer', 'error');
|
|
return;
|
|
}
|
|
|
|
const itemHeight = 50;
|
|
const width = 400;
|
|
const height = legendItems.length * itemHeight + 60;
|
|
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = width * 2;
|
|
canvas.height = height * 2;
|
|
const ctx = canvas.getContext('2d');
|
|
ctx.scale(2, 2);
|
|
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
ctx.fillStyle = '#000';
|
|
ctx.font = 'bold 18px Arial';
|
|
ctx.fillText('Legende', 20, 30);
|
|
|
|
ctx.strokeStyle = '#ccc';
|
|
ctx.beginPath();
|
|
ctx.moveTo(20, 40);
|
|
ctx.lineTo(width - 20, 40);
|
|
ctx.stroke();
|
|
|
|
let loadedCount = 0;
|
|
|
|
legendItems.forEach((item, index) => {
|
|
const y = 60 + index * itemHeight;
|
|
const img = new Image();
|
|
const svgBlob = new Blob([item.svg], { type: 'image/svg+xml' });
|
|
img.src = URL.createObjectURL(svgBlob);
|
|
|
|
img.onload = () => {
|
|
ctx.drawImage(img, 20, y - 5, 32, 32);
|
|
|
|
ctx.fillStyle = '#000';
|
|
ctx.font = 'bold 14px Arial';
|
|
ctx.fillText(item.name, 60, y + 15);
|
|
|
|
if (item.description) {
|
|
ctx.fillStyle = '#666';
|
|
ctx.font = '11px Arial';
|
|
ctx.fillText(item.description, 60, y + 30);
|
|
}
|
|
|
|
loadedCount++;
|
|
if (loadedCount === legendItems.length) {
|
|
canvas.toBlob(blob => {
|
|
const url = URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = 'legende.png';
|
|
link.click();
|
|
URL.revokeObjectURL(url);
|
|
showNotification('Legende als PNG exportiert!');
|
|
}, 'image/png');
|
|
}
|
|
};
|
|
});
|
|
}
|