Trayectos con curvas

La etiqueta <path> para curvas


Una vez hemos aprendido a crear trayectos lineales con la etiqueta <path> como vimos en el artículo Trayectos lineales, vamos a aprender a crear trayectos más específicos, utilizando curvas y arcos.

Si no has visto el artículo anterior, es recomendable echarle un vistazo antes de continuar. Establece las bases de la etiqueta <path> que es necesario conocer para entender los trayectos curvos.

Operaciones de trayectos

Las siguientes operaciones se pueden establecer en el atributo d de un elemento <path> para crear curvas y trayectos personalizados con formas redondeadas, y se unen a las operaciones lineales del artículo anterior:

Letra Significado Descripción Ejemplo
Trayectos cubic bézier
C Cubic Bézier CurveTo Curva Bézier con puntos de control (a,b) y (c,d). C a,b c,d x,y
S Smooth Cubic Bézier CurveTo Idem, pero suavizada (sin puntos de control). S x,y
Trayectos quadratic bézier
Q Quadratic Bézier CurveTo Curva Bézier Cuadrática con punto de control (a,b) Q a,b x,y
T Smooth Quadratic Bézier CurveTo Curva Bézier Cuadrática suavizada (sin punto de control) T x,y
Trayecto de arco
A Elliptical Arc Curve Curva de arco elíptico A rx ry a l s x,y

Veamos como funcionan cada una de ellas.

Curvas Bézier cúbicas (C)

De la misma forma que estas operaciones lineales que hemos visto, en el atributo d de un elemento <path> también podemos utilizar otras letras que corresponden a operaciones un poco más complejas, mediante las cuales podemos crear trayectos con curvas.

Empecemos con este primer ejemplo, donde aún no utilizaremos curvas, pero nos servirá para crear una. Observa el elemento <path> con clase .curve, concretamente en el atributo d, que tiene la siguiente información: M25,25 C25,25 25,75 25,75.

  • M25,25 establece la posición inicial en la coordenada (25,25).
  • La operación SVG con letra C creará una curva Bézier usando tres puntos.
  • El primer punto (25,25), es el punto de control inicial.
  • El segundo punto (25,75), es el punto de control final.
  • El tercer punto (25,75), es el punto final ha donde se dirige el trayecto.

El código en cuestión sería el siguiente:

<svg viewBox="0 0 100 100" width="275" height="275" style="background:#aaa">
  <path class="curve" d="M25,25 C25,25 25,75 25,75" stroke="steelblue" fill="none" />
</svg>

La «curva» Bézier va desde el punto (25,25) hasta el punto (25,75). En este caso, la curva es una línea recta, ya que tenemos los puntos de control de inicio y final en los puntos (25,25) y (25,75) respectivamente, que son exactamente los mismos que el punto inicial y final del trayecto.

Así pues, vamos a modificar los puntos de control inicio y final a (50,25) y (50,75), de forma que desplazaremos la línea recta, convirtiéndose en una curva. El atributo d tendrá el valor M25,25 C50,25 50,75 25,75. Quedaría así:

  • M25,25 establece la posición inicial en la coordenada (25,25).
  • La operación SVG con letra C creará una curva Bézier usando tres puntos.
  • El primer punto (50,25), es el punto de control inicial.
  • El segundo punto (50,75), es el punto de control final.
  • El tercer punto (25,75), es el punto final ha donde se dirige el trayecto.

El código en cuestión sería el siguiente:

<svg viewBox="0 0 100 100" width="275" height="275" style="background:#aaa">
  <path class="curve" d="M25,25 C50,25 50,75 25,75" stroke="steelblue" fill="none" />
  <!-- Apoyo visual -->
  <path class="line" d="M25,25 L50,25" stroke="indigo" />
  <path class="end line" d="M25,75 L50,75" stroke="indigo" />
  <path class="end line" d="M25,25 L25,75" stroke="darkred" stroke-dasharray="3" />
  <circle class="start dot" cx="50" cy="25" r="1.5" stroke="black" fill="gold" />
  <circle class="end dot" cx="50" cy="75" r="1.5" stroke="black" fill="gold" />
</svg>

Se han añadido varios elementos para mostrar los puntos clave y los «tiradores» que modifican la curva. En este caso, el trayecto pasa a ser curvo porque lo modificamos desplazando los puntos de control.

Curvas Bézier suavizadas (S)

En el caso de las Curvas Bézier suavizadas, se denotan con una S en el atributo d del elemento <path>, y permiten realizar una curva, sin indicar los puntos de control, sino indicando solamente los puntos clave.

Observa el siguiente ejemplo, enfocándote sobre todo en el atributo d de la etiqueta <path>, que contiene el valor M25,25 S25,75 50,25 50,75 75,25:

<svg viewBox="0 0 100 100" width="275" height="275" style="background:#aaa">
  <path class="curve" d="M25,25 S25,75 50,25 50,75 75,25" stroke="steelblue" fill="none" />
  <!-- Apoyo visual -->
  <polyline class="line" points="25,25 25,75 50,25 50,75 75,25" fill="none"
            stroke="darkred" stroke-dasharray="3" />
  <circle class="zero dot" cx="25" cy="25" r="1.5" stroke="black" fill="gold" />
  <circle class="first dot" cx="25" cy="75" r="1.5" stroke="black" fill="gold" />
  <circle class="second dot" cx="50" cy="25" r="1.5" stroke="black" fill="gold" />
  <circle class="third dot" cx="50" cy="75" r="1.5" stroke="black" fill="gold" />
  <circle class="fourth dot" cx="75" cy="25" r="1.5" stroke="black" fill="gold" />
