Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/lucumaagency/video-scrolling/archive/refs/heads/main.zipPlugin de WordPress para recorridos cinematográficos controlados por scroll.
Dibuja una secuencia de frames WebP en un <canvas>: el scroll no mueve la
imagen, elige qué frame se pinta.
Por qué canvas y no <video>
Safari en iOS no permite hacer seek fiable de un <video> desde el scroll.
Se producen saltos y congelamientos justo en el dispositivo donde más se ve una
landing inmobiliaria. Con frames el comportamiento es idéntico en todos lados.
El costo es ~3× el peso del MP4, y a cambio funciona siempre.
Instalación
Con Deployer for Git (o cualquier deploy por repo): el repo ES el plugin.
proba-scroll.php va en la raíz, no dentro de una subcarpeta. Deployer clona en
wp-content/plugins/video-scrolling/ y WordPress encuentra la cabecera ahí
mismo. Si el plugin quedara un nivel más abajo, WP no lo detecta.
A mano: descargar el ZIP del repo, y en WP Admin → Plugins → Añadir nuevo →
Subir plugin. Ojo: el ZIP de GitHub trae una carpeta contenedora
video-scrolling-main/, que WordPress acepta sin problema porque el archivo
principal sigue quedando a un nivel.
Al activar se crea wp-content/uploads/proba-scroll/ con su .htaccess.
Crear una secuencia
Con ffmpeg en el servidor (el plugin lo detecta y lo avisa en el panel): sube el MP4 en Proba Scroll → Nueva secuencia. El plugin extrae los frames.
Sin ffmpeg (lo normal en hosting compartido): genera el ZIP en local.
./build-frames.sh living-cinematic.mp4 living
Y sube build/living.zip en el panel.
Después, en Editar, define los capítulos: kicker, título, texto y el rango de frames en el que cada uno aparece.
Ficha del proyecto
En la misma pantalla de Editar, debajo de los ajustes, va la ficha que se pinta arriba a la derecha sobre el recorrido: rótulo, cliente, características con icono y precio total.
| Campo | Ejemplo |
|---|---|
| Rótulo | Info del cliente |
| Cliente | Diego Rey |
| Características | 🛏 Nº de Dorm · 3 Dormitorios |
| 🛁 Nº de Baños · 2 Baños | |
| 👁 Vista · Calle | |
| 🍳 Cocina · Abierta | |
| Precio total | S/ 336,200.00 |
| Nota | Incluye acabados. No incluye gastos notariales. |
Hay 10 iconos: dormitorio, baño, vista, cocina, área, estacionamiento, depósito, piso, entrega y ubicación. Son SVG inline, sin librería externa.
El precio es texto libre y se pinta tal cual: así la moneda y el separador de miles quedan como los escribe el comercial, sin que el plugin adivine formato.
Una fila sin valor no se guarda, y si la ficha entera queda vacía no se pinta
nada. Se puede apagar con ficha="no" en el shortcode o con el check del
elemento de Bricks.
Con varias secuencias encadenadas (seq="living,bedroom") cada una puede llevar
su propia ficha y el panel cambia al pasar de un recorrido al siguiente. Si solo
una tiene ficha, esa se queda fija durante todo el recorrido: es la ficha del
proyecto, no la de la escena.
En móvil el panel deja de ser una columna a la derecha y pasa a una barra arriba con las características en dos columnas.
Uso
[proba_scroll seq="living"]
Atributos: chapters="no", counter="no", ficha="no", px_per_frame="20",
class="...".
En Bricks hay un elemento nativo Proba Scroll en la categoría Proba, con selector de secuencia. No hace falta shortcode.
Decisiones de arquitectura
Los frames nunca entran a la Media Library. Es el error que hunde este tipo
de plugin: WordPress genera tamaños derivados de cada imagen y 192 frames se
convierten en ~1.000 archivos que dejan la Biblioteca inutilizable. Viven en
uploads/proba-scroll/<slug>/, fuera del índice de attachments.
La verdad vive en el manifiesto, no en la base de datos. Cada carpeta lleva
su manifest.json. La opción en wp_options solo guarda la lista de slugs. Así
la carpeta se puede mover, respaldar o restaurar por FTP sin perder nada.
Cache inmutable. Los frames no cambian nunca, así que el .htaccess les
pone max-age=31536000, immutable. El mismo archivo bloquea el listado de
directorio y la ejecución de PHP dentro de la carpeta.
Nada de 100vw para el ancho completo. 100vw incluye la barra de scroll
vertical, así que el bloque queda unos 15 px más ancho que el área visible y
aparece scroll horizontal en toda la página. El ancho real lo mide el JS con
documentElement.clientWidth y lo publica en --proba-vw. Dos líneas inline
antes del bloque fijan la variable antes del primer pintado, porque el script
del footer llegaría tarde.
Al liberar el sticky se usa overflow-x: clip, no visible. Buena parte de
los overflow que rompen el sticky son un overflow-x: hidden puesto a
propósito para contener el scroll horizontal de la página: quitarlo cambia un
bug por otro. clip recorta igual pero no crea un contenedor de scroll, así que
el sticky sobrevive. Sin soporte de clip (Safari < 16) se cae a visible.
La página se escanea antes de pintarla. En template_redirect se busca el
shortcode en el contenido y el elemento en el árbol de Bricks (que vive en
postmeta y no pasa por the_content). Sin ese paso previo el <link rel="preload"> nunca llegaba a imprimirse: cuando el shortcode se ejecuta, el
<head> ya está cerrado. El mismo escaneo permite sacar el CSS en el head en
vez del footer, que era de dónde venía el parpadeo del bloque sin sticky.
El preload se intenta dos veces, en wp_head 5 y 999, con un flag para no
duplicarlo. Bricks pinta el contenido dentro de wp_head para poder sacar su
CSS inline ahí, así que en una página de Bricks el render ocurre después de la
prioridad 5 y en la primera pasada todavía no se sabe qué secuencia hay.
Carga en dos olas. Se esperan los primeros 20 frames y se muestra el hero;
el resto sigue cargando en background con concurrencia de 6. Si un frame se
cuelga hay un timeout de 4 s que arranca igual, y si falta uno se reutiliza el
anterior en vez de romper la secuencia. Además el primer frame va en
<link rel="preload">, para que el primer pintado sea inmediato.
Variante móvil. Al crear la secuencia se genera sm/ a 800 px. En pantallas
menores a 900 px se sirve esa: el capítulo baja de ~6 MB a ~2 MB.
Secuencias generadas
Desde cotizacion-landing/videos/, ambas 1920×1080, 8 s a 24 fps = 192 frames.
El ZIP incluye desktop (1600 px, raíz) y móvil (800 px, sm/), calidad 72:
| Slug | Origen | Desktop | Móvil | ZIP |
|---|---|---|---|---|
living |
walkt-living.mp4 | 8,2 MB | 3,7 MB | 11 MB |
bedroom |
walkt-bethroom.mp4 | 12 MB | 3,6 MB | 15 MB |
Listos en build/living.zip y build/bedroom.zip.
bedroom pesa 45 % más a igual calidad por la textura de la ropa de cama y el
tejido del cabecero. Bajar a q62 solo ahorra 2 MB y empieza a ensuciar las
sábanas, así que no compensa.
Rendimiento de referencia
Medido sobre la prueba a 720p (192 frames):
| Calidad | Ancho | Total | Por frame |
|---|---|---|---|
| 60 | 1600 px | 5,5 MB | 28 KB |
| 72 | 1600 px | 6,3 MB | 32 KB |
| 82 | 1600 px | 8,7 MB | 45 KB |
72 es el punto dulce: sin banding visible en paredes ni cortinas, que es donde primero aparece la compresión.
Pendiente
- Probar en Plesk con el material real.
- Los
px_per_frame(14 por defecto) definen el largo del scroll: 192 frames × 14 = 2.688 px de recorrido. Ajustar al ritmo que se quiera.