Cuando los desarrolladores front-end y diseñadores UX se plantean construir una interfaz web que transmita sensaciones táctiles, el enfoque habitual suele ser recurrir a motores físicos como Matter.js o Cannon.js para simular movimientos dinámicos. Sin embargo, el equipo de Isadora Agency llevó un planteamiento distinto al crear Stress Release, un juguete digital para liberar estrés enfocado en que usuarios puedan apretar, estirar y distorsionar personajes animados de la interfaz.
Inicialmente se exploró la posibilidad de aprovechar estos motores físicos para imitar movimientos realistas y reacciones físicas naturales. Pero pronto se hicieron conscientes de un aspecto esencial: los animadores habían diseñado movimientos intencionados y específicos cuadro a cuadro, que no podía dejarse a la aleatoriedad o simulaciones aproximadas de la física.
Por ello descartaron totalmente los motores físicos y optaron por un control determinista basado en Lottie, una biblioteca que reproduce animaciones vectoriales a partir de archivos JSON, junto con manipulación directa del DOM y cálculos matemáticos simples para relacionar las interacciones del usuario con estados específicos de animación.
El reto del movimiento intencionado
La prioridad en Stress Release era un control absoluto y detallado de las animaciones. Por ejemplo, para la reacción denominada mega squeeze los animadores crearon una secuencia precisa de 181 frames para la apretura seguida de una secuencia de liberación exacta. Esto exigía una arquitectura capaz de respetar exactamente esos fotogramas, sin ser sustituida por aproximaciones algorítmicas.
Con este enfoque, la interacción del usuario —al pulsar sobre un personaje— disparaba un estado de la animación exacto, garantizando que lo que ve el usuario refleje con fidelidad el diseño artístico.
Retroalimentación táctil mediante mapeo entre DOM y Lottie
La tecnología usada se basa en gestionar animaciones SVG renderizadas internamente por Lottie, controlando directamente elementos del DOM con selectores por ID o clase para activar diferentes segmentos de animación según la interacción.
La clave para generar una sensación táctil satisfactoria fue un mapeo radial del punto de clic desde las coordenadas globales de la página hacia el espacio local del personaje. Se calcula la distancia desde el centro del personaje hasta el punto de interacción usando el teorema de Pitágoras, lo que permite definir zonas concéntricas para puntuar la acción y determinar dónde se muestran efectos visuales específicos, como explosiones.
Por ejemplo, el código determina que si el clic se produce a menos de 10 píxeles del centro, se otorgan 100 puntos y la animación de explosión aparece exactamente en ese punto, reforzando la sensación táctil y el feedback instantáneo para el usuario.
// Cálculo del centro del personaje y posición del clic var x_center = parseFloat($("#playChar").width() / 2); var y_center = parseFloat($("#playChar").height() / 2); var offset = $("#playChar").offset(); var X = parseFloat(e.pageX - offset.left); var Y = parseFloat(e.pageY - offset.top); var a = parseFloat(X - x_center); var b = parseFloat(Y - y_center); var distance = Math.hypot(a, b);
Control preciso de la narrativa mediante segmentos de animación
Se aprovechan como base segmentos definidos de animación dentro de los archivos JSON de Lottie, que representan estados del personaje tales como reposo, distintas intensidades de reacción y estados finales.
Al recibir un clic activo, el código detiene la animación actual e inicia el segmento de reacción correspondiente según la secuencia y la intensidad deseadas. Al concluir, vuelve a un bucle de reposo para esperar nuevas interacciones.
const play_segments = [{ charId: 0, sections: { idle: [0, 40], squeeze1: [41, 80], squeeze2: [81, 120], squeeze3: [121, 160], }, playOrder: ["squeeze1", "squeeze2", "squeeze3"], endAnimation: [161, 200]}];
Así, se consigue un control semántico y estrictamente dirigido de todas las animaciones, ajustándose perfectamente a la intención creativa.
Adaptabilidad y rendimiento con elementos DOM
Un beneficio clave de usar animaciones gestionadas en el DOM fue la facilidad para asegurar un comportamiento responsive sin complejas modificaciones al tamaño y zonas de colisión de los elementos animados. El escalado se controla mediante variables CSS que se actualizan al cambiar la ventana del navegador, logrando que las animaciones escalen fluidamente sin perder estado ni calidad visual.
Para optimizar la carga y ejecución en dispositivos móviles, se aplicaron estrategias como la monitorización de conexión para ajustar la carga, la carga secuencial de animaciones para evitar saturaciones, la gestión agresiva de memoria destruyendo animaciones pesadas cuando no se usan y reducción dinámica de calidad según el contexto de la escena.
const appHeight = () => { const doc = document.documentElement; doc.style.setProperty("--doc-height", `${window.innerHeight}px`); doc.style.setProperty("--doc-width", `${doc.clientWidth}px`);} window.addEventListener("resize", appHeight); appHeight();
Elegir la tecnología adecuada según el diseño
Este proyecto subraya la importancia de que el stack tecnológico se adapte a las necesidades concretas del diseño y la experiencia buscada. Al priorizar un control exacto de los movimientos intencionados sobre simulaciones físicas emergentes, permitieron a los animadores conservar la dirección artística y a los desarrolladores controlar con precisión cómo y cuándo se disparaban las animaciones.
Con este método, combinar la potencia del timeline nativo de Lottie con la manipulación del DOM abre la puerta a experiencias web táctiles, inmersivas y con un feedback instantáneo y fiel al diseño.
Recursos para experimentar
- Demostración práctica: Un ejemplo simplificado en CodePen muestra cómo un personaje responde a clics con `playSegments()`.
- Producto final: En la web de Stress Release pueden verse los 21 personajes y la optimización aplicada en acción.
- Documentación oficial: La documentación de Lottie Web explica con detalle los métodos `loadAnimation()`, `playSegments()`, `setSpeed()` y `setQuality()`, fundamentales para entender y aprovechar esta técnica.