Perfil Servicios Gadgets IA Blog Contactar
Inicio/Blog/9 Gadgets Vanilla JS
9 Gadgets IA sin Frameworks: Arquitectura de un Portfolio en Vanilla JS

9 Gadgets IA sin Frameworks: Arquitectura de un Portfolio en Vanilla JS

23.000 líneas de código, 9 prototipos funcionales, 0 frameworks. OCR con Tesseract.js, análisis de sentimiento, simulador 3D, CRM completo, weather dashboard... Todo en JavaScript puro. Así está organizado.

La Decisión: ¿Por Qué Sin Frameworks?

No fue por ideología anti-React. Fue por una razón práctica: quería demostrar que entiendo la tecnología base, no solo que sé instalar npm packages. Cualquiera puede hacer npx create-react-app. Pero construir un sistema de componentes, gestión de estado, lazy loading y i18n desde cero demuestra algo distinto.

Además, para un portfolio estático desplegado en Cloudflare Pages, un framework añade complejidad innecesaria: build steps, dependencias de node_modules, tiempo de bundling. Mi sitio carga en menos de 2 segundos porque no tiene que ejecutar un Virtual DOM — es HTML directo al navegador.

El Mapa de los 23.000 Líneas

ArchivoLíneasFunción
solar-system-pro.js8.087Simulador astronómico Three.js + Launch Library 2 API
crm-studio-pro.js2.850CRM con pipeline y analítica
weather-pro.js1.950Dashboard meteorológico
neural-bricks-3d.js1.800Motor voxel Three.js
gadget-popups.css1.685Sistema expandir gadgets
sentiment-analyzer-pro.js1.600NLP con scoring
pricing-simulator-pro.js1.400Pricing dinámico ML
ocr-scanner-pro.js1.350OCR con Tesseract.js
script.js1.315Core + boot screen
email-pro.js1.100Reescritura profesional
styles.css2.007Estilos principales
Otros (i18n, info, popups)~1.800Infraestructura

Patrón Compartido: El "Gadget Expand"

Todos los gadgets siguen el mismo patrón: una tarjeta compacta en la grid del portfolio (card mode) y un modo laboratorio expandido (expand mode) que ocupa pantalla completa. El sistema de expand es un overlay gestionado por gadget-popups.js:

function openGadgetExpand(gadgetId) {
    const backdrop = document.getElementById('gadget-expand-backdrop');
    const content = document.getElementById('gadget-expand-content');

    // Lazy init: solo crea el DOM del gadget cuando se abre
    if (!content.dataset.initialized) {
        content.innerHTML = buildGadgetHTML(gadgetId);
        initGadgetLogic(gadgetId);
        content.dataset.initialized = gadgetId;
    }

    backdrop.classList.add('active');
    document.body.style.overflow = 'hidden';

    // Trap focus dentro del modal para accesibilidad
    trapFocus(content);
}

El lazy init es clave: los gadgets pesados (Solar System, Neural Bricks) no crean sus escenas Three.js hasta que el usuario los abre. Esto significa que la página principal carga rápido aunque tenga 9 gadgets registrados.

Gadget por Gadget: Decisiones Técnicas

1. OCR Scanner Pro — Tesseract.js

El escáner usa Tesseract.js v4 para extracción de texto real en el navegador. El reto principal es el rendimiento: OCR en WebAssembly tarda 3-8 segundos según la imagen. La solución fue un pipeline con feedback visual:

async function processImage(imageData) {
    updateProgress('Inicializando Tesseract...', 10);
    const worker = await Tesseract.createWorker('spa+eng');

    updateProgress('Analizando imagen...', 30);
    const { data } = await worker.recognize(imageData, {
        logger: m => {
            if (m.status === 'recognizing text') {
                updateProgress('Reconociendo texto...', 30 + m.progress * 60);
            }
        }
    });

    updateProgress('Procesando resultados...', 95);
    displayResults(data);
    await worker.terminate();
}

2. Sentiment Analyzer — NLP Client-Side

El analizador de sentimientos funciona sin API externa. Usa un diccionario de ~2.000 palabras con scores de sentimiento (positivo/negativo/neutro) más heurísticas para detectar negaciones, intensificadores y emojis. No es GPT-4, pero demuestra el concepto de NLP aplicado.

