Mi lucha por usar y animar un degradado cónico en SVG

La maravillosa empresa para la que trabajo, Payoneer , tiene un nuevo logotipo y mi trabajo consistía en recrearlo y animarlo para un componente de carga en nuestra aplicación. Explicaré exactamente cómo lo hice, compartiré los problemas que tuve y te guiaré a través de la solución que se me ocurrió. Y, como beneficio adicional, ¡veremos cómo animarlo!

Pero primero, supongo que algunos de vosotros os estaréis preguntando… ¿Recrearlo? ¿Por qué?

La agencia de branding que diseñó nuestro logotipo nos envió un conjunto completo de recursos categorizados por temas. Los había en todos los tamaños y en todos los formatos disponibles. Teníamos todo, incluidos SVG, para el logotipo y la animación del cargador. Pero no pudimos usarlos.

Este es el por qué. Echemos un vistazo al logotipo:

El logo es un anillo con un degradado cónico que consta de cinco colores, y… eso es todo. El problema es que SVG no admite gradientes en ángulo (al menos por ahora), por lo que cuando exportamos un diseño que tiene un gradiente cónico como SVG, necesitamos algún tipo de truco para obtener el resultado deseado.

Ahora bien, no soy un experto cuando se trata de trabajar con software de gráficos vectoriales, por lo que podría haber una forma diferente (y quizás mejor) de hacerlo, pero sé que la forma más común de exportar gradientes cónicos a SVG es convertir el elemento degradado a una imagen e inserte esa imagen en el SVG como una cadena base64. Eso también lo obtuvimos de la agencia de branding, y confío en que sabrán cuál es la mejor manera de exportar un SVG.

Pero, dado que el archivo SVG final ahora contiene una cadena PNG base64, el tamaño del archivo saltó a casi 1 MB, lo que puede no ser un desastre total, pero es mucho más alto que los 2 KB que debería ser. Multiplique esa diferencia por tres temas (sin texto, texto claro y variaciones de texto oscuro), y veremos 3 MB de imágenes en lugar de 3 KB de código. Esa es una gran diferencia, por eso hemos decidido recrear el logotipo con SVG.

¡¿Pero cómo?!

Aunque CSS es totalmente compatible con gradientes cónicos , SVG no. Entonces, la primera pregunta que me hice fue cómo crear un degradado cónico en SVG. De hecho, le pregunté a Google. Y lo que encontré fueron muchas formas interesantes, únicas y creativas de agregar gradientes cónicos a SVG, la mayoría de ellas basadas en algún tipo de clip-pathimplementación. Primero creé un corto pathque representa la forma del anillo y lo usé como clip-pathun elemento simple rect.

A continuación, necesitaba llenarlo rectcon degradados cónicos, pero primero tenía que encontrar todas las paradas de color correctas para recrear el aspecto. Me llevó un tiempo, pero después de muchos ajustes, obtuve un resultado con el que estoy contento:

div.gradient {  background-image: conic-gradient(from 270deg, #ff4800 10%, #dfd902 35%, #20dc68, #0092f4, #da54d8 72% 75%, #ff4800 95%);}

El último paso fue reemplazar el rectcon algo más que admita gradientes cónicos, y la forma más sencilla que encontré es usar un foreignObjectelemento SVG con un elemento regular diven su interior y un conic-gradientcomo background-image. Luego todo lo que tenía que hacer era configurar clip-pathel foreignObjectelemento, y eso es todo.

Así es como utilicé un degradado cónico en un SVG para mantener el diseño completamente vectorial y escalable con menos de 20 líneas de código y menos de 2 KB de tamaño de archivo.

Pero esa fue la parte fácil. Ahora hablemos de animación.

el cargador

Nuestra aplicación muestra una animación de carga cada vez que un usuario inicia sesión. Habíamos estado usando un archivo GIF para ello, pero tenía la intención de actualizarlo a una animación CSS/SVG pura durante meses. Los beneficios son obvios: un renderizado más rápido significa una experiencia de carga más fluida y un tamaño de archivo más pequeño significa una carga aún más rápida. Simplemente obtenemos más por menos, lo cual es especialmente ideal para una animación de carga.

Aquí está la animación que buscaba:

Este tipo de animación es bastante fácil con SVG. Todo lo que realmente necesitamos es un truco usando stroke-dasharrayy stroke-dashoffset. Ese fue mi punto de partida. Creé un nuevo pathen el centro del anillo, eliminé el fill, agregué un strokecon la derecha stroke-widthy luego trabajé en la animación.

Me tomó un poco de juego conseguir el movimiento tal como lo querían los diseñadores. En realidad, terminé usando dos animaciones: una controla el stroke-dashoffsety la segunda gira todo pathun giro completo.

Pero, dado que la clip-pathpropiedad se refiere a fillla forma, animar el trazo significaba que tenía que resolver uno de dos problemas: podía encontrar una manera diferente de animar el movimiento o encontrar una manera diferente de agregar los colores al trazo.

Así que volví a Google y a todas las ideas creativas que encontré antes, pero la mayoría de ellas eran prácticamente no animables, así que comencé a buscar una buena forma clip-pathde agregar colores al trazo. Miré algunas soluciones “listas para usar”, revisé el enmascaramiento y terminé con la solución perfecta más simple:

.logoBlend {  mix-blend-mode: lighten;}

Un lightenmodo de fusión analiza los colores RGB de cada píxel del elemento renderizado, lo compara con el valor RGB del píxel de fondo que está detrás de él y mantiene el que sea más alto. Eso significa que las partes del elemento que son blancas permanecerán blancas y las partes oscuras obtendrán los valores del píxel de fondo.

Al agregar un blanco rectal camino negro, básicamente bloqueé todo lo que esté detrás de él. Mientras tanto, todo lo que hay detrás del trazo negro animado es visible. Eso significaba que podía recuperar el foreignObjectcon el conic-gradient, colocarlo detrás de la mix-blend-modecapa y darle una animación de rotación simple para que coincidiera con el diseño.

Note that the end result of this method will have a white background, not transparent like the static logo, but I was fine with that. If you need to, you can flip it around, use black background, and hide the light parts of your element by setting the blend mode to darken.

Final touches

I was pretty much done at this point, and quite happy with the end result. But a couple of days later, I got a Lottie-based JSON file from the branding agency with the exact same animation. In retrospect, maybe I could spare my work and use their file, it would have worked just fine. Even the file size was surprisingly small, but it was still 8✕ bigger than the SVG, so we ended up using my animation anyway.

But, that meant I had one last thing to do. The Lottie animation had a “start animation” where the small orange dot grows into view, and I had to add it to my animation as well. I added a short 0.5s delay to all three animations as well as a scaling animation in the beginning.

Click on “Rerun” on the Pen to see the animation again from the initial dot.

That’s it! Now my company has a new logo and a set of lightweight, fully scalable assets to use across our web platforms.

And for those of you wondering, yes, I did end up creating a nice little Logo component in React since we’re using it. It even renders the SVG according to a theme passed to it as a prop, making the implementation easier, and keeping all future changes in a single location.

What about you?

Do you think there’s a better way to get the same result? Share your thoughts in the comments! And thank you for reading.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir