Communitygithub.com

liangdabiao/whiteboard-teacher-video

Crea videos explicativos con animaciones dibujadas a mano a partir de texto narrativo. El código dibuja gráficos trazo a trazo y escribe texto letra por letra, sincronizando audio y video.

¿Qué es whiteboard-teacher-video?

Esta habilidad permite convertir un guion de explicación, divulgación o demostración en un video animado que se dibuja a sí mismo en tiempo real, como si un profesor estuviera pintando en una pizarra. A diferencia de generar imágenes estáticas, el video se compone de código que dibuja cada elemento secuencialmente (trazo a trazo, letra a letra), lo que permite una edición precisa, re-renderizado rápido y cero costos de API de generación de imágenes. Soporta cinco estilos visuales (pizarra blanca, pizarra negra, pergamino, ilustración cálida y tecnología oscura) y cuenta con 29 componentes prefabricados (tablas, diagramas de flujo, medidores, terminales, gráficos 3D). El motor de renderizado usa Chrome local, lo que garantiza velocidad y determinismo: cada fotograma es una función pura del tiempo, permitiendo avance instantáneo, renderizado paralelo con 12 navegadores y verificación de consistencia. Está diseñado para plataformas como Claude Code, Cursor y Codex, y es ideal para creadores de contenido educativo, divulgadores científicos, y desarrolladores que necesitan producir videos explicativos animados de alta calidad sin depender de herramientas de generación de imágenes externas.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add liangdabiao/whiteboard-teacher-video

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Whiteboard Teacher Video · Video Explicativo con Animaciones Dibujadas

Convierte un guion explicativo en un video que se "dibuja a sí mismo". Las imágenes no se generan como fotos, sino que el código las dibuja trazo a trazo: por lo tanto, se pueden re-renderizar, ajustar con precisión y sin costo de generación de imágenes.

Contrato del Motor (Comprende esto primero)

El video completo es una función pura del tiempo. ENGINE.renderAt(t) renderiza el fotograma en el segundo t, independientemente de lo que se haya reproducido antes.

Esto otorga cuatro capacidades, que son la razón fundamental por la que debes seguir las reglas:

Capacidad¿Cómo se logra?
Modificar una página solo re-renderiza los segmentos afectadosCaché segmentada con clave = sha1(motor + código de esa página)
12 navegadores renderizando en paraleloLos segmentos no dependen entre sí
La vista previa puede saltar a cualquier instanteNo necesita reproducir desde el inicio
Verificación deterministaRenderizar dos veces el mismo instante y comparar píxeles

Línea roja: El código de página tiene prohibido Math.random() / Date.now() / transiciones CSS / rAF. La aleatoriedad debe usar PV.rng(seed), y el tiempo debe usar P.c(i) / P.cw(i,'palabra'). Si rompes esto, las cuatro capacidades anteriores quedarán inservibles.

Flujo de Trabajo (Sigue este orden, no te saltes pasos)

Usuario: "Haz un video de 90 segundos sobre la relatividad"
  ↓
① Leer references/storyboard-method.md → escribir storyboard.json
② ★★★ DETENTE y lee el storyboard al usuario para confirmación ★★★   ← Única compuerta humana obligatoria
③ Escribir script.js (narración, con cues según storyboard)
④ python scripts/ftnew.py <proyecto> --title "..." --style whiteboard
⑤ python scripts/ftvoice.py <proyecto> → voice.js + subtítulos.srt
⑥ Escribir páginas una por una en pages/pNN.js ← Principal trabajo creativo
⑦ python scripts/ftcheck.py <proyecto> → lint + collage de cada página
⑧ Abrir out/snap/pNN.jpg con Read para ver página por página → Corregir de forma dirigida, **no más de 2 rondas**
⑨ python scripts/ftrender.py --fps 24 --skip-subs → **Primero un borrador que se pueda ver**
⑩ ★ Entregar el borrador al usuario ★ ← No acumules correcciones sin entregar
⑪ Corregir una ronda basándose en las imágenes → ftrender.py → Entregar versión final

El paso ② no se puede omitir. Si el storyboard está mal, por más bonito que se dibuje después, solo será una presentación de diapositivas. El proyecto original implementa este paso como una compuerta de promesa por una razón.

★★ El paso ⑩ es igualmente importante: primero entrega el video, luego púlelo

El usuario quiere un video, no un video perfecto. El ritmo de entrega es más importante que la precisión del producto final.

  • La revisión de calidad del paso ⑧ debe llegar hasta "sin errores evidentes" (lint sin errores, texto no tapado, NaN convertido a 0), no persigas la perfección de la composición
  • El primer renderizado usa --fps 24 --skip-subs (40% más rápido), entrega primero una versión visible al usuario
  • No esperes a corregir todas las rondas para entregar. El usuario solo puede dar retroalimentación real cuando vea el borrador
  • ¿Quieres cambiar el estilo, añadir páginas, ajustar contenido? Modifica y re-renderiza, la caché segmentada hará que la segunda ronda sea muy rápida (probado: modificar una página en 1 minuto)

