Morphing SVG con react-spring | Programar Plus

Me ha intrigado el efecto de transformación desde que era un niño. Hay algo en una animación que cambia de forma que siempre capta mi atención. La primera vez que vi morphing me dejó preguntándome “Wow, ¿cómo hicieron eso?” Desde entonces, creé demostraciones y escribí un artículo sobre el efecto.

Hay muchas opciones cuando se trata de diferentes bibliotecas de animación que admiten morphing. Muchos de ellos son buenos y ofrecen numerosas funciones. Últimamente, he sido absorbido por react-spring. React-spring es una ingeniosa biblioteca de animación habilitada para la física construida sobre React. Adam Rackis publicó recientemente una buena descripción general. La biblioteca viene con muchas características que incluyen, entre muchas otras, transformación SVG. De hecho, la belleza de react-spring radica en cómo admite la transformación. Le permite hacerlo directamente en el marcado donde define sus descriptores de rutas SVG. Esto es bueno desde la perspectiva de la contabilidad. Los descriptores de ruta SVG están donde normalmente esperaría que estuvieran.

Aquí hay un video de lo que estamos investigando en este artículo:

Es un efecto de transformación en una secuencia de incorporación. Aquí, se usa como efecto de fondo. Está destinado a complementar la animación de primer plano; para que se destaque un poco más en lugar de apoderarse de la escena.

Creando el documento SVG

Lo primero que queremos hacer es crear el modelo subyacente. Por lo general, una vez que tengo una idea clara de lo que quiero hacer, creo algún tipo de diseño. La mayoría de mis exploraciones comienzan con un modelo y terminan con una demostración. En la mayoría de los casos, significa crear un documento SVG en mi editor de vectores. Utilizo Inkscape para dibujar mis SVG.

Cuando creo documentos SVG, utilizo las proporciones exactas. Encuentro que es mejor ser preciso. Para mí, ayuda a mi percepción de lo que quiero crear cuando uso el mismo sistema de coordenadas en el editor de vectores que en el navegador y el editor de código. Por ejemplo, digamos que está a punto de crear un icono SVG de 24px ✕ 30px, incluido el relleno. El mejor enfoque es utilizar exactamente el mismo tamaño: un documento SVG de 24 píxeles de ancho por 30 píxeles de alto. Si las proporciones resultan ser incorrectas, siempre se pueden ajustar más adelante. SVG es indulgente en ese sentido. Es escalable, no importa lo que hagas.

El documento SVG que estamos creando tiene 256 píxeles de ancho y 464 píxeles de alto.

Dibujando los modelos

Al crear modelos, debemos pensar dónde colocamos los nodos y cuántos nodos usar. Esto es importante. Aquí es donde sentamos las bases para la animación. Modelar es de lo que se trata el morphing. Tenemos un conjunto de nodos que se transforma en otro. Estas colecciones de nodos deben tener exactamente el mismo número de nodos. En segundo lugar, estos conjuntos deberían correlacionarse de alguna manera.

Si la relación entre las formas vectoriales no se piensa detenidamente, la animación no será perfecta. Todos y cada uno de los nodos afectarán la animación. Su posición y curvatura deben ser las correctas. Para obtener información más detallada sobre cómo se construyen los nodos en las rutas SVG, consulte la explicación de las curvas de Bézier en MDN.

En segundo lugar, debemos tener en cuenta ambas formas. Uno de los vectores puede contener partes que no se encuentran en el otro. O puede haber otras diferencias entre los dos modelos. Para estos casos, puede ser una buena idea insertar nodos adicionales en ciertos lugares. Lo mejor es formar estrategias. Como, esta esquina va allí, esta línea recta se abulta en una curva y así sucesivamente.

He armado un bolígrafo para ilustrar cómo se ve cuando los conjuntos se correlacionan mal con cuando están diseñados con precisión. En el siguiente ejemplo, en el efecto de transformación de la izquierda, los nodos se colocan aleatoriamente. Los nodos que componen el número uno y dos no tienen relación. En el ejemplo de la derecha, la ubicación de los nodos se planifica con más cuidado. Esto conduce a una experiencia más coherente.

El primer modelo

La herramienta de línea es lo que usamos para dibujar la primera forma de vector. Como el modelo que estamos creando es más abstracto, es un poco más indulgente. Todavía tenemos que pensar en la ubicación y la curvatura, pero permite un mayor descuido.

En cuanto a los vectores y el tamaño, lo mismo ocurre con la creación de modelos para la transformación. Es un proceso iterativo. Si no está bien la primera vez, siempre podemos volver atrás y ajustarnos. Por lo general, requiere una o dos iteraciones para que la animación brille. Así es como se ve el modelo cuando está completo.

El resultado es una forma SVG abstracta suave con ocho nodos.

El segundo y tercer modelo

Una vez que se completa el primer modelo, es hora de dibujar el segundo modelo (que también podemos considerar como un estado). Esta es la forma en la que se transformará el primer conjunto. Este podría ser el estado final, es decir, un único efecto de transformación. O podría ser un paso en el camino, como un fotograma clave. En el caso que estamos viendo, hay tres pasos. Nuevamente, cada modelo debe correlacionarse con el anterior. Una forma de asegurarse de que los modelos coincidan es crear el segundo vector como un duplicado del primero. De esta manera, sabemos que los modelos tienen el mismo número de nodos y la misma apariencia.

