/** * UI Bindings - Verbindet HTML-Elemente mit dem State */ var UiBindings = { elements: {}, init: function() { this.cacheElements(); this.bindEvents(); this.syncFromState(); this.updateVisibility(); this.updatePreview(); this.updateStandaloneArrowPreview(); }, cacheElements: function() { var e = this.elements; // Text & Farben e.textInput = document.getElementById('textInput'); e.fontSizeInput = document.getElementById('fontSize'); e.fontSizeValue = document.getElementById('fontSizeValue'); e.textColorInput = document.getElementById('textColor'); e.frameColorInput = document.getElementById('frameColor'); // Rahmen e.frameScaleInput = document.getElementById('frameScale'); e.frameScaleValue = document.getElementById('frameScaleValue'); e.frameScaleRow = document.getElementById('frameScaleRow'); // Padding e.paddingAllInput = document.getElementById('framePaddingAll'); e.paddingAllValue = document.getElementById('framePaddingAllValue'); e.paddingTopInput = document.getElementById('framePaddingTop'); e.paddingTopValue = document.getElementById('framePaddingTopValue'); e.paddingRightInput = document.getElementById('framePaddingRight'); e.paddingRightValue = document.getElementById('framePaddingRightValue'); e.paddingBottomInput = document.getElementById('framePaddingBottom'); e.paddingBottomValue = document.getElementById('framePaddingBottomValue'); e.paddingLeftInput = document.getElementById('framePaddingLeft'); e.paddingLeftValue = document.getElementById('framePaddingLeftValue'); e.paddingAllRow = document.getElementById('framePaddingAllRow'); e.paddingRow = document.getElementById('framePaddingRow'); // Pfeil e.arrowLengthInput = document.getElementById('arrowLength'); e.arrowLengthValue = document.getElementById('arrowLengthValue'); e.arrowAngleInput = document.getElementById('arrowAngle'); e.arrowAngleValue = document.getElementById('arrowAngleValue'); e.arrowBendInput = document.getElementById('arrowBend'); e.arrowBendValue = document.getElementById('arrowBendValue'); e.arrowSizeInput = document.getElementById('arrowSize'); e.arrowSizeValue = document.getElementById('arrowSizeValue'); e.arrowTipLengthInput = document.getElementById('arrowTipLength'); e.arrowTipLengthValue = document.getElementById('arrowTipLengthValue'); e.arrowDetailsRow = document.getElementById('arrowDetailsRow'); e.arrowDetailsRow2 = document.getElementById('arrowDetailsRow2'); // Vorschau e.textPreview = document.getElementById('textPreview'); e.standaloneArrowPreview = document.getElementById('standaloneArrowPreview'); // Buttons e.shapeButtons = document.querySelectorAll('.shape-btn'); e.arrowButtons = document.querySelectorAll('.arrow-btn'); e.lineStyleButtons = document.querySelectorAll('.line-style-btn'); e.lineWeightButtons = document.querySelectorAll('.line-weight-btn'); }, bindEvents: function() { var self = this; var e = this.elements; var state = window.TextGenState; // Text-Input if (e.textInput) { e.textInput.addEventListener('input', function(ev) { state.set('text', ev.target.value); self.updatePreview(); }); } // Schriftgroesse if (e.fontSizeInput) { e.fontSizeInput.addEventListener('input', function(ev) { var val = parseInt(ev.target.value); state.set('fontSize', val); if (e.fontSizeValue) e.fontSizeValue.textContent = val + 'px'; self.updatePreview(); }); } // Farben if (e.textColorInput) { e.textColorInput.addEventListener('input', function(ev) { state.set('textColor', ev.target.value); self.updatePreview(); }); } if (e.frameColorInput) { e.frameColorInput.addEventListener('input', function(ev) { state.set('frameColor', ev.target.value); self.updatePreview(); }); } // Rahmen-Skalierung if (e.frameScaleInput) { e.frameScaleInput.addEventListener('input', function(ev) { var val = parseInt(ev.target.value); state.set('frameScale', val); if (e.frameScaleValue) e.frameScaleValue.textContent = val + '%'; self.updatePreview(); }); } // Gesamt-Padding if (e.paddingAllInput) { e.paddingAllInput.addEventListener('input', function(ev) { var val = parseInt(ev.target.value); state.setMultiple({ paddingTop: val, paddingRight: val, paddingBottom: val, paddingLeft: val }); if (e.paddingAllValue) e.paddingAllValue.textContent = val + 'px'; // Einzelne Slider synchronisieren if (e.paddingTopInput) e.paddingTopInput.value = val; if (e.paddingTopValue) e.paddingTopValue.textContent = val + 'px'; if (e.paddingRightInput) e.paddingRightInput.value = val; if (e.paddingRightValue) e.paddingRightValue.textContent = val + 'px'; if (e.paddingBottomInput) e.paddingBottomInput.value = val; if (e.paddingBottomValue) e.paddingBottomValue.textContent = val + 'px'; if (e.paddingLeftInput) e.paddingLeftInput.value = val; if (e.paddingLeftValue) e.paddingLeftValue.textContent = val + 'px'; self.updatePreview(); }); } // Einzelne Paddings this.bindPaddingSlider('paddingTopInput', 'paddingTopValue', 'paddingTop'); this.bindPaddingSlider('paddingRightInput', 'paddingRightValue', 'paddingRight'); this.bindPaddingSlider('paddingBottomInput', 'paddingBottomValue', 'paddingBottom'); this.bindPaddingSlider('paddingLeftInput', 'paddingLeftValue', 'paddingLeft'); // Pfeil-Slider this.bindSlider('arrowLengthInput', 'arrowLengthValue', 'arrowLength', 'px'); this.bindSlider('arrowAngleInput', 'arrowAngleValue', 'arrowAngle', '\u00B0'); this.bindSlider('arrowBendInput', 'arrowBendValue', 'arrowBend', '%'); this.bindSlider('arrowSizeInput', 'arrowSizeValue', 'arrowSize', 'px'); this.bindSlider('arrowTipLengthInput', 'arrowTipLengthValue', 'arrowTipLength', 'px'); // Shape-Buttons e.shapeButtons.forEach(function(btn) { btn.addEventListener('click', function() { e.shapeButtons.forEach(function(b) { b.classList.remove('active'); }); btn.classList.add('active'); state.set('shape', btn.dataset.shape); self.updateVisibility(); self.updatePreview(); }); }); // Arrow-Buttons e.arrowButtons.forEach(function(btn) { btn.addEventListener('click', function() { e.arrowButtons.forEach(function(b) { b.classList.remove('active'); }); btn.classList.add('active'); state.set('arrow', btn.dataset.arrow); self.updateVisibility(); self.updatePreview(); self.updateStandaloneArrowPreview(); }); }); // Line-Style-Buttons e.lineStyleButtons.forEach(function(btn) { btn.addEventListener('click', function() { e.lineStyleButtons.forEach(function(b) { b.classList.remove('active'); }); btn.classList.add('active'); state.set('lineStyle', btn.dataset.style); self.updatePreview(); }); }); // Line-Weight-Buttons e.lineWeightButtons.forEach(function(btn) { btn.addEventListener('click', function() { e.lineWeightButtons.forEach(function(b) { b.classList.remove('active'); }); btn.classList.add('active'); state.set('lineWeight', parseInt(btn.dataset.weight)); self.updatePreview(); }); }); }, bindSlider: function(inputKey, valueKey, stateKey, unit) { var self = this; var input = this.elements[inputKey]; var valueEl = this.elements[valueKey]; var state = window.TextGenState; if (input) { input.addEventListener('input', function(ev) { var val = parseInt(ev.target.value); state.set(stateKey, val); if (valueEl) valueEl.textContent = val + unit; self.updatePreview(); if (stateKey.indexOf('arrow') === 0) { self.updateStandaloneArrowPreview(); } }); } }, bindPaddingSlider: function(inputKey, valueKey, stateKey) { var self = this; var input = this.elements[inputKey]; var valueEl = this.elements[valueKey]; var state = window.TextGenState; if (input) { input.addEventListener('input', function(ev) { var val = parseInt(ev.target.value); state.set(stateKey, val); if (valueEl) valueEl.textContent = val + 'px'; self.updatePreview(); }); } }, syncFromState: function() { var e = this.elements; var s = window.TextGenState.current; if (e.textInput) e.textInput.value = s.text; if (e.fontSizeInput) e.fontSizeInput.value = s.fontSize; if (e.fontSizeValue) e.fontSizeValue.textContent = s.fontSize + 'px'; if (e.textColorInput) e.textColorInput.value = s.textColor; if (e.frameColorInput) e.frameColorInput.value = s.frameColor; if (e.frameScaleInput) e.frameScaleInput.value = s.frameScale; if (e.frameScaleValue) e.frameScaleValue.textContent = s.frameScale + '%'; // Padding if (e.paddingAllInput) e.paddingAllInput.value = s.paddingTop; if (e.paddingAllValue) e.paddingAllValue.textContent = s.paddingTop + 'px'; if (e.paddingTopInput) e.paddingTopInput.value = s.paddingTop; if (e.paddingTopValue) e.paddingTopValue.textContent = s.paddingTop + 'px'; if (e.paddingRightInput) e.paddingRightInput.value = s.paddingRight; if (e.paddingRightValue) e.paddingRightValue.textContent = s.paddingRight + 'px'; if (e.paddingBottomInput) e.paddingBottomInput.value = s.paddingBottom; if (e.paddingBottomValue) e.paddingBottomValue.textContent = s.paddingBottom + 'px'; if (e.paddingLeftInput) e.paddingLeftInput.value = s.paddingLeft; if (e.paddingLeftValue) e.paddingLeftValue.textContent = s.paddingLeft + 'px'; // Pfeil if (e.arrowLengthInput) e.arrowLengthInput.value = s.arrowLength; if (e.arrowLengthValue) e.arrowLengthValue.textContent = s.arrowLength + 'px'; if (e.arrowAngleInput) e.arrowAngleInput.value = s.arrowAngle; if (e.arrowAngleValue) e.arrowAngleValue.textContent = s.arrowAngle + '\u00B0'; if (e.arrowBendInput) e.arrowBendInput.value = s.arrowBend; if (e.arrowBendValue) e.arrowBendValue.textContent = s.arrowBend + '%'; if (e.arrowSizeInput) e.arrowSizeInput.value = s.arrowSize; if (e.arrowSizeValue) e.arrowSizeValue.textContent = s.arrowSize + 'px'; if (e.arrowTipLengthInput) e.arrowTipLengthInput.value = s.arrowTipLength; if (e.arrowTipLengthValue) e.arrowTipLengthValue.textContent = s.arrowTipLength + 'px'; // Buttons aktivieren this.activateButton(e.shapeButtons, 'shape', s.shape); this.activateButton(e.arrowButtons, 'arrow', s.arrow); this.activateButton(e.lineStyleButtons, 'style', s.lineStyle); this.activateButtonByValue(e.lineWeightButtons, 'weight', s.lineWeight); }, activateButton: function(buttons, dataAttr, value) { buttons.forEach(function(btn) { btn.classList.remove('active'); if (btn.dataset[dataAttr] === value) { btn.classList.add('active'); } }); }, activateButtonByValue: function(buttons, dataAttr, value) { buttons.forEach(function(btn) { btn.classList.remove('active'); if (parseInt(btn.dataset[dataAttr]) === value) { btn.classList.add('active'); } }); }, updateVisibility: function() { var e = this.elements; var s = window.TextGenState.current; var hasShape = s.shape !== 'none'; var hasArrow = s.arrow !== 'none'; if (e.frameScaleRow) e.frameScaleRow.style.display = hasShape ? 'flex' : 'none'; if (e.paddingAllRow) e.paddingAllRow.style.display = hasShape ? 'flex' : 'none'; if (e.paddingRow) e.paddingRow.style.display = hasShape ? 'flex' : 'none'; if (e.arrowDetailsRow) e.arrowDetailsRow.style.display = hasArrow ? 'flex' : 'none'; if (e.arrowDetailsRow2) e.arrowDetailsRow2.style.display = hasArrow ? 'flex' : 'none'; }, updatePreview: function() { var e = this.elements; if (e.textPreview && window.SvgGenerator) { var svg = window.SvgGenerator.generate(window.TextGenState.current); e.textPreview.innerHTML = svg; } }, updateStandaloneArrowPreview: function() { var e = this.elements; var s = window.TextGenState.current; if (!e.standaloneArrowPreview) return; if (s.arrow === 'none') { e.standaloneArrowPreview.innerHTML = '
Waehle einen Pfeil aus
'; return; } if (window.SvgGenerator) { var svg = window.SvgGenerator.generateArrowOnly(s); if (svg) { e.standaloneArrowPreview.innerHTML = svg; } } }, resetToDefaults: function() { window.TextGenState.reset(); this.syncFromState(); this.updateVisibility(); this.updatePreview(); this.updateStandaloneArrowPreview(); } }; window.UiBindings = UiBindings;