</svg>

En este caso, se realizan las siguientes operaciones:

  • M25,25 se establece la posición en el primero punto: (25,25).
  • Tras la operación S comenzamos a indicar puntos clave, que crearán curvas suavizadas.
  • El siguiente punto es (25,75). Aún no se verá nada, necesitamos otro punto para visualizarlo.
  • Punto 3: (50,25). Se verá una curva desde el primer punto hasta este, tendiendo al segundo punto.
  • Punto 4: (50,75). Necesitamos un nuevo punto para visualizarlo.
  • Punto 5: (75,25). Se verá una curva desde el tercer punto hasta este, tendiendo al cuarto punto.

Se pueden ir añadiendo más puntos para lograr curvas más complejas, o simplemente utilizar otra operación de las mencionadas en la tabla inicial.

Curvas Bézier cuadráticas (Q)

Vamos ahora con las Curvas Bézier cuadráticas, que se denotan con una Q. Nuevamente, en este caso utilizamos puntos de control, uno en cada punto indicado.

Observa el siguiente ejemplo, donde usamos un atributo d con valor M25,25 Q25,75 50,25 50,75 75,25:

<svg viewBox="0 0 100 100" width="275" height="275" style="background:#aaa">
  <path class="curve" d="M25,25 Q25,75 50,25 50,75 75,25" stroke="steelblue" fill="none" />
  <!-- Apoyo visual -->
  <path class="line" d="M25,25 L25,75 M50,25 L50,75" stroke="darkred" stroke-dasharray="3" />
  <circle class="zero dot" cx="25" cy="25" r="1.5" stroke="black" fill="gold" />
  <circle class="first dot" cx="25" cy="75" r="1.5" stroke="black" fill="gold" />
  <circle class="second dot" cx="50" cy="25" r="1.5" stroke="black" fill="gold" />
  <circle class="third dot" cx="50" cy="75" r="1.5" stroke="black" fill="gold" />
  <circle class="fourth dot" cx="75" cy="25" r="1.5" stroke="black" fill="gold" />
</svg>

En este caso hemos hecho lo siguiente:

  • M25,25 establece la posición inicial en la coordenada (25,25).
  • La operación SVG con letra Q creará una curva Bézier usando dos puntos.
  • El primer punto (25,75), es el punto de control de una nueva operación.
  • El segundo punto (50,25), es el punto a donde se dirige el trayecto.
  • El tercer punto (50,75), es el punto de control de una nueva operación.
  • El cuarto punto (75,25), es el punto a donde se dirige el trayecto.

Observa que aunque son los mismos valores numéricos que el ejemplo anterior, en esta curva no se «mantiene la inercia» del trayecto en cada punto, sino que puede producir un pico en dicho punto de la curva.

Curvas cuadráticas suaves (T)

Ahora, vamos con una Curva Bézier cuadrática suavizada, denotada con una T. Nuevamente, no utilizamos puntos de control, sino que en este caso utilizamos los puntos claves, que son los mismos de los ejemplos anteriores.

Observa el siguiente ejemplo, donde usamos un atributo d con valor M25,25 T25,75 50,25 50,75 75,25:

<svg viewBox="0 0 100 100" width="275" height="275" style="background:#aaa">
  <path class="curve" d="M25,25 T25,75 50,25 50,75 75,25" stroke="steelblue" fill="none" />
  <!-- Apoyo visual -->
  <polyline class="line" points="25,25 25,75 50,25 50,75 75,25" fill="none"
            stroke="darkred" stroke-dasharray="3" />
  <circle class="zero dot" cx="25" cy="25" r="1.5" stroke="black" fill="gold" />
  <circle class="first dot" cx="25" cy="75" r="1.5" stroke="black" fill="gold" />
  <circle class="second dot" cx="50" cy="25" r="1.5" stroke="black" fill="gold" />
  <circle class="third dot" cx="50" cy="75" r="1.5" stroke="black" fill="gold" />
  <circle class="fourth dot" cx="75" cy="25" r="1.5" stroke="black" fill="gold" />
</svg>

En este caso, se puede observar que los trayectos son muy alargados, y que nuevamente difieren de los anteriores.

Curvas de arco elíptico (A)

Por último, mediante las curvas de arco elíptico, denotadas con una A, se pueden crear arcos basados en elipses. Veamos un ejemplo, teniendo clara la estructura a utilizar. Observa que utilizamos un atributo d con valor M25,25 A 5 5 1 1 1 75,75:

  • M25,25 establece la posición inicial en el punto (25,25).
  • A 5 5 crea un arco con radio elíptico rx y ry.
  • 1 establece una rotación de 1deg con respecto a x.
  • 1 determina si se usará un arco grande (o arco pequeño si se usa 0).
  • 1 determina la rotación en el sentido de las agujas del reloj (o inverso si se usa 0).
  • 75,75 establece el punto del destino del trayecto.
<svg viewBox="0 0 100 100" width="275" height="275" style="background:#aaa">
  <path class="curve" d="M25,25 A 5 5 1 1 1 75,75" stroke="steelblue" fill="none" />
  <!-- Apoyo visual -->
  <circle class="first dot" cx="25" cy="25" r="1.5" stroke="black" fill="gold" />
  <circle class="second dot" cx="75" cy="75" r="1.5" stroke="black" fill="gold" />
</svg>

Por ejemplo, prueba a utilizar el valor M25,25 A 5 5 1 1 0 75,75, para comprobar que con ese 0, indicamos que debe girar en el sentido contrario de las agujas del reloj, por lo que veremos el arco trazado justo al lado inverso.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev