En SVG, existe un atributo denominado transform
mediante el cuál se pueden hacer transformaciones a las formas, figuras y trazos dibujados. Las transformaciones SVG son muy similares a las transformaciones CSS, sin embargo tienen algunas diferencias sustanciales.
Estas son las funciones que podemos utilizar para realizar transformaciones:
Función | Descripción |
---|---|
translate(x y) | Traslada (mueve) el elemento x unidades en horizontal, y y unidades en vertical. |
rotate(a x y) | Rota el elemento a grados, utilizando el punto de origen (x, y) . |
scale(x y) | Escala el elemento x unidades en horizontal y y unidades en vertical. |
scale(s) | Escala el elemento s unidades en horizontal y vertical. |
skewX(x) | Deforma el elemento x unidades en horizontal. |
skewY(y) | Deforma el elemento y unidades en vertical. |
Una diferencia importante respecto a HTML/CSS, es que en SVG los valores por parámetro no se separan por comas, ni se utilizan unidades como
px
, ya que indicamos las unidades delviewbox
.
Observa la siguiente imagen SVG con fondo gris, donde tenemos un cuadrado color violeta del tamaño de la mitad del lienzo, colocado al inicio.
<svg viewBox="0 0 100 100" height="300" style="background:grey">
<rect x="0" y="0" width="50" height="50" fill="indigo">
</svg>
En los siguientes ejemplos, vamos a añadirle un atributo transform
al elemento <rect>
para realizar transformaciones. En las demostraciones interactivas puedes variar los valores de la función de transformación y observar la diferencia visual.
La función translate()
Mediante la transformación translate()
podemos realizar movimientos o desplazamientos en horizontal y vertical. Observa que los parámetros, aunque pueden ir separados por comas, es más habitual separarlo únicamente con espacios.
<svg viewBox="0 0 100 100" height="300" style="background:grey">
<rect x="0" y="0" width="50" height="50" fill="indigo" transform="translate(50 50)">
</svg>
<p>Valor de <code>X</code>: <input class="x" type="range" min="-25" max="75" value="50"></p>
<p>Valor de <code>Y</code>: <input class="y" type="range" min="-25" max="75" value="50"></p>
<code>transform="translate(</code><output>50 50</output><code>)"</code>
const x = document.querySelector(".x");
const y = document.querySelector(".y");
const rect = document.querySelector("rect");
const output = document.querySelector("output");
const update = () => {
output.value = `${x.value} ${y.value}`;
rect.setAttribute("transform", `translate(${x.value} ${y.value})`);
}
x.addEventListener("input", () => update());
y.addEventListener("input", () => update());
La función rotate()
Mediante la función rotate()
debemos indicar tres parámetros: el ángulo (de 0 a 360), el punto de referencia de x
y el punto de referencia de y
. El único obligatorio es el ángulo, ya que si no indicamos valores x
e y
, ambos valdrán 0
.
<svg viewBox="0 0 100 100" height="300" style="background:grey">
<rect x="0" y="0" width="50" height="50" fill="indigo" transform="rotate(45 50 50)">
</svg>
<p>Angulo de rotación: <input class="a" type="range" min="0" max="360" value="45"></p>
<p>Valor de <code>X</code>: <input class="x" type="range" min="0" max="50" value="50"></p>
<p>Valor de <code>Y</code>: <input class="y" type="range" min="0" max="50" value="50"></p>
<code>transform="rotate(</code><output>45 50 50</output><code>)"</code>
const a = document.querySelector(".a");
const x = document.querySelector(".x");
const y = document.querySelector(".y");
const rect = document.querySelector("rect");
const output = document.querySelector("output");
const update = () => {
output.value = `${a.value} ${x.value} ${y.value}`;
rect.setAttribute("transform", `rotate(${a.value} ${x.value} ${y.value})`);
}
a.addEventListener("input", () => update());
x.addEventListener("input", () => update());
y.addEventListener("input", () => update());
La función scale()
La transformación scale()
nos permite escalar nuestro objeto, y hacerlo más pequeño (valores inferiores a 1) o más grande (valores superiores a 1). Observa el siguiente ejemplo, que tiene un scale(1)
por defecto. Esto significa que el elemento no estará alterado, sino que estará a su tamaño real.
Si indicamos un scale(2)
, el elemento tendrá el doble de tamaño, si indicamos un scale(0.5)
tendrá la mitad de su tamaño real.
<svg viewBox="0 0 100 100" height="300" style="background:grey">
<rect x="0" y="0" width="50" height="50" fill="indigo" transform="scale(1)">
</svg>
<p>Escala: <input class="s" type="range" min="0" max="2" step="0.1" value="1"></p>
<code>transform="scale(</code><output>1</output><code>)"</code>
const s = document.querySelector(".s");
const rect = document.querySelector("rect");
const output = document.querySelector("output");
const update = () => {
output.value = `${s.value}`;
rect.setAttribute("transform", `scale(${s.value})`);
}
s.addEventListener("input", () => update());
También es posible indicar dos parámetros, de modo que si indicamos scale(1 2)
, significa que el elemento tendrá el mismo tamaño en horizontal, pero el doble en vertical.
La función skewX()
/ skewY()
Por último, las funciones de transformación skewX()
y skewY()
permiten deformar o torcer un elemento. Juega un poco con los controles de la demo y observarás el resultado de deformar elementos en los diferentes ejes.
<svg viewBox="0 0 100 100" height="300" style="background:grey">
<rect x="0" y="0" width="50" height="50" fill="indigo" transform="skewX(45) skewY(0)">
</svg>
<p>Valor de <code>X</code>: <input class="x" type="range" min="-45" max="45" value="45"></p>
<p>Valor de <code>Y</code>: <input class="y" type="range" min="-45" max="45" value="0"></p>
<code>transform="</code><output>skewX(45) skewY(0)</output><code>"</code>
const x = document.querySelector(".x");
const y = document.querySelector(".y");
const rect = document.querySelector("rect");
const output = document.querySelector("output");
const update = () => {
output.value = `skewX(${x.value}) skewY(${y.value})`;
rect.setAttribute("transform", `skewX(${x.value}) skewY(${y.value})`);
}
x.addEventListener("input", () => update());
y.addEventListener("input", () => update());
Como habrás visto, ten en cuenta que es posible aplicar múltiples transformaciones simplemente separando por espacio las funciones de transformación.