Movimiento continuo en Web
Desde RC.7: colores, bordes, pintura continua, tamaño real, FLIP y escenas con seek amplían este runtime. Las APIs Web siguen experimentales; la paridad completa continúa en #236.
Desde 0.1.0-rc.6, motionValue(), bind(), springValue() y drag() están disponibles en @rafaelaugusto/jolt/web. Las APIs Web siguen experimentales; las entradas nativas y el adapter Vue conservan sus contratos.
Valores de entrada y bindings
import { createWebRuntime } from '@rafaelaugusto/jolt/web'
const motion = createWebRuntime(document)
const input = motion.motionValue(0)
const follower = motion.springValue(input, { stiffness: 170, damping: 22 })
const binding = motion.bind(card, { x: follower })
input.set(180)
input.set(60)
binding.dispose()
follower.dispose()
input.dispose()
motion.release(card)
motion.dispose()Los valores pertenecen al contexto. get() lee el número actual; getVelocity() usa unidades/segundo. set() cambia la entrada inmediatamente y las escrituras visuales se agrupan por frame. Se admiten x/y/rotación/escala/opacidad; scale se expande a scaleX/scaleY. Se rechazan valores ajenos al contexto, descartados o no numéricos antes de sustituir el control existente.
subscribe(listener) observa cambios después de las escrituras programadas y devuelve la función de desuscripción; no emite el valor inicial. Los callbacks tienen coste JavaScript propio y no convierten animaciones WAAPI independientes en loops. Los mapeos numéricos y cadenas limitadas están en el soporte Web de RC.6. RC.7 añade mapeos de color y bindings continuos de pintura; la paridad completa sigue en #236.
El binding posee solo sus canales de base. animate(), set() y stop() posteriores sustituyen los canales correspondientes; los demás y las capas press continúan. Descartar un binding antiguo no restaura valores obsoletos. Desvincular mantiene el valor actual. release() restaura los estilos inline que aún controla y cancela el trabajo; quitar el elemento del DOM hace lo mismo. Los valores pueden sobrevivir al elemento: descártalos o descarta el runtime. Descartar una entrada descarta también sus followers.
Scheduler y springs
Un scheduler por contexto agrupa lecturas, actualizaciones y escrituras mediante timestamps, sin paso fijo de 60 Hz. Deja de programar frames cuando entradas, observadores y movimiento se estabilizan. El tiempo del documento oculto no avanza las springs continuas; al volver no se simula todo el intervalo. Los relojes WAAPI finitos mantienen la timeline del navegador.
Mientras una superficie tiene bindings vivos, el scheduler compone también sus canales finitos; las demás superficies conservan WAAPI. Desvincular devuelve los tracks finitos a WAAPI sin reiniciar sus relojes. La composición continua requiere JavaScript y no garantiza ejecución por compositor.
La spring sigue un valor numérico legible del mismo contexto con el solver analítico portátil. Admite stiffness, damping, mass o duration/bounce, además de initial, restDelta (0,001 unidades) y restSpeed (0,01 unidades/segundo). pause() conserva posición/velocidad mientras cambia la entrada; play() retoma hacia el destino actual; stop() mantiene posición con velocidad cero; jump() alcanza la entrada; dispose() es terminal.
El movimiento reducido estabiliza todos los followers genéricos, incluso sin bindings; la entrada directa sigue siendo directa. Cada trayectoria nueva captura el timeScale actual, sin reescalar trayectorias activas. Damping cero puede mantener trabajo hasta detener o descartar.
Drag y snap finito
const drag = motion.drag(card, {
axis: 'x',
bounds: { left: -120, right: 120 },
snap: { x: [-100, 0, 100] },
spring: { stiffness: 180, damping: 20 },
})Drag usa un puntero primario y traslación x/y en píxeles CSS. La transformación estática del target debe ser identidad; los ancestros que afectan su geometría no pueden introducir transforms, perspectiva o zoom CSS. RC.7 admite transforms identidad y termina en la raíz real modal/popover de la top layer, cuya propia geometría sigue importando; vea geometría de overlays. Rotación/escala de Jolt y press se componen después de la traslación. Scroll y resize cancelan el drag; espacios arbitrariamente transformados, pinch y handoff de scroll anidado siguen fuera.
Drag toma la traslación en pointerdown y captura el puntero. Aplica temporalmente touch-action: pan-y para x, pan-x para y o none para ambos, restaurando el valor inline al descartar. Los controles interactivos internos conservan su entrada. Taps y activación por teclado siguen funcionando; un drag suprime su clic resultante. Disabled/inert/busy, cancelación, pérdida de captura/foco, ocultación y desmontaje cancelan sin snap de éxito.
Bounds limita la entrada y los destinos; la spring puede sobrepasarlos. Snap elige por eje con una proyección de velocidad de 150 ms; sin puntos vuelve a la posición al adjuntarse. La velocidad usa muestras recientes, se hace cero tras 80 ms sin movimiento y se limita a 5.000 píxeles CSS/segundo. Al soltar, posición/velocidad pasan a playback WAAPI finito. Un drag nuevo puede capturarlo; un nuevo dueño de la aplicación cancela el anterior sin restaurar su traslación.
drag.animation expone el último snap y finished. update({ disabled: true }) cancela la entrada; cancel() mantiene la posición sin snap; dispose() detiene solo su snap. El descarte del elemento/runtime libera bindings/listeners. La alternativa de teclado y la semántica accesible pertenecen al componente.
Referencias nativas y validación
Las grabaciones revisadas conservan las implementaciones nativas existentes. Muestran valores, followers y drag nativos; no el nuevo scheduler Web ni una pantalla compartida de Mavis. Las APIs nativa y Web conservan subconjuntos distintos.
Ejecuta npm run web:dynamic:typecheck y npm run web:dynamic:test. Chromium, Firefox y WebKit cubren composición, cancelación y limpieza. La inyección de scroll táctil real usa solo Chromium; los demás conservan pruebas de cancelación de puntero. Las pruebas de tiempo oculto controlan la señal de visibilidad y no miden background en móviles físicos. Consulta el informe reproducible. CI nativo y consumidores reales Web/Vue/SSR/nativos siguen siendo obligatorios. Esta entrega no cambia Mavis ni añade otro framework.