|
|
|
|
|
|
|
|
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); |
|
|
|