CÓMO CREAR IMÁGENES SVG EN PROGRAMACIÓN WEB
Introducción a los Gráficos SVG
Los gráficos vectoriales escalables (SVG) son una herramienta poderosa para desarrolladores web que buscan crear imágenes interactivas y dinámicas sin depender de archivos externos o bibliotecas de terceros. SVG permite incrustar gráficos directamente en el código HTML, ofreciendo flexibilidad para manipularlos con CSS y JavaScript. Este formato es ideal para íconos, diagramas y animaciones simples, ya que su sintaxis es similar a la de HTML, lo que facilita su integración en proyectos web modernos. En este tutorial, exploraremos cómo crear y manipular SVG, desde formas básicas hasta animaciones y diagramas dinámicos, con ejemplos prácticos que puedes implementar en tus aplicaciones.
Entendiendo la Etiqueta SVG
La etiqueta <svg> es el contenedor principal para cualquier gráfico SVG. Define el marco de la imagen, especificando su tamaño externo mediante los atributos width y height, y su sistema de coordenadas interno con viewBox. El atributo viewBox en SVG determina cómo se posicionan los elementos dentro del gráfico, mientras que width y height controlan el tamaño que ocupa en la página web. Por ejemplo, un viewBox de “-100 -100 200 200” centra el sistema de coordenadas en (0,0), con 200 unidades de ancho y alto. Cambiar el viewBox puede escalar o recortar la imagen sin alterar su tamaño externo.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<circle cx="0" cy="0" r="50" fill="blue" />
</svg>
En este ejemplo, se dibuja un círculo centrado en (0,0) con un radio de 50 unidades. Si ajustamos el viewBox a “-50 -50 100 100”, el círculo aparecerá más grande, ya que el sistema de coordenadas se reduce, pero el tamaño externo permanece en 200x200 píxeles.
Creando un Ornamento Navideño con SVG
Comencemos con un ejemplo simple: un ornamento navideño compuesto por un círculo grande, un círculo pequeño y un rectángulo. Los elementos SVG como <circle> y <rect> usan atributos para definir posición y estilo. El atributo fill establece el color de relleno, mientras que stroke y stroke-width definen el borde.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<circle cx="0" cy="20" r="70" fill="#D1495B" />
<circle
cx="0"
cy="-75"
r="12"
fill="none"
stroke="#F79257"
stroke-width="2"
/>
<rect x="-17.5" y="-65" width="35" height="20" fill="#F79257" />
</svg>
Este código crea un círculo rojo grande, un anillo naranja más pequeño y un rectángulo naranja, formando un ornamento. Las coordenadas están relativas al viewBox, con el origen (0,0) en el centro de la imagen. Ajustar estas coordenadas permite mover los elementos con precisión.
Construyendo un Árbol de Navidad con SVG
Para formas más complejas, podemos usar el elemento <polygon>, que conecta una lista de puntos con líneas rectas. Un árbol de Navidad puede representarse con varios polígonos para las ramas y un rectángulo para el tronco.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<polygon points="0,0 80,120 -80,120" fill="#234236" />
<polygon points="0,-40 60,60 -60,60" fill="#0C5C4C" />
<polygon points="0,-80 40,0 -40,0" fill="#38755B" />
<rect x="-20" y="120" width="40" height="30" fill="brown" />
</svg>
Cada <polygon> define una rama del árbol, con puntos especificados en el atributo points. El rectángulo actúa como el tronco. Para determinar las coordenadas, es útil esbozar el diseño en papel o ajustar los valores iterativamente hasta lograr el resultado deseado.
Creando una Figura de Pan de Jengibre con SVG
Podemos mejorar la legibilidad del código moviendo los estilos a CSS, asignando clases a los elementos SVG. Por ejemplo, una figura de pan de jengibre puede usar círculos para el cuerpo y ojos, un rectángulo para la boca y líneas para los brazos y piernas.
<svg class="gingerbread" width="200" height="200" viewBox="-100 -100 200 200">
<circle class="body" cx="0" cy="-50" r="30" />
<circle class="eye" cx="-12" cy="-55" r="3" />
<circle class="eye" cx="12" cy="-55" r="3" />
<rect class="mouth" x="-10" y="-40" width="20" height="5" rx="2" />
<line class="limb" x1="-40" y1="-10" x2="40" y2="-10" />
<line class="limb" x1="-25" y1="50" x2="0" y2="-15" />
<line class="limb" x1="25" y1="50" x2="0" y2="-15" />
<circle class="button" cx="0" cy="-10" r="5" />
<circle class="button" cx="0" cy="10" r="5" />
</svg>
.gingerbread .body {
fill: #cd803d;
}
.gingerbread .eye {
fill: white;
}
.gingerbread .mouth {
fill: none;
stroke: white;
stroke-width: 2px;
}
.gingerbread .limb {
stroke: #cd803d;
stroke-width: 35px;
stroke-linecap: round;
}
El atributo rx en el rectángulo redondea las esquinas, similar a border-radius en CSS. El atributo stroke-linecap en SVG con valor round da a las líneas un acabado suave, ideal para los brazos y piernas.
Dibujando una Estrella con Transformaciones SVG
Las transformaciones, como rotate y translate, permiten crear formas complejas a partir de elementos simples. Para una estrella, podemos definir un ala como un grupo de polígonos y rotarlo cinco veces.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<g transform="translate(0 5)">
<g>
<polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
<polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
</g>
<g transform="rotate(72)">
<polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
<polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
</g>
<g transform="rotate(-72)">
<polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
<polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
</g>
<g transform="rotate(144)">
<polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
<polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
</g>
<g transform="rotate(-144)">
<polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
<polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
</g>
</g>
</svg>
El elemento <g> agrupa los polígonos, funcionando como un contenedor similar a un <div> en HTML. La transformación translate(0 5) desplaza la estrella hacia abajo, mientras que rotate crea las alas adicionales.
Creando un Copo de Nieve con Reutilización de Elementos
Para evitar repetir código, podemos definir formas en la sección <defs> y reutilizarlas con <use>. Un copo de nieve puede crearse definiendo una rama como un <path> y rotándola seis veces.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<defs>
<path
id="branch"
d="
M 0 0 L 0 -90
M 0 -20 L 20 -34
M 0 -20 L -20 -34
M 0 -40 L 20 -54
M 0 -40 L -20 -54
M 0 -60 L 20 -74
M 0 -60 L -20 -74"
stroke="#E5C39C"
stroke-width="5"
/>
</defs>
<use href="#branch" />
<use href="#branch" transform="rotate(60)" />
<use href="#branch" transform="rotate(120)" />
<use href="#branch" transform="rotate(180)" />
<use href="#branch" transform="rotate(240)" />
<use href="#branch" transform="rotate(300)" />
</svg>
El elemento <path> usa comandos como M (mover a) y L (línea a) para dibujar la rama. El atributo path en SVG define la forma mediante una serie de comandos y coordenadas, permitiendo formas complejas con un solo elemento.
Dibujando un Bosque con Elementos Reutilizados
Podemos escalar y posicionar elementos reutilizados para crear escenas complejas, como un bosque. Definimos un árbol en <defs> y lo reutilizamos con diferentes posiciones y escalas.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<defs>
<g id="tree">
<polygon points="-10,0 10,0 0 -50" fill="#38755b" />
<line
x1="0"
y1="0"
x2="0"
y2="10"
stroke="#778074"
stroke-width="2"
/>
</g>
</defs>
<rect x="-100" y="-100" width="200" height="200" fill="#F1DBC3" />
<circle cx="0" cy="380" r="350" fill="#F8F4E8" />
<use href="#tree" x="-30" y="25" transform="scale(2)" />
<use href="#tree" x="-20" y="40" transform="scale(1.2)" />
<use href="#tree" x="40" y="40" />
<use href="#tree" x="50" y="30" transform="scale(1.5)" />
</svg>
La transformación scale ajusta el tamaño de los árboles, mientras que x y y controlan su posición, creando una ilusión de profundidad.
Creando un Árbol Curvo con Curvas Bézier
Las curvas Bézier permiten formas más orgánicas. La curva cuadrática (Q) usa un punto de control para definir la curvatura, ideal para un árbol estilizado.
<svg width="200" height="400" viewBox="-100 -200 200 400">
<path
d="
M 0 -80
Q 5 -75 0 -70
Q -10 -65 0 -60
Q 15 -55 0 -50
Q -20 -45 0 -40
Q 25 -35 0 -30
Q -30 -25 0 -20
Q 35 -15 0 -10
Q -40 -5 0 0
Q 45 5 0 10
Q -50 15 0 20
Q 55 25 0 30
Q -60 35 0 40
Q 65 45 0 50
Q -70 55 0 60
Q 75 65 0 70
Q -80 75 0 80
Q 85 85 0 90
Q -90 95 0 100
Q 95 105 0 110
Q -100 115 0 120
L 0 140
L 20 140
L -20 140"
fill="none"
stroke="#0C5C4C"
stroke-width="5"
/>
</svg>
Cada comando Q define un segmento curvo, con un punto de control que aleja la curva del centro, creando un efecto ondulante.
Dibujando una Campana con Curvas Bézier Cúbicas
Las curvas Bézier cúbicas (C) ofrecen mayor control al usar dos puntos de control por segmento, permitiendo transiciones suaves. Una campana puede combinar líneas rectas, curvas cuadráticas y cúbicas.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<g stroke="black" stroke-width="2">
<circle cx="0" cy="-45" r="7" fill="#4F6D7A" />
<circle cx="0" cy="50" r="10" fill="#F79257" />
<path
d="
M -50 40
L -50 50
L 50 50
L 50 40
Q 40 40 40 10
C 40 -60 -40 -60 -40 10
Q -40 40 -50 40"
fill="#FDEA96"
/>
</g>
</svg>
La curva cúbica (C) asegura una transición suave en la parte superior de la campana, mientras que las curvas cuadráticas (Q) forman los lados.
Escribiendo Texto a lo Largo de un Camino SVG
El elemento <textPath> permite que el texto siga un camino definido, como un arco circular, útil para efectos decorativos.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<defs>
<path id="text-arc" d="M 0, 50 A 50 50 0 1 1 1,50" />
</defs>
<text
fill="#0C5C4C"
font-family="Tahoma"
font-size="0.77em"
font-weight="bold"
>
<textPath href="#text-arc">
¡Felices Fiestas! ¡Felices Fiestas! ¡Felices Fiestas!
</textPath>
</text>
</svg>
El camino definido en <defs> con el comando A (arco) crea una trayectoria circular que el texto sigue, ideal para logotipos o diseños circulares.
Animando SVG con CSS
Podemos animar elementos SVG usando CSS, aplicando transformaciones como translate. Un ejemplo es un efecto de nieve cayendo en el bosque.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<defs>
<g id="tree">
<polygon points="-10,0 10,0 0 -50" fill="#38755b" />
<line x2="0" y2="10" stroke="#778074" stroke-width="2" />
</g>
<circle id="big" cx="0" cy="0" r="5" fill="white" />
<circle id="small" cx="0" cy="0" r="3" fill="white" />
</defs>
<rect x="-100" y="-100" width="200" height="200" fill="#F1DBC3" />
<circle cx="0" cy="380" r="350" fill="#F8F4E8" />
<use href="#tree" x="-30" y="25" transform="scale(2)" />
<use href="#tree" x="-20" y="40" transform="scale(1.2)" />
<use href="#tree" x="40" y="40" />
<use href="#tree" x="50" y="30" transform="scale(1.5)" />
<use href="#big" x="0" y="0" class="flake fast" />
<use href="#big" x="-50" y="-20" class="flake fast opaque" />
<use href="#small" x="10" y="-50" class="flake slow" />
</svg>
.flake {
animation-name: snowing;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
.flake.opaque {
opacity: 0.7;
}
.flake.slow {
animation-duration: 5s;
}
.flake.fast {
animation-duration: 3s;
}
@keyframes snowing {
from {
transform: translate(0, -100px);
}
to {
transform: translate(0, 100px);
}
}
La animación CSS mueve los copos de nieve hacia abajo, con diferentes velocidades y opacidades para un efecto realista.
Creando un Reloj con SVG y JavaScript
SVG se integra fácilmente con JavaScript para crear elementos interactivos, como un reloj que muestra la hora actual. Manipulamos los atributos de transformación para rotar las manecillas.
<svg width="200" height="200" viewBox="-100 -100 200 200">
<rect x="-100" y="-100" width="200" height="200" fill="#CD803D" />
<circle r="55" stroke="#FCCE7B" stroke-width="10" fill="white" />
<circle
r="45"
stroke="#B6705F"
stroke-width="6"
stroke-dasharray="6 17.56194490192345"
stroke-dashoffset="3"
fill="none"
/>
<g stroke="#5f4c6c" stroke-linecap="round">
<line id="hours" y2="-20" stroke-width="8" />
<line id="minutes" y2="-35" stroke-width="6" />
</g>
</svg>
window.addEventListener("DOMContentLoaded", () => {
const hoursElement = document.getElementById("hours");
const minutesElement = document.getElementById("minutes");
const hour = new Date().getHours() % 12;
const minute = new Date().getMinutes();
hoursElement.setAttribute("transform", `rotate(${(360 / 12) * hour})`);
minutesElement.setAttribute("transform", `rotate(${(360 / 60) * minute})`);
});
El código JavaScript calcula la rotación de las manecillas según la hora actual, actualizando el atributo transform.
Creando Diagramas Dinámicos con SVG y React
SVG es compatible con frameworks como React, permitiendo generar diagramas basados en datos. Un componente React puede crear un diagrama de columnas y una línea sinusoidal.
function Diagram() {
const dataPoints = [3, 4, 7, 5, 3, 6];
const sineWave = Array.from({ length: 115 })
.map((item, index) => `${index - 55},${Math.sin(index / 20) * 20 + 10}`)
.join(" ");
return (
<svg width="200" height="200" viewBox="-100 -100 200 200">
{dataPoints.map((dataPoint, index) => (
<rect
key={index}
x={index * 20 - 55}
y={50 - dataPoint * 10}
width="15"
height={dataPoint * 10}
fill="#CD803D"
/>
))}
<polyline
points={sineWave}
fill="none"
stroke="black"
stroke-width="5"
/>
</svg>
);
}
Este componente genera rectángulos para un diagrama de columnas y una polilínea para una onda sinusoidal, mostrando cómo SVG puede visualizar datos dinámicos.
Conclusiones
SVG ofrece a los desarrolladores web una herramienta versátil para crear gráficos interactivos y escalables directamente en el código. Desde formas básicas como círculos y polígonos hasta animaciones y diagramas dinámicos, SVG permite personalizar elementos con CSS y JavaScript, integrándose perfectamente con frameworks como React. Los ejemplos presentados, desde ornamentos navideños hasta relojes y diagramas, demuestran su flexibilidad para proyectos de programación web. Al dominar SVG, puedes reducir la dependencia de imágenes externas, mejorar el rendimiento y crear experiencias visuales únicas, todo desde tu editor de código favorito.