Files
architeur c0ae55a597 Refactor symbols app: cleanup and fix issues
- Removed duplicate files (index2/3/4.html, symbols.js duplicates)
- Kept index4.html as the main index.html (modular version)
- Removed old text-generator.js (replaced by modular version)
- Fixed ID mismatch in ui-bindings.js to match HTML
- Added square and circle shape support in svg-generator.js
- Added legend preview with copy functionality
- Removed 580 lines of obsolete text-generator v4 code from app.js
- Added addTextToLegend and addStandaloneArrowToLegend to export.js

Still TODO: Split large files to comply with 300 line limit
- app.js: 1219 lines
- styles.css: 1319 lines
- symbols.js: 870 lines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 21:09:39 +01:00

363 lines
12 KiB
JavaScript

/**
* Export-Funktionen fuer Text-Symbole
*/
var TextExport = {
// SVG zu Canvas rendern
svgToCanvas: function(svgString, scale) {
return new Promise(function(resolve, reject) {
var img = new Image();
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var parser = new DOMParser();
var svgDoc = parser.parseFromString(svgString, 'image/svg+xml');
var svgEl = svgDoc.documentElement;
var width = parseFloat(svgEl.getAttribute('width')) || 200;
var height = parseFloat(svgEl.getAttribute('height')) || 100;
canvas.width = width * scale;
canvas.height = height * scale;
var blob = new Blob([svgString], { type: 'image/svg+xml' });
var url = URL.createObjectURL(blob);
img.onload = function() {
ctx.scale(scale, scale);
ctx.drawImage(img, 0, 0);
URL.revokeObjectURL(url);
resolve(canvas);
};
img.onerror = function(e) {
URL.revokeObjectURL(url);
reject(e);
};
img.src = url;
});
},
// In Zwischenablage kopieren (als PNG)
copyAsImage: function(svgString, scale) {
var self = this;
scale = scale || 3;
return this.svgToCanvas(svgString, scale).then(function(canvas) {
return new Promise(function(resolve, reject) {
canvas.toBlob(function(blob) {
if (!blob) {
reject(new Error('Canvas toBlob failed'));
return;
}
navigator.clipboard.write([
new ClipboardItem({ 'image/png': blob })
]).then(resolve).catch(reject);
}, 'image/png');
});
});
},
// SVG in Zwischenablage
copySvg: function(svgString) {
return navigator.clipboard.writeText(svgString);
},
// SVG herunterladen
downloadSvg: function(svgString, filename) {
var blob = new Blob([svgString], { type: 'image/svg+xml' });
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = filename || 'symbol.svg';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
},
// PNG herunterladen
downloadPng: function(svgString, filename, scale) {
scale = scale || 3;
return this.svgToCanvas(svgString, scale).then(function(canvas) {
var url = canvas.toDataURL('image/png');
var a = document.createElement('a');
a.href = url;
a.download = filename || 'symbol.png';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
},
// JPG herunterladen
downloadJpg: function(svgString, filename, scale, bgColor) {
scale = scale || 3;
bgColor = bgColor || '#ffffff';
return this.svgToCanvas(svgString, scale).then(function(canvas) {
// Neues Canvas mit Hintergrund
var bgCanvas = document.createElement('canvas');
bgCanvas.width = canvas.width;
bgCanvas.height = canvas.height;
var ctx = bgCanvas.getContext('2d');
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, bgCanvas.width, bgCanvas.height);
ctx.drawImage(canvas, 0, 0);
var url = bgCanvas.toDataURL('image/jpeg', 0.95);
var a = document.createElement('a');
a.href = url;
a.download = filename || 'symbol.jpg';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
},
// DXF generieren (vereinfacht - nur Linien)
svgToDxf: function(svgString) {
var parser = new DOMParser();
var svgDoc = parser.parseFromString(svgString, 'image/svg+xml');
var svgEl = svgDoc.documentElement;
var width = parseFloat(svgEl.getAttribute('width')) || 200;
var height = parseFloat(svgEl.getAttribute('height')) || 100;
var dxf = '0\nSECTION\n2\nENTITIES\n';
// Rechtecke
var rects = svgEl.querySelectorAll('rect');
rects.forEach(function(rect) {
var x = parseFloat(rect.getAttribute('x')) || 0;
var y = parseFloat(rect.getAttribute('y')) || 0;
var w = parseFloat(rect.getAttribute('width')) || 0;
var h = parseFloat(rect.getAttribute('height')) || 0;
var fy = height - y;
dxf += '0\nLINE\n8\n0\n';
dxf += '10\n' + x + '\n20\n' + fy + '\n30\n0\n';
dxf += '11\n' + (x + w) + '\n21\n' + fy + '\n31\n0\n';
dxf += '0\nLINE\n8\n0\n';
dxf += '10\n' + (x + w) + '\n20\n' + fy + '\n30\n0\n';
dxf += '11\n' + (x + w) + '\n21\n' + (fy - h) + '\n31\n0\n';
dxf += '0\nLINE\n8\n0\n';
dxf += '10\n' + (x + w) + '\n20\n' + (fy - h) + '\n30\n0\n';
dxf += '11\n' + x + '\n21\n' + (fy - h) + '\n31\n0\n';
dxf += '0\nLINE\n8\n0\n';
dxf += '10\n' + x + '\n20\n' + (fy - h) + '\n30\n0\n';
dxf += '11\n' + x + '\n21\n' + fy + '\n31\n0\n';
});
// Pfade (vereinfacht)
var paths = svgEl.querySelectorAll('path');
paths.forEach(function(path) {
var d = path.getAttribute('d');
if (!d) return;
var points = [];
var parts = d.match(/[ML]\s*[\d.-]+\s+[\d.-]+/g);
if (parts) {
parts.forEach(function(part) {
var nums = part.match(/[\d.-]+/g);
if (nums && nums.length >= 2) {
points.push({ x: parseFloat(nums[0]), y: parseFloat(nums[1]) });
}
});
}
for (var i = 0; i < points.length - 1; i++) {
dxf += '0\nLINE\n8\n0\n';
dxf += '10\n' + points[i].x + '\n20\n' + (height - points[i].y) + '\n30\n0\n';
dxf += '11\n' + points[i + 1].x + '\n21\n' + (height - points[i + 1].y) + '\n31\n0\n';
}
});
// Text (als Hinweis)
var texts = svgEl.querySelectorAll('text');
texts.forEach(function(text) {
var x = parseFloat(text.getAttribute('x')) || 0;
var y = parseFloat(text.getAttribute('y')) || 0;
var content = text.textContent || '';
dxf += '0\nTEXT\n8\n0\n';
dxf += '10\n' + x + '\n20\n' + (height - y) + '\n30\n0\n';
dxf += '40\n10\n1\n' + content + '\n';
});
dxf += '0\nENDSEC\n0\nEOF\n';
return dxf;
},
// DXF herunterladen
downloadDxf: function(svgString, filename) {
var dxf = this.svgToDxf(svgString);
var blob = new Blob([dxf], { type: 'application/dxf' });
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = filename || 'symbol.dxf';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
},
// Feedback anzeigen
showFeedback: function(message, isError) {
var existing = document.querySelector('.export-feedback');
if (existing) existing.remove();
var feedback = document.createElement('div');
feedback.className = 'export-feedback';
feedback.style.cssText = 'position: fixed; bottom: 20px; right: 20px; padding: 12px 20px; border-radius: 8px; font-size: 14px; z-index: 10000; animation: fadeIn 0.3s;';
feedback.style.background = isError ? '#ef4444' : '#10b981';
feedback.style.color = 'white';
feedback.textContent = message;
document.body.appendChild(feedback);
setTimeout(function() {
feedback.style.opacity = '0';
feedback.style.transition = 'opacity 0.3s';
setTimeout(function() { feedback.remove(); }, 300);
}, 2000);
}
};
window.TextExport = TextExport;
// Globale Export-Funktionen fuer onclick-Handler
window.copyTextAsImage = function() {
var svg = window.SvgGenerator.generate(window.TextGenState.current);
window.TextExport.copyAsImage(svg).then(function() {
window.TextExport.showFeedback('Als PNG kopiert!');
}).catch(function(e) {
window.TextExport.showFeedback('Fehler: ' + e.message, true);
});
};
window.copyTextSVG = function() {
var svg = window.SvgGenerator.generate(window.TextGenState.current);
window.TextExport.copySvg(svg).then(function() {
window.TextExport.showFeedback('SVG kopiert!');
});
};
window.downloadTextPNG = function() {
var svg = window.SvgGenerator.generate(window.TextGenState.current);
window.TextExport.downloadPng(svg, 'text-symbol.png');
};
window.downloadTextJPG = function() {
var svg = window.SvgGenerator.generate(window.TextGenState.current);
window.TextExport.downloadJpg(svg, 'text-symbol.jpg');
};
window.downloadTextSVG = function() {
var svg = window.SvgGenerator.generate(window.TextGenState.current);
window.TextExport.downloadSvg(svg, 'text-symbol.svg');
};
window.downloadTextDXF = function() {
var svg = window.SvgGenerator.generate(window.TextGenState.current);
window.TextExport.downloadDxf(svg, 'text-symbol.dxf');
};
window.resetToDefaults = function() {
window.UiBindings.resetToDefaults();
};
// Standalone-Pfeil Funktionen
window.copyStandaloneArrow = function() {
var svg = window.SvgGenerator.generateArrowOnly(window.TextGenState.current);
if (svg) {
window.TextExport.copyAsImage(svg).then(function() {
window.TextExport.showFeedback('Pfeil als PNG kopiert!');
});
}
};
window.copyStandaloneArrowSVG = function() {
var svg = window.SvgGenerator.generateArrowOnly(window.TextGenState.current);
if (svg) {
window.TextExport.copySvg(svg).then(function() {
window.TextExport.showFeedback('Pfeil-SVG kopiert!');
});
}
};
window.downloadStandaloneArrowSVG = function() {
var svg = window.SvgGenerator.generateArrowOnly(window.TextGenState.current);
if (svg) {
window.TextExport.downloadSvg(svg, 'pfeil.svg');
}
};
window.downloadStandaloneArrowPNG = function() {
var svg = window.SvgGenerator.generateArrowOnly(window.TextGenState.current);
if (svg) {
window.TextExport.downloadPng(svg, 'pfeil.png');
}
};
window.downloadStandaloneArrowJPG = function() {
var svg = window.SvgGenerator.generateArrowOnly(window.TextGenState.current);
if (svg) {
window.TextExport.downloadJpg(svg, 'pfeil.jpg');
}
};
window.downloadStandaloneArrowDXF = function() {
var svg = window.SvgGenerator.generateArrowOnly(window.TextGenState.current);
if (svg) {
window.TextExport.downloadDxf(svg, 'pfeil.dxf');
}
};
// Zur Legende hinzufuegen
window.addTextToLegend = function() {
var state = window.TextGenState.current;
var svg = window.SvgGenerator.generate(state);
var name = state.text || 'Text-Symbol';
if (typeof legendItems !== 'undefined' && typeof updateLegendCount === 'function') {
legendItems.push({
id: 'text_' + Date.now(),
name: name.split('\n')[0].substring(0, 30),
svg: svg,
description: ''
});
updateLegendCount();
saveLegendToStorage();
if (typeof showNotification === 'function') {
showNotification('Zur Legende hinzugefuegt!');
}
}
};
window.addStandaloneArrowToLegend = function() {
var state = window.TextGenState.current;
var svg = window.SvgGenerator.generateArrowOnly(state);
if (!svg) return;
if (typeof legendItems !== 'undefined' && typeof updateLegendCount === 'function') {
legendItems.push({
id: 'arrow_' + Date.now(),
name: 'Pfeil ' + state.arrow,
svg: svg,
description: ''
});
updateLegendCount();
saveLegendToStorage();
if (typeof showNotification === 'function') {
showNotification('Pfeil zur Legende hinzugefuegt!');
}
}
};