CommandPrompt's picture
I want it all in Spanish even more high tech and called simply >_teleprompter
6917ab6 verified
// Variables globales
let isScrolling = false;
let scrollInterval;
let currentSpeed = 1;
let currentTheme = 'blue';
let currentTextSize = 'medium';
let currentAlignment = 'center';
let currentFont = 'sans';
let mirroredView = false;
// Elementos DOM
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')
};
// Inicializar todos los componentes
function initializeComponents() {
setupEventListeners();
loadSettings();
updatePreview();
setupKeyboardShortcuts();
}
// Configurar escuchadores de eventos
function setupEventListeners() {
// Control de velocidad
elements.speedSlider.addEventListener('input', handleSpeedChange);
// Cambios en el área de texto
elements.scriptTextarea.addEventListener('input', updatePreview);
// Cambios en tamaño de texto
elements.textSizeSelect.addEventListener('change', handleTextSizeChange);
// Selección de tema
document.querySelectorAll('.theme-btn').forEach(button => {
button.addEventListener('click', () => handleThemeChange(button.dataset.theme));
});
// Alineación de texto
document.getElementById('align-left').addEventListener('click', () => handleAlignmentChange('left'));
document.getElementById('align-center').addEventListener('click', () => handleAlignmentChange('center'));
document.getElementById('align-right').addEventListener('click', () => handleAlignmentChange('right'));
// Estilo de fuente
document.getElementById('font-sans').addEventListener('click', () => handleFontChange('sans'));
document.getElementById('font-serif').addEventListener('click', () => handleFontChange('serif'));
// Botones de formato
document.getElementById('format-bold').addEventListener('click', () => toggleFormatting('bold'));
document.getElementById('format-italic').addEventListener('click', () => toggleFormatting('italic'));
document.getElementById('format-underline').addEventListener('click', () => toggleFormatting('underline'));
// Botones de control
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);
// Entrada de archivo
elements.fileInput.addEventListener('change', importScriptFromFile);
// Eventos de ventana
window.addEventListener('beforeunload', saveSettings);
}
// Manejar cambio de velocidad
function handleSpeedChange() {
currentSpeed = parseFloat(elements.speedSlider.value);
elements.speedValue.textContent = `${currentSpeed.toFixed(1)}x`;
if (isScrolling) {
clearInterval(scrollInterval);
startScrolling();
}
}
// Manejar cambio de tamaño de texto
function handleTextSizeChange() {
currentTextSize = elements.textSizeSelect.value;
updatePreview();
}
// Manejar cambio de tema
function handleThemeChange(theme) {
currentTheme = theme;
// Actualizar botón activo
document.querySelectorAll('.theme-btn').forEach(btn => {
btn.classList.remove('active');
});
document.querySelector(`.theme-btn[data-theme="${theme}"]`).classList.add('active');
// Aplicar tema a la vista previa
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();
}
// Manejar cambio de alineación
function handleAlignmentChange(alignment) {
currentAlignment = alignment;
// Actualizar botón activo
document.querySelectorAll('#align-left, #align-center, #align-right').forEach(btn => {
btn.classList.remove('active');
});
document.getElementById(`align-${alignment}`).classList.add('active');
updatePreview();
}
// Manejar cambio de fuente
function handleFontChange(font) {
currentFont = font;
// Actualizar botón activo
document.getElementById('font-sans').classList.toggle('active', font === 'sans');
document.getElementById('font-serif').classList.toggle('active', font === 'serif');
updatePreview();
}
// Alternar formato de texto
function toggleFormatting(format) {
const button = document.getElementById(`format-${format}`);
button.classList.toggle('active');
// En una implementación real, esto aplicaría formato al texto seleccionado
showToast(`Alternado formato ${format}`);
}
// Actualizar vista previa
function updatePreview() {
const text = elements.scriptTextarea.value || "Su script aparecerá aquí...";
elements.previewText.textContent = text;
// Aplicar tamaño de texto
const sizeClasses = {
small: 'text-sm',
medium: 'text-base',
large: 'text-lg',
'x-large': 'text-xl'
};
elements.previewText.className = sizeClasses[currentTextSize] || 'text-base';
// Aplicar alineación
elements.previewText.classList.remove('text-left', 'text-center', 'text-right');
elements.previewText.classList.add(`text-${currentAlignment}`);
// Aplicar fuente
elements.previewText.classList.toggle('font-serif', currentFont === 'serif');
// Aplicar clases de formato
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'));
}
// Alternar desplazamiento
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();
}
}
// Iniciar animación de desplazamiento
function startScrolling() {
isScrolling = true;
// Limpiar cualquier intervalo existente
if (scrollInterval) {
clearInterval(scrollInterval);
}
// Calcular duración basada en velocidad (en segundos)
const baseDuration = 30; // Duración base para velocidad 1x
const duration = (baseDuration / currentSpeed) * 1000; // Convertir a milisegundos
// Reiniciar animación
elements.previewText.style.animation = 'none';
void elements.previewText.offsetWidth; // Activar reflow
// Aplicar animación de desplazamiento
elements.previewText.style.animation = `scroll ${duration}ms linear infinite`;
// Agregar clase de desplazamiento para estilizar
elements.previewContainer.classList.add('scrolling');
}
// Detener animación de desplazamiento
function stopScrolling() {
isScrolling = false;
clearInterval(scrollInterval);
elements.previewText.style.animation = 'none';
elements.previewContainer.classList.remove('scrolling');
}
// Guardar script en localStorage
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!');
}
// Cargar script desde localStorage
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.');
}
}
// Exportar script como archivo
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!');
}
// Importar script desde archivo
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(/\.[^/.]+$/, ""); // Eliminar extensión
updatePreview();
showToast('¡Script importado exitosamente!');
};
reader.readAsText(file);
// Reiniciar entrada de archivo
elements.fileInput.value = '';
}
// Limpiar script
function clearScript() {
if (confirm('¿Está seguro de que desea limpiar el script actual?')) {
elements.scriptTextarea.value = '';
elements.scriptTitle.value = '';
updatePreview();
showToast('Script limpiado.');
}
}
// Alternar modo de vista previa
function togglePreviewMode() {
elements.previewContainer.classList.toggle('bg-black');
elements.previewContainer.classList.toggle('bg-gray-900');
showToast('Modo de vista previa alternado.');
}
// Alternar vista espejo
function toggleMirrorView() {
mirroredView = !mirroredView;
elements.previewContainer.classList.toggle('mirror', mirroredView);
showToast(mirroredView ? 'Vista espejo habilitada.' : 'Vista espejo deshabilitada.');
}
// Configurar atajos de teclado
function setupKeyboardShortcuts() {
document.addEventListener('keydown', function(e) {
// Solo activar atajos cuando no esté en campos de entrada
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
// Barra espaciadora para alternar desplazamiento
if (e.code === 'Space') {
e.preventDefault();
toggleScrolling();
}
// Ctrl+S para guardar
if (e.ctrlKey && e.code === 'KeyS') {
e.preventDefault();
saveScript();
}
// Ctrl+O para cargar
if (e.ctrlKey && e.code === 'KeyO') {
e.preventDefault();
loadScript();
}
// Ctrl+E para exportar
if (e.ctrlKey && e.code === 'KeyE') {
e.preventDefault();
exportScript();
}
// Flechas Arriba/Abajo para ajustar velocidad
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();
}
});
}
// Guardar configuraciones en localStorage
function saveSettings() {
const settings = {
speed: currentSpeed,
theme: currentTheme,
textSize: currentTextSize,
alignment: currentAlignment,
font: currentFont,
mirroredView: mirroredView
};
localStorage.setItem('teleprompterSettings', JSON.stringify(settings));
}
// Cargar configuraciones desde localStorage
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');
}
}
}
// Mostrar notificación toast
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);
}
// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', initializeComponents);