En CSS existen los trayectos animados, también denominados como Motion Paths. Se trata de una característica mediante la cuál podemos crear de forma muy sencilla trayectos, rutas o caminos por los que animamos un elemento.
Propiedades de trayectos animables
Para crear estos trayectos debemos realizar dos tareas. En primer lugar, definir el trayecto. En segundo lugar, crear la animación para mover un elemento a través de dicho trayecto, definiendo su punto de partida y su punto final.
Para hacer esto, se utilizan una serie de propiedades CSS prefijadas por offset-
, que son las que veremos en este artículo y tienen resumidas en la siguiente tabla:
Propiedad | Descripción | Más información |
---|---|---|
offset-path | Define un trayecto, ruta o camino. | |
offset-distance | Indica la posición actual en el trayecto. | |
offset-position | Define el punto de inicio del trayecto. | Ver offset-position |
offset-rotate | Define la orientación del elemento del trayecto. | |
offset-anchor | Define el punto de anclaje (punto de origen) del elemento que se mueve por el trayecto. | |
offset | Propiedad de atajo de las anteriores. |
Vayamos viendo cada una de estas propiedades CSS para entenderlas correctamente.
Definir un trayecto
Probablemente, la parte más importante de los Motion Paths (trayectos animados) es definir un trayecto mediante la propiedad offset-path
. Este trayecto creará el camino por el que se puede mover el elemento que animaremos más adelante.
Hay varias formas de crear trayectos con offset-path
. En este artículo vamos a utilizar la función polygon()
, que pertenece a las formas básicas, pero es muy recomendable echar un vistazo luego a estos artículos para conocer más formas de crear trayectos.
La propiedad offset-path
nos permite definir un trayecto de varias formas:
Forma | Descripción |
---|---|
none | No establece ningún trayecto. Es el valor por defecto. |
Forma básica CSS | Una forma básica, mediante funciones como xywh() , circle() , polygon() o similares. |
Función ray() | Permite definir trayectos como porciones de un círculo (ángulo cónico). |
Función path() | Permite definir trayectos mediante rutas de SVG |
Función url() | Permite definir trayectos mediante ficheros externos SVG. |
Como hemos dicho, en este artículo vamos a utilizar la función polygon()
, que sirve para definir un polígono imaginario, indicando los puntos x,y
por donde vamos creando el polígono. Nuestro .element
se moverá a través de un rectángulo invisible definido por polygon()
:
.element {
--size: 50px;
width: var(--size);
height: var(--size);
background: indigo url("robot.png");
background-size: var(--size);
border-top: 5px solid deeppink;
offset-path: polygon(0 0, 350px 0, 350px 100px, 0 100px);
animation: move 5s infinite linear;
}
@keyframes move {
0% { offset-distance: 0%; }
100% { offset-distance: 100%; }
}
<div class="element"></div>
Observa que a .element
le hemos añadido un borde superior rosa. Si te fijas, al seguir el trayecto, el elemento se va girando conforme al trayecto definido. Esto es importante y lo retomaremos más adelante.
Posición actual en el trayecto
Si observas el ejemplo anterior, en la animación move
estamos utilizando la propiedad offset-distance
, que nos permite indicar el tamaño o porcentaje actual, es decir, el fragmento recorrido en el trayecto desde la posición inicial.
En nuestro ejemplo definimos la animación desde el inicio (0%) hasta el final (100%), utilizando porcentajes que es la unidad más cómoda:
@keyframes move {
0% { offset-distance: 0%; }
100% { offset-distance: 100%; }
}
También podríamos utilizar otras unidades o, en lugar de una animación, gestionarlo mediante transiciones o código Javascript más personalizado.
Rotación del elemento
La propiedad offset-rotate
se encarga de definir como vamos a rotar el elemento respecto a su trayecto. En apartados anteriores vimos que la rotación se realizaba de forma automática respecto a su posición en el trayecto. Este es el comportamiento si offset-rotate
está establecido a auto
.
Sin embargo, si modificamos offset-rotate
con el valor 0deg
, estaremos indicando al navegador que ese elemento no debería rotarse.
Los valores que puede tomar esta propiedad son los siguientes:
Valor | Descripción |
---|---|
auto | El valor auto es el valor por defecto. El elemento rota según el trayecto definido. |
auto | Prefijado del valor auto , se le suma el ángulo indicado en |
reverse | El valor reverse es justo el inverso al valor auto . |
reverse | Idem a auto |
Se establece exactamente el ángulo de rotación de |
Veamos un ejemplo utilizando la propiedad offset-rotate
en la animación definida, donde le indicamos que vaya desde 90deg
a 0deg
:
.element {
--size: 50px;
width: var(--size);
height: var(--size);
background: indigo url("robot.png");
background-size: var(--size);
border-top: 5px solid deeppink;
offset-path: polygon(0 0, 350px 0, 350px 100px, 0 100px);
animation: move 5s infinite linear;
}
@keyframes move {
0% {
offset-distance: 0%;
offset-rotate: 90deg;
}
100% {
offset-distance: 100%;
offset-rotate: 0deg;
}
}
<div class="element"></div>
Obviamente, estos valores podemos modificarlos a nuestro criterio y elección, según nos interese.
Punto de anclaje
Mediante la propiedad offset-anchor
podemos establecer un punto de origen para el elemento que se mueve en el trayecto. Por ejemplo, observa la siguiente imagen y ten en cuenta los valores indicados (valor de eje X y valor de eje Y).
- El primero es
100% 100%
: El punto que se moverá por el trayecto es la esquina inferior-derecha. - El segundo es
50% 50%
: El punto que se moverá por el trayecto es el centro de la imagen. - El tercero es
50% 0%
: El punto que se moverá por el trayecto es la antena del robot.
En este caso, estamos usando un trayecto definido con la función path()
, que explicaremos un poco más adelante. Básicamente, crea un camino basado en un trayecto SVG. Luego, con la propiedad offset-anchor
definimos su punto de anclaje:
.element {
--size: 50px;
width: var(--size);
height: var(--size);
background: indigo url("robot.png");
background-size: var(--size);
border-top: 5px solid deeppink;
offset-path: path("m 50 50 h 350 v 100");
offset-anchor: 50% 50%;
animation: move 5s infinite linear;
}
@keyframes move {
0% { offset-distance: 0%; }
100% { offset-distance: 100%; }
}
<div class="element"></div>
Observa que al haber definido 50% 50%
, la rotación la hace sobre el centro de la imagen del robot.
Atajo: La propiedad offset
Por último, como muchas otras propiedades CSS, podemos utilizar la propiedad de atajo offset
que nos permite escribir todas las propiedades individuales que hemos visto, desde una misma propiedad, algo que en muchas ocasiones nos resulta muy cómodo:
.box {
/* offset: <position> <path> <distance> <rotate> / <anchor>; */
offset: path("m 0 0 h 100 v 200") 0% 45deg;
offset: auto path("m 0 0 h 100 v 200") 0% 45deg / 50% 50%;
offset: ray(45deg closest-side) / 40px 20px;
}
Observa que, en el primer y último ejemplo, omitimos la propiedad offset-position
, ya que no nos interesa indicarla (la explicaremos en el próximo artículo). La propiedad offset-anchor
en el primer ejemplo, también la hemos omitido. De necesitar usarla, habría que añadir sus valores, precedidos del carácter /
.
En el próximo artículo nos centraremos en aprender a crear trayectos utilizando la función
ray()
, que nos permitirá definir porciones de un círculo.