PTENES
MÓDULO 4.4

📱 Reels / Shorts

Video vertical 1080×1920 para Instagram Reels y YouTube Shorts. Ritmo rápido, texto impactante con typewriter e bounce-text, glitch en el elemento destacado, sound-wave visual, fondo bokeh y recordatorio para suscribirse en los últimos 5 segundos.

6
Temas
45
Minutos
Avanzado
Nivel
Proyecto
Tipo
bokeh-circles (z=0) sound-wave (z=1) typewriter (z=2) glitch-text (z=3) subscribe (z=4, final) 9:16 1080×1920 Reel / Short listo 30–60 s · ritmo rápido · 85% sin sonido
1

📐 Formato vertical — 1080×1920 con useVideoConfig

El Reel comienza con la definición de la Composition: width: 1080, height: 1920. Todo dentro del componente lee esas dimensiones mediante useVideoConfig() para adaptarse — fuentes más grandes, márgenes más pequeños, contenido centrado verticalmente en el tercio superior (donde está el pulgar del usuario).

Composición vertical + hook Root.tsx + Reel.tsx
// Root.tsx — declaração do formato
<Composition
  id="Reel"
  component={ReelVideo}
  width={1080}
  height={1920}
  fps={30}
  durationInFrames={900}  // 30 s
/>

// Reel.tsx — layout responsivo
const { width, height } = useVideoConfig();

// fonte escala com a largura
const baseFontSize = width * 0.055; // ~60px em 1080px

// conteúdo no terço superior (fora da área do polegar)
const contentTop = height * 0.15;

📱 Reglas de diseño para 9:16

  • Tercio superior (0–30%): título y texto principal — área más visible
  • Tercio central (30–70%): visual/imagen — zona donde se enfoca la mirada
  • Tercio inferior (70–100%): CTA y suscripción: zona del pulgar, interacción
  • Fuente mínima: 60px en 1080px (width * 0.055) — legible en un celular pequeño
1080×1920
Resolución 9:16
width*0.055
Fuente base escalable
30 s = 900f
Duración ideal
Tercios
Diseño en 3 zonas
2

💬 Subtítulo animado — typewriter y bounce-text

El 85% de los Reels se ve sin sonido. Eso significa que el texto es el audio del video. El typewriter-subtitle.tsx revela el texto letra por letra, mientras el bounce-text.tsx hace que cada palabra entre con un pequeño salto — ambos crean la sensación de que alguien está "escribiendo en vivo".

Typewriter por palabra typewriter-subtitle.tsx
const words = text.split(" ");
const FRAMES_PER_WORD = 8;  // ritmo: 1 palavra a cada 8 frames

{words.map((word, i) => {
  const startFrame = i * FRAMES_PER_WORD;
  const opacity = interpolate(
    frame, [startFrame, startFrame + 6], [0, 1],
    { extrapolateLeft: "clamp", extrapolateRight: "clamp" }
  );
  // bounce: entra de baixo
  const y = interpolate(
    frame, [startFrame, startFrame + 10], [20, 0],
    { easing: Easing.out(Easing.back(1.5)), extrapolateLeft: "clamp", extrapolateRight: "clamp" }
  );
  return <span key={i} style={{ opacity, transform: `translateY(${y}px)`, display: "inline-block", margin: "0 4px" }}>{word}</span>;
})}

💡 Ritmo: 8 frames por palabra = 0.27 s

A 30fps, 8 frames por palabra producen una lectura natural y fluida. Para frases impactantes que necesitan más énfasis, usa 12–15 frames por palabra. Para listas rápidas («fácil · rápido · barato»), usa 5–6 frames. El ritmo del texto debe imitar el ritmo del habla.

Ritmo
8f por palabra
Bounce
Easing.back(1.5)
Display
inline-block por palabra
Fuente
≥60px en 1080px
3

⚡ Glitch en el destaque — impacto visual en los primeros frames

El algoritmo de Reels mide la retención de los primeros 3 segundos. El glitch-text.tsx crea un efecto de «interferencia» en la palabra clave del video: desplazamientos rápidos de color (channel offset) durante 2–4 frames, que generan un impacto visual que capta la atención de inmediato.

✓ Glitch que funciona

  • ✓Glitch en los primeros 0–15 frames: capta la atención antes de que sigas deslizando.
  • ✓Offset pequeño (3–8px) — perceptible sin ser nauseabundo.
  • ✓random("glitch-N") con seed — el mismo glitch en todos los renders.

✗ Glitch que aleja

  • ✗Glitch durante todo el video: cansa y parece un error, no un efecto.
  • ✗Offset grande (20px+) — hace que el texto sea ilegible.
  • ✗Math.random() sin seed — texto «parpadeando» sin control durante el render.
1

Frame 0–3: glitch intenso

Tres capas del texto desplazadas aleatoriamente en X e Y (pero con semilla). Colores: ámbar, cian y blanco, separadas entre 3–6px.

2

Frame 4–6: glitch residual

Offset se reduce a 1–2px. La "cura" del glitch es tan importante como el glitch — la estabilización refuerza la palabra como recuerdo.