Lección probada: Al hacer el video de 95 segundos con 8 páginas, dudé mucho en la segunda ronda sobre si valía la pena corregir los problemas que reportaba el lint, y entregué después de dos rondas de duda. El usuario se impacientó. Lo correcto: Corrige los errores de lint, corrige los bugs evidentes, entrega el borrador primero, y luego corrige en la siguiente ronda.

★ Lint todo verde no significa que la imagen sea correcta

lint es una verificación automática; solo puede detectar errores duros como elementos fuera de límites, superposiciones o tamaño de fuente; la composición, si los elementos están apretados, si el texto está cubierto por bloques de color, solo se ve al mirar la imagen.

Lección probada: En la página p07, el lint reportó 0 errores y la verificación de calidad mostró todo verde, pero al mirar el collage descubrí que la palabra "microsegundo" en "7 microsegundos" estaba completamente cubierta por un resaltador, dejando solo el "7" en rojo: el espectador no podía leer la unidad en absoluto.

Reglas Estrictas

★ Ritmo (La regla más importante)

  • El usuario quiere un video, no un video perfecto. El borrador también es un video; no acumular sin entregar es como no haber hecho nada.
  • La revisión de calidad debe detenerse en "sin errores evidentes", no persigas la perfección de la composición.
  • El primer renderizado usa --fps 24 --skip-subs (40% más rápido), entrega primero una versión visible.
  • Corrige una ronda y luego entrega la versión final. La caché segmentada hace que la segunda ronda sea muy rápida (probado: modificar una página en 1 minuto).

Imagen

  • Área de contenido: x 140–1780, y 180–880. y > 900 es la zona de subtítulos, no pongas contenido allí.
  • ★ Para centrar texto, debes dar w + align:'c' — si no das w, x es el borde izquierdo, no el centro. Este es el error más frecuente.
  • ★ En páginas con P.push(), coloca los elementos hacia el centro de la imagen — al ampliar, los elementos en los bordes se saldrán del lienzo (lint reportará off-canvas).
  • Tamaño de fuente del cuerpo: ≥ 32px (< 24px hará que lint falle).
  • Máximo 8 caracteres por línea de texto chino.
  • Colores: solo usa nombres semánticos: ink soft muted faint blue orange red green purple yellow, añade F para relleno claro (blueF). No codifiques colores hex — si escribes mal el nombre, el motor lo registrará y el informe de calidad lo mostrará.
  • Una página, una idea, 2–3 frases de narración, cada 2–4 segundos debe aparecer algo nuevo.

Animación

  • P.c(i, dt) = inicio de la frase i + dt segundos.
  • P.cw(i, 'palabra', dt) = cuando la frase i pronuncia una palabra específica + dt segundos (usa esto para números clave: que aparezcan justo cuando se pronuncian).
  • P.ce(i) = fin de esa frase; P.endT = fin de la página.
  • Los énfasis se hacen con trazos (ring círculo / underline subrayado / mark resaltador / cross cruz / check palomita), no con efectos especiales.
  • Al cambiar de página, debe haber algo en la página, no puede estar en blanco.

Iteración

  • Modificar una página → re-renderizar solo esa página (ftcheck.py --only pNN), no todo.
  • Si lint tiene errores, no renderices, corrige primero.
  • Aunque lint pase, revisa el collage — lint solo controla errores duros, no comprueba si la composición es bonita o si hay elementos tapados.
  • ftcheck.py reportará NaN — son errores fatales que lint no detecta (el gráfico desaparece en silencio).
  • Si no puedes corregir todo, marca "Necesita atención" y continúa, no te bloquees (máximo 2 rondas para sacar el video).

Tiempos de Referencia (Probados localmente, video de 8 páginas, 87 segundos)

FaseDuración
Crear proyecto + escribir código de 8 páginasAprox. 10 minutos (tiempo de creación humana)
Locutar 26 frasesAprox. 1.5 minutos
Control de calidad (lint + collage de 8 páginas)Aprox. 1 minuto
Renderizado (primera vez, 12 workers)Aprox. 2 minutos 45 segundos
Renderizado (después de modificar una página, con caché)Aprox. 1 minuto
Renderizado (versión rápida --fps 24 --skip-subs)Aprox. 1 minuto 40 segundos