Tenga cuidado con el editor. Los editores de vectores suelen optimizar el tamaño y el formato de los archivos. Es muy posible que los modelos sean incompatibles al guardar los cambios. Me he acostumbrado a inspeccionar el código SVG después de guardar el archivo. También ayuda si está familiarizado con el formato del descriptor de ruta. Es un poco críptico si no estás acostumbrado. También podría ser una buena idea deshabilitar la optimización en las preferencias del editor de vectores.

Repite el proceso anterior para la tercera forma. Copie, reubique todos los nodos y establezca el tercer color.

¡Luces, CAMARA, ACCION!

Una vez creados los modelos, hemos realizado la mayor parte del trabajo. Ahora es el momento de mirar la parte de la animación. React-spring viene con un conjunto de ganchos que podemos usar para animación y morphing. useSpring es un candidato perfecto para el efecto en este ejemplo. Está destinado a ser utilizado para animaciones individuales como la que estamos creando. Aquí se explica cómo iniciar animaciones con el useSpring gancho.

const [{ x }, set] = useSpring(() => ({
  x: 0,
}));

Lo anterior nos da una propiedad de animación, x, para construir nuestro efecto morphing. Una gran cosa acerca de estas propiedades de animación es que podemos modificarlas para crear casi cualquier tipo de animación. Si el valor está desactivado, podemos cambiarlo mediante interpolación.

El segundo parámetro, el set función, nos permite activar actualizaciones. A continuación se muestra un fragmento de código que muestra su uso. Actualiza el valor de la animación. x con un gestor de gestos useDrag de la biblioteca reaccionar-usar-gestos. Hay muchas formas en las que podemos activar animaciones en react-spring.

const bind = useDrag(
  ({ movement: [x] }) => {
    // ...
    set({ x });
  },
);

Ahora tenemos todo configurado para combinar nuestros modelos, los descriptores de ruta, con el marcado. Añadiendo el animated palabra clave al código JSX, activamos el sistema de animación de react-spring. Con la llamada de interpolación to, previamente nombrado interpolate, convertimos distancias de arrastre en formas transformadas. La matriz de salida contiene los modelos ya discutidos. Para ponerlos en su lugar, simplemente copiamos los descriptores de ruta del archivo SVG en el marcado. Tres descriptores diferentes, d, de tres diferentes path los elementos copiados de tres archivos SVG diferentes ahora se combinan en uno. Así es como se ve el nodo JSX cuando se alimenta con una animación de resorte de reacción.

<svg ...>
  <animated.path
    d={x.to({
      range: [-400, -200, 0],
      output: [
        // First model
        "M 157.81292,131.16918 C 128.33979,127.45582 59.004493,121.76045 53.287478,168.06051 47.570462,214.36057 86.454799,213.14326 77.881699,234.66986 69.308599,256.19646 59.042495,268.13837 67.634107,288.98209 76.225718,309.82581 103.27857,320.05328 138.34249,312.55156 173.40641,305.04984 204.93111,298.87002 208.02612,279.75926 211.12113,260.6485 189.48716,257.88808 188.5557,229.54606 187.62424,201.20404 212.01456,174.45091 200.8528,155.7634 189.69104,137.07589 187.28605,134.88254 157.81292,131.16918 Z",
        // Second model
        "M 157.81292,131.16918 C 128.33979,127.45582 48.756902,138.1566 53.287478,168.06051 57.818054,197.96442 75.182448,197.77187 73.782662,224.42227 72.382877,251.07266 70.314846,257.89078 72.757903,278.7345 75.20096,299.57822 88.114636,303.32873 113.94876,307.60312 139.78288,311.87751 159.84171,314.24141 176.25858,295.13065 192.67546,276.01989 203.83379,256.86332 190.60522,228.5213 177.37665,200.17928 205.866,189.8223 211.10039,171.13479 216.33478,152.44728 187.28605,134.88254 157.81292,131.16918 Z",
        // Third model
        "M 157.81292,131.16918 C 128.33979,127.45582 86.672992,124.83473 71.733144,166.01099 56.793295,207.18725 69.033893,203.92043 80.955976,230.57083 92.87806,257.22123 55.968217,259.9403 59.436033,279.75926 62.90385,299.57822 94.985717,299.83924 132.0922,306.16316 169.19868,312.48708 186.48544,320.38997 198.80328,288.98209 211.12113,257.57422 199.73475,245.59097 195.72902,217.24895 191.72328,188.90693 209.96504,178.54995 215.19943,159.86244 220.43382,141.17493 187.28605,134.88254 157.81292,131.16918 Z",
      ],
    })}
  />
</svg>

Veamos las diferencias entre un JSX estándar path elemento y lo que tenemos actualmente. Para poner la animación morphing en su lugar, tenemos:

  • agregó la palabra clave animada para hacer el JSX path elemento animado con resorte React,
  • cambió el descriptor d de una cadena a una interpolación de resorte React, y
  • convertido la distancia x a una animación de fotogramas clave entre tres path descriptores.

Entorno de desarrollo

Todavía tengo que encontrar el entorno de desarrollo perfecto para trabajar con SVG. Actualmente, voy y vengo entre el editor de vectores, el IDE y el navegador. Hay un poco de copia y redundancia involucrada. No es perfecto, pero funciona. He experimentado un poco, en el pasado, con scripts que analizan SVG. Todavía no he encontrado algo que pueda aplicar a todos los escenarios. Tal vez sea solo yo quien se equivocó. De lo contrario, sería genial si el desarrollo web con SVG pudiera ser un poco más fluido.

¡Aquí vamos!

Por último, pero no menos importante, ¡la demostración!

¡Gracias por leer!

(Visited 5 times, 1 visits today)