3

Frame 7+: texto estable

El texto principal permanece estable durante el resto de la escena. El efecto glitch puede reaparecer brevemente cuando surge una nueva frase.

Frames 0–6
Ventana del glitch
3 capas
Color separado por offset
random seed
Determinístico
3–8px
Offset máximo
4

🎵 Visualización de onda sonora — ritmo sin audio

O sound-wave.tsx renderiza una fila de barras que oscilan con Math.sin(), simulando una visualización de audio. En el Reel sin sonido, este elemento indica "este video tiene energía"; es el equivalente visual de un ritmo musical.

Barras oscilantes con Math.sin sound-wave.tsx
const frame = useCurrentFrame();
const BAR_COUNT = 32;
const MAX_H = 80; // px, relativo ao height do container

{Array.from({ length: BAR_COUNT }).map((_, i) => {
  const seed = random(`wave-${i}`); // fase aleatória por barra
  const barH = Math.abs(
    Math.sin(frame * 0.15 + seed * Math.PI * 2)
  ) * MAX_H + 4;  // mínimo 4px para não sumir

  return <div key={i} style={{
    width: 4, height: barH,
    background: i % 3 === 0 ? "#38bdf8" : "#fbbf24",
    borderRadius: 2
  }} />;
})}
Math.sin
frame * 0.15 + seed
32 compases
Densidad visual
random seed
Fase única por barra
Mínimo 4px
Nunca desaparece
5

🫧 Fondo bokeh — profundidad de campo sintética

O bokeh-circles.tsx genera círculos desenfocados que flotan en el fondo: el efecto bokeh de una cámara real, pero 100% computacional. Cada círculo tiene un tamaño, una posición, una opacidad y una velocidad vertical aleatorios (con semilla), lo que crea profundidad de campo sin una cámara física.

🫧 Cómo se genera el bokeh

  • Posición: random("bokeh-x-N") y random("bokeh-y-N") — fijas y determinísticas
  • Tamaño: random("bokeh-r-N") * 80 + 20 — entre 20 y 100px de radio
  • Flotación: translateY = -frame * random("bokeh-speed-N") * 0.3 — sube lentamente
  • Reaparición: cuando y < -r, reubicar en height + r (loop)
  • Desenfoque: filter: blur(Npx) — entre 8 y 20px para que parezca desenfocado
blur
8–20px por círculo
opacity
0.15–0.45
Loop
Reaparece en la parte inferior
z=0
Base de AbsoluteFill
6

🔔 Subscribe reminder — CTA en los últimos 5 s

O subscribe-reminder.tsx aparece en los últimos 150 frames (5 s) del Reel — una animación de campana + texto «Suscríbete» que no compite con el contenido principal, pero está ahí cuando el espectador está más interesado (porque lo vio hasta el final).

Subscribe con timing relativo al final subscribe-reminder.tsx
const { durationInFrames } = useVideoConfig();
const frame = useCurrentFrame();

// aparece nos últimos 150 frames
return (
  <Sequence from={durationInFrames - 150}>
    <SubscribeWidget />
  </Sequence>
);

// SubscribeWidget — sino com shake e texto
const bellFrame = useCurrentFrame(); // local frame (0–150)
const scale = spring({ frame: bellFrame, fps,
  config: { damping: 10, stiffness: 200 }
});
// shake: oscila 3x por segundo
const shakeX = Math.sin(bellFrame * 0.5) *
  interpolate(bellFrame, [0, 10], [8, 0], { extrapolateRight: "clamp" });

💡 ¿Por qué el último quinto?

Los espectadores que llegan a los últimos 5 s del Reel ya están «interesados»: aprobaron el contenido. Ese es el mejor momento para pedirles que hagan algo. El subscribe antes de ese momento parece spam; después, no hay tiempo para reaccionar. El timing correcto es lo que distingue un CTA eficaz de una intrusión.

Timing
durationInFrames - 150
Frame local
Se reinicia desde 0
Spring
Entrada de la campana
Shake
Math.sin × 8px → 0

🏆 Resumen del módulo — y del curso

✓
Composition 1080×1920 — width/height leídos mediante useVideoConfig para un diseño responsivo.
✓
El texto es el audio — typewriter a 8f/palabra + bounce con Easing.back(1.5).
✓
Glitch en los primeros 3 segundos — 3 capas, offset 3–8px, aleatoriedad con semilla, se estabiliza en 6 fotogramas.
✓
Onda sonora visual — Math.sin(frame * 0.15 + seed) con 32 barras oscilantes.
✓
Bokeh computacional — círculos con blur 8–20px que flotan en un loop con semilla.
✓
Subscribe en los últimos 5 s — Sequence from=durationInFrames-150, frame local de la campana.

🎓 ¡Completaste la Ruta 4 y el curso!

Recorriste las 4 rutas: Fundamentos (T1), Recursos y plantillas (T2), Combinación y composición (T3) y ahora Proyectos completos (T4). Con las 81 plantillas de la biblioteca y las técnicas que aprendiste, tienes todo lo necesario para crear cualquier video programático, desde aperturas de canal hasta Reels virales.