Por lo tanto, desde crear el proyecto hasta obtener el primer video, el proceso total dura aproximadamente 15 minutos. Iterar sobre una página toma un minuto, así que no hay necesidad de acumular todas las correcciones antes de entregar.

Tres Errores Frecuentes con la API del Motor

// ① Centrar texto: si no das w, x es el borde izquierdo, no el centro
P.text('Andén', { x: 420, y: 640, w: 280, align: 'c', size: 46 });   // ✓ centro en 420

// ② El tercer parámetro de check/cross es el "tamaño", no un objeto de configuración (si lo pasas mal, solo da NaN, no error)
P.cross(970, 716, 64, { color: 'red', at: t });   // ✓
P.cross(970, 716, { color: 'red', at: t });      // ✗ sz = [object Object]

// ③ No llames R al parámetro del callback de liveRough; además, R solo tiene cuatro métodos: box/circle/line/path
const R = 1400;                                    // ← será sobrescrito por el parámetro del callback
P.liveRough((lt, R) => (xL + R) / 2);              // ✗ NaN
P.liveRough((lt, rough) => [rough.box(x, y, w, h, { color: 'ink' })]);  // ✓

Durante el renderizado, presta atención a la consola por NaN — no lanza excepción, el lint no siempre lo reporta, pero el gráfico correspondiente no se dibuja.

La lista completa está en references/page-api.md.

Qué se puede hacer / Qué no se puede hacer

Sí se puede: Divulgación científica, explicación de conceptos, deducción de procesos, explicación de gráficos de datos, demostraciones de productos (se pueden incrustar capturas de pantalla reales), explicación de proyectos de GitHub; cinco estilos; orientación horizontal/vertical; locución en chino/inglés; subtítulos automáticos; duración de 20 segundos a 10 minutos.

No se puede:

  • Fotos realistas o estilo de grabación 3D realista (para esa textura, usa herramientas de generación de imágenes).
  • Música de fondo automática y efectos de sonido (page.sfx puede hacerlo, pero debes preparar los archivos de audio tú mismo).
  • Ilustraciones dibujadas a mano generadas por IA (los componentes son vectores dibujados con código).
  • Generar decenas de páginas de una vez (cada página requiere código, se recomienda ≤ 12 páginas).

Diferencia con whiteboard-explainer

whiteboard-explainerframetell-video (esta habilidad)
ImagenTrazos de píxel a nivel de crecimientoDibujo estilizado con rough.js
EstiloÚnico (pizarra blanca, color de fondo codificado)Cinco estilos, incluido modo oscuro
ComponentesTodos escritos a mano29 prefabricados
Control de calidadVerificación de pertenencialint + collage + determinismo
Adecuado paraDeducción matemática, fuerte sensación de dibujo a manoDivulgación científica, gráficos densos, múltiples estilos

Si necesitas "sensación real de dibujo a mano / crecimiento elemento por elemento" → usa whiteboard-explainer. Si necesitas "múltiples estilos / gráficos complejos / reutilización de componentes / control de calidad sólido" → usa esta habilidad.

Índice de Documentación

Cuándo leerloQué leer
Primera vezassets/example-relativity/ (código fuente completo de un video real: 8 páginas, léelo y entenderás)
Antes de dibujar cualquier páginareferences/page-api.md (referencia rápida de la API de dibujo + tres errores frecuentes)
Al definir el storyboard / escribir la narraciónreferences/storyboard-method.md (estructura de cinco partes + prohibiciones)
Al elegir estilo / dudas sobre coloresreferences/style-packs.md (cinco estilos + resumen de sintaxis)
Si no entiendes los campos de script.jsreferences/script-format.md
Si la locución da error / quieres cambiar TTSreferences/tts-backends.md (incluye explicación de que edge-tts está bloqueado)
Si no entiendes los errores del motorreferences/troubleshooting.md (indexado por síntoma)

Primer Uso

Si scripts/ muestra "Motor no listo" o faltan dependencias, ejecuta primero la configuración:

python scripts/setup.py                                    # Multiplataforma
powershell -ExecutionPolicy Bypass -File scripts/setup.ps1  # Windows

Requisitos: Node.js ≥ 22.19, Git, Chrome/Edge local, Python 3.9+

La primera vez tarda entre 2 y 4 minutos: descarga el motor desde GitHub (aproximadamente 16 MB, sparse checkout solo para packages/engine) + npm install dependencias (aproximadamente 130 MB).

Si no tienes Git instalado: Descarga manualmente https://github.com/sitor-ai/frametell , copia packages/engine al directorio raíz de la habilidad como engine/, y vuelve a ejecutar setup.

La lista de dependencias y su tamaño está en README.md; la información de licencias está en vendor/ATTRIBUTION.md.

Skills relacionados