3. Dynamic Pricing — Algoritmo Multi-Factor

El simulador de pricing calcula precios óptimos combinando 4 factores (demanda, competencia, estacionalidad, stock) con pesos configurables. Incluye un modo avanzado con curvas de sensibilidad y análisis what-if:

function calculateOptimalPrice(base, factors) {
    const demandMultiplier = 1 + (factors.demand - 50) / 100 * 0.8;
    const competitionFactor = 1 - (factors.competition - 50) / 100 * 0.3;
    const seasonBoost = 1 + Math.sin(factors.season * Math.PI / 100) * 0.4;
    const stockPressure = 1 + (100 - factors.stock) / 100 * 0.5;

    return base * demandMultiplier * competitionFactor
               * seasonBoost * stockPressure;
}

4. Weather Dashboard — Open-Meteo API

El widget meteorológico consume la API gratuita de Open-Meteo (sin API key). Primero geocodifica la ciudad, luego obtiene forecast de 7 días. El modo expandido muestra gráficos de temperatura, precipitación y viento construidos con Canvas puro — sin Chart.js ni D3.

5. CRM Studio Pro — Estado Complejo sin Redux

Este es el gadget más parecido a una "app real": pipeline Kanban con drag & drop, formularios de contacto, analítica con gráficos, y export a CSV/JSON. Todo el estado vive en un objeto JavaScript en memoria con persistencia opcional en localStorage.

6-7. Neural Bricks + Solar System — Three.js

Los dos gadgets 3D usan Three.js r128 pero con enfoques distintos. Neural Bricks es un motor de voxels con 8 modelos procedurales y animación frame-by-frame. Solar System es una simulación científica con datos NASA reales. Tengo un análisis técnico completo del Solar System aquí.

8. Before/After Slider — Canvas + CSS Filters

El comparador visual parece simple pero tiene profundidad: modo lente circular, crossfade, 12 filtros CSS en tiempo real, modo fullscreen, y exportación de capturas. Todo con Canvas API y manipulación de píxeles.

El Sistema de i18n

El portfolio es bilingüe (ES/EN) con un sistema propio de internacionalización. 195 claves de traducción gestionadas con atributos data-i18n en el HTML:

// i18n.js — 324 líneas
const I18N = {
    dict: {
        'nav.profile':  { es: 'Perfil',    en: 'Profile' },
        'nav.services': { es: 'Servicios', en: 'Services' },
        // ... 193 más
    },

    _apply() {
        document.querySelectorAll('[data-i18n]').forEach(el => {
            const val = this.t(el.getAttribute('data-i18n'));
            val.includes('<') ? el.innerHTML = val : el.textContent = val;
        });
        // También actualiza placeholders, aria-labels, <html lang>
    }
};

Boot Screen: La Primera Impresión

La pantalla de inicio simula un terminal Linux con matrix rain, carga ASCII art del logo, y hace un typewriter de líneas de "sistema". Es puro teatro, pero cumple una función real: precargar recursos mientras el usuario está entretenido. Al terminar la secuencia, las fuentes, imágenes y scripts ya están en caché.

Lo Que Haría Diferente

Con 23K líneas de vanilla JS, hay cosas que un framework haría mejor:

Pero para un portfolio cuyo objetivo es demostrar capacidad técnica, vanilla JS fue la decisión correcta. Muestra que entiendo qué hacen los frameworks por debajo, y que puedo construir sin ellos.

El mejor framework para un portfolio es ninguno. Demuestra que sabes programar, no que sabes instalar dependencias.

Todos los gadgets están en cristiancorrales.com. Abre cualquiera y pulsa "LABORATORIO" para ver el modo completo.

¿Tu web no trae clientes?

Diseño webs que cargan rápido y convierten, para negocios de Tarragona y alrededores. Precios claros desde el primer día.

Ver el servicio de diseño web →

¿Quieres una cifra orientativa ya? Configura tu web y ve el precio al instante →

¿Quieres ver casos reales de IA en pymes?

Te escribo solo cuando tengo un caso con costes y resultados reales, o una herramienta que merece la pena. Sin humo, sin spam y baja en un clic.

Comparte este artículo

Cristian Corrales

Cristian Corrales

+20 años en tecnología. SEO, automatización e IA aplicada a negocios reales desde Calafell, Tarragona.