|
|
| |
| let isScrolling = false; |
| let scrollInterval; |
| let currentSpeed = 1; |
| let currentTheme = 'blue'; |
| let currentTextSize = 'medium'; |
| let currentAlignment = 'center'; |
| let currentFont = 'sans'; |
| let mirroredView = false; |
|
|
| |
| const elements = { |
| speedSlider: document.getElementById('speed-slider'), |
| speedValue: document.getElementById('speed-value'), |
| scriptTextarea: document.getElementById('script-textarea'), |
| previewText: document.getElementById('preview-text'), |
| previewContainer: document.getElementById('preview-container'), |
| textSizeSelect: document.getElementById('text-size'), |
| scriptTitle: document.getElementById('script-title'), |
| fileInput: document.getElementById('file-input') |
| }; |
| |
| function initializeComponents() { |
| setupEventListeners(); |
| loadSettings(); |
| updatePreview(); |
| setupKeyboardShortcuts(); |
| } |
| |
| function setupEventListeners() { |
| |
| elements.speedSlider.addEventListener('input', handleSpeedChange); |
| |
| |
| elements.scriptTextarea.addEventListener('input', updatePreview); |
| |
| |
| elements.textSizeSelect.addEventListener('change', handleTextSizeChange); |
| |
| |
| document.querySelectorAll('.theme-btn').forEach(button => { |
| button.addEventListener('click', () => handleThemeChange(button.dataset.theme)); |
| }); |
| |
| |
| document.getElementById('align-left').addEventListener('click', () => handleAlignmentChange('left')); |
| document.getElementById('align-center').addEventListener('click', () => handleAlignmentChange('center')); |
| document.getElementById('align-right').addEventListener('click', () => handleAlignmentChange('right')); |
| |
| |
| document.getElementById('font-sans').addEventListener('click', () => handleFontChange('sans')); |
| document.getElementById('font-serif').addEventListener('click', () => handleFontChange('serif')); |
| |
| |
| document.getElementById('format-bold').addEventListener('click', () => toggleFormatting('bold')); |
| document.getElementById('format-italic').addEventListener('click', () => toggleFormatting('italic')); |
| document.getElementById('format-underline').addEventListener('click', () => toggleFormatting('underline')); |
| |
| |
| document.getElementById('start-scroll').addEventListener('click', toggleScrolling); |
| document.getElementById('save-script').addEventListener('click', saveScript); |
| document.getElementById('load-script').addEventListener('click', loadScript); |
| document.getElementById('export-script').addEventListener('click', exportScript); |
| document.getElementById('import-script').addEventListener('click', () => elements.fileInput.click()); |
| document.getElementById('clear-script').addEventListener('click', clearScript); |
| document.getElementById('toggle-preview').addEventListener('click', togglePreviewMode); |
| document.getElementById('mirror-preview').addEventListener('click', toggleMirrorView); |
| |
| |
| elements.fileInput.addEventListener('change', importScriptFromFile); |
| |
| |
| window.addEventListener('beforeunload', saveSettings); |
| } |
| |
| function handleSpeedChange() { |
| currentSpeed = parseFloat(elements.speedSlider.value); |
| elements.speedValue.textContent = `${currentSpeed.toFixed(1)}x`; |
| |
| if (isScrolling) { |
| clearInterval(scrollInterval); |
| startScrolling(); |
| } |
| } |
| |
| function handleTextSizeChange() { |
| currentTextSize = elements.textSizeSelect.value; |
| updatePreview(); |
| } |
| |
| function handleThemeChange(theme) { |
| currentTheme = theme; |
| |
| |
| document.querySelectorAll('.theme-btn').forEach(btn => { |
| btn.classList.remove('active'); |
| }); |
| document.querySelector(`.theme-btn[data-theme="${theme}"]`).classList.add('active'); |
| |
| |
| const themeColors = { |
| blue: 'from-blue-500 to-blue-700', |
| green: 'from-green-500 to-green-700', |
| purple: 'from-purple-500 to-purple-700', |
| red: 'from-red-500 to-red-700', |
| yellow: 'from-yellow-500 to-yellow-700', |
| pink: 'from-pink-500 to-pink-700' |
| }; |
| |
| const gradientClass = themeColors[theme]; |
| document.querySelector('.bg-gradient-to-r').className = `p-6 bg-gradient-to-r ${gradientClass} relative`; |
| |
| updatePreview(); |
| } |
| |
| function handleAlignmentChange(alignment) { |
| currentAlignment = alignment; |
| |
| |
| document.querySelectorAll('#align-left, #align-center, #align-right').forEach(btn => { |
| btn.classList.remove('active'); |
| }); |
| document.getElementById(`align-${alignment}`).classList.add('active'); |
| |
| updatePreview(); |
| } |
| |
| function handleFontChange(font) { |
| currentFont = font; |
| |
| |
| document.getElementById('font-sans').classList.toggle('active', font === 'sans'); |
| document.getElementById('font-serif').classList.toggle('active', font === 'serif'); |
| |
| updatePreview(); |
| } |
| |
| function toggleFormatting(format) { |
| const button = document.getElementById(`format-${format}`); |
| button.classList.toggle('active'); |
| |
| |
| showToast(`Alternado formato ${format}`); |
| } |
| |
| function updatePreview() { |
| const text = elements.scriptTextarea.value || "Su script aparecerá aquí..."; |
| elements.previewText.textContent = text; |
| |
| |
| const sizeClasses = { |
| small: 'text-sm', |
| medium: 'text-base', |
| large: 'text-lg', |
| 'x-large': 'text-xl' |
| }; |
| |
| elements.previewText.className = sizeClasses[currentTextSize] || 'text-base'; |
| |
| |
| elements.previewText.classList.remove('text-left', 'text-center', 'text-right'); |
| elements.previewText.classList.add(`text-${currentAlignment}`); |
| |
| |
| elements.previewText.classList.toggle('font-serif', currentFont === 'serif'); |
| |
| |
| elements.previewText.classList.toggle('bold', document.getElementById('format-bold').classList.contains('active')); |
| elements.previewText.classList.toggle('italic', document.getElementById('format-italic').classList.contains('active')); |
| elements.previewText.classList.toggle('underline', document.getElementById('format-underline').classList.contains('active')); |
| } |
| |
| function toggleScrolling() { |
| const button = document.getElementById('start-scroll'); |
| |
| if (isScrolling) { |
| stopScrolling(); |
| button.innerHTML = '<i data-feather="play" class="w-4 h-4"></i> Iniciar Desplazamiento'; |
| feather.replace(); |
| } else { |
| startScrolling(); |
| button.innerHTML = '<i data-feather="pause" class="w-4 h-4"></i> Pausar Desplazamiento'; |
| feather.replace(); |
| } |
| } |
| |
| function startScrolling() { |
| isScrolling = true; |
| |
| |
| if (scrollInterval) { |
| clearInterval(scrollInterval); |
| } |
| |
| |
| const baseDuration = 30; |
| const duration = (baseDuration / currentSpeed) * 1000; |
| |
| |
| elements.previewText.style.animation = 'none'; |
| void elements.previewText.offsetWidth; |
| |
| |
| elements.previewText.style.animation = `scroll ${duration}ms linear infinite`; |
| |
| |
| elements.previewContainer.classList.add('scrolling'); |
| } |
| |
| function stopScrolling() { |
| isScrolling = false; |
| clearInterval(scrollInterval); |
| elements.previewText.style.animation = 'none'; |
| elements.previewContainer.classList.remove('scrolling'); |
| } |
| |
| function saveScript() { |
| const scriptData = { |
| title: elements.scriptTitle.value, |
| content: elements.scriptTextarea.value, |
| speed: currentSpeed, |
| theme: currentTheme, |
| textSize: currentTextSize, |
| alignment: currentAlignment, |
| font: currentFont |
| }; |
| |
| localStorage.setItem('teleprompterScript', JSON.stringify(scriptData)); |
| showToast('¡Script guardado exitosamente!'); |
| } |
| |
| function loadScript() { |
| const savedData = localStorage.getItem('teleprompterScript'); |
| |
| if (savedData) { |
| const scriptData = JSON.parse(savedData); |
| |
| elements.scriptTitle.value = scriptData.title || ''; |
| elements.scriptTextarea.value = scriptData.content || ''; |
| elements.speedSlider.value = scriptData.speed || 1; |
| currentSpeed = scriptData.speed || 1; |
| elements.speedValue.textContent = `${currentSpeed.toFixed(1)}x`; |
| |
| handleThemeChange(scriptData.theme || 'blue'); |
| elements.textSizeSelect.value = scriptData.textSize || 'medium'; |
| currentTextSize = scriptData.textSize || 'medium'; |
| |
| handleAlignmentChange(scriptData.alignment || 'center'); |
| handleFontChange(scriptData.font || 'sans'); |
| |
| updatePreview(); |
| showToast('¡Script cargado exitosamente!'); |
| } else { |
| showToast('No se encontró script guardado.'); |
| } |
| } |
| |
| function exportScript() { |
| const content = elements.scriptTextarea.value; |
| const title = elements.scriptTitle.value || 'teleprompter-script'; |
| |
| const blob = new Blob([content], { type: 'text/plain' }); |
| const url = URL.createObjectURL(blob); |
| |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = `${title}.txt`; |
| document.body.appendChild(a); |
| a.click(); |
| |
| setTimeout(() => { |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| }, 100); |
| |
| showToast('¡Script exportado exitosamente!'); |
| } |
| |
| function importScriptFromFile(event) { |
| const file = event.target.files[0]; |
| if (!file) return; |
| |
| const reader = new FileReader(); |
| reader.onload = function(e) { |
| elements.scriptTextarea.value = e.target.result; |
| elements.scriptTitle.value = file.name.replace(/\.[^/.]+$/, ""); |
| updatePreview(); |
| showToast('¡Script importado exitosamente!'); |
| }; |
| reader.readAsText(file); |
| |
| |
| elements.fileInput.value = ''; |
| } |
| |
| function clearScript() { |
| if (confirm('¿Está seguro de que desea limpiar el script actual?')) { |
| elements.scriptTextarea.value = ''; |
| elements.scriptTitle.value = ''; |
| updatePreview(); |
| showToast('Script limpiado.'); |
| } |
| } |
| |
| function togglePreviewMode() { |
| elements.previewContainer.classList.toggle('bg-black'); |
| elements.previewContainer.classList.toggle('bg-gray-900'); |
| showToast('Modo de vista previa alternado.'); |
| } |
| |
| function toggleMirrorView() { |
| mirroredView = !mirroredView; |
| elements.previewContainer.classList.toggle('mirror', mirroredView); |
| showToast(mirroredView ? 'Vista espejo habilitada.' : 'Vista espejo deshabilitada.'); |
| } |
| |
| function setupKeyboardShortcuts() { |
| document.addEventListener('keydown', function(e) { |
| |
| if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return; |
| |
| |
| if (e.code === 'Space') { |
| e.preventDefault(); |
| toggleScrolling(); |
| } |
| |
| |
| if (e.ctrlKey && e.code === 'KeyS') { |
| e.preventDefault(); |
| saveScript(); |
| } |
| |
| |
| if (e.ctrlKey && e.code === 'KeyO') { |
| e.preventDefault(); |
| loadScript(); |
| } |
| |
| |
| if (e.ctrlKey && e.code === 'KeyE') { |
| e.preventDefault(); |
| exportScript(); |
| } |
| |
| |
| if (e.code === 'ArrowUp') { |
| e.preventDefault(); |
| const newValue = Math.min(5, parseFloat(elements.speedSlider.value) + 0.1); |
| elements.speedSlider.value = newValue.toFixed(1); |
| handleSpeedChange(); |
| } |
| |
| if (e.code === 'ArrowDown') { |
| e.preventDefault(); |
| const newValue = Math.max(0.1, parseFloat(elements.speedSlider.value) - 0.1); |
| elements.speedSlider.value = newValue.toFixed(1); |
| handleSpeedChange(); |
| } |
| }); |
| } |
| |
| function saveSettings() { |
| const settings = { |
| speed: currentSpeed, |
| theme: currentTheme, |
| textSize: currentTextSize, |
| alignment: currentAlignment, |
| font: currentFont, |
| mirroredView: mirroredView |
| }; |
| |
| localStorage.setItem('teleprompterSettings', JSON.stringify(settings)); |
| } |
| |
| function loadSettings() { |
| const savedSettings = localStorage.getItem('teleprompterSettings'); |
| |
| if (savedSettings) { |
| const settings = JSON.parse(savedSettings); |
| |
| currentSpeed = settings.speed || 1; |
| elements.speedSlider.value = currentSpeed; |
| elements.speedValue.textContent = `${currentSpeed.toFixed(1)}x`; |
| |
| handleThemeChange(settings.theme || 'blue'); |
| elements.textSizeSelect.value = settings.textSize || 'medium'; |
| currentTextSize = settings.textSize || 'medium'; |
| |
| handleAlignmentChange(settings.alignment || 'center'); |
| handleFontChange(settings.font || 'sans'); |
| |
| if (settings.mirroredView) { |
| mirroredView = true; |
| elements.previewContainer.classList.add('mirror'); |
| } |
| } |
| } |
| |
| function showToast(message) { |
| const toast = document.createElement('div'); |
| toast.className = 'toast show'; |
| toast.textContent = message; |
| |
| document.body.appendChild(toast); |
| |
| setTimeout(() => { |
| toast.classList.remove('show'); |
| setTimeout(() => { |
| document.body.removeChild(toast); |
| }, 300); |
| }, 3000); |
| } |
| |
| document.addEventListener('DOMContentLoaded', initializeComponents); |
|
|