La verdad es que la evolución de la web y sus estándares es apasionante. Si, muchas veces nos hemos tirado de los pelos por incompatibilidades, y aún queda para que todos esos problemas queden atrás... pero también podemos frotarnos las manos con las posibilidades que ya podemos ver y tocar.
Uno de los elementos que me lleva tiempo interesando es SVG. Siempre me ha gustado la idea de expresar gráficos como XML me parece elegante, legible y portable. Y gracias a que son documentos XML se pueden adaptar al estílo de la página utilizando CSS.
A los que siempre hemos huido de flash, por una razón y otra, ahora podemos sentir el potencial de este (bueno, al menos parte) utilizando SVG. Ya que no solo podemos describir elementos con XML, también podemos modificarlos utilizando JavaScript.
Para ir aprendiendo he dedicado un par de tardes a hacer este indicador que podría encajar en cualquier panel de control. Puedes descargarlo desde aquí.
1. ViewBox
El ViewBox nos indica la zona visible del dibujo. Si no declaramos un ViewBox este se adaptará a la zona en la que se esté dibujando el documento. Si por el contrario lo declaramos, el dibujo se reescalará para adaptar el ViewBox a la zona donde se esté dibujando.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<svg | |
xmlns = "http://www.w3.org/2000/svg" | |
xmlns:xlink = "http://www.w3.org/1999/xlink" | |
version = "1.1" | |
viewBox = "0 0 300 150" | |
with = "300" | |
height = "150"> | |
<!-- your code here --> | |
</svg> |
2. Definiciones (defs)
Es posible reutilizar parte del código dentro del mismo documento utilizando definiciones. Podemos pensar en las definiciones como componentes que se podrán incrustar posteriormente tantas veces como queramos.
En este dibujo se han definido dos componentes: indicator_step y needle. El primero es utilizado para dibujar las marcas que nos ayudan a leer los valores indicados por la aguja, el segundo es la aguja del indicador.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<defs> | |
<g id="indicator_step" stroke-linecap="round" stroke="black"> | |
<line x1="-145" y1="0" x2="-120" y2="0" stroke-width="1" /> | |
<line x1="-145" y1="0" x2="-135" y2="0" stroke-width="4" /> | |
</g> | |
<g id="needle" stroke-linecap="round" stroke="black" > | |
<line x1="-110" y1="0" x2="0" y2="0" stroke-width="1" /> | |
<line x1="-80" y1="0" x2="0" y2="0" stroke-width="4" /> | |
<line x1="-30" y1="0" x2="0" y2="0" stroke-width="6" /> | |
<line x1="-20" y1="0" x2="0" y2="0" stroke-width="9" /> | |
<line x1="-15" y1="0" x2="0" y2="0" stroke-width="12" /> | |
<line x1="-10" y1="0" x2="0" y2="0" stroke-width="18" /> | |
</g> | |
</defs> |
3. Dibujado
Finalmente dibujamos todos los componentes de dentro a fuera. Primero dibujamos el fondo dibidido en tres areas de diferentes colores para distinguir rápidamente la importancia del nivel indicado:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<g id="background" stroke-width="4"> | |
<path d="M150,148 H4 A148,148 0 0,1 150,2 Z" fill="lime" stroke="green" /> | |
<path d="M150,148 V2 A148,148 0 0,1 278,78 Z" fill="yellow" stroke="orange" /> | |
<path d="M150,148 L278,78 A148,148 0 0,1 296,148 Z" fill="pink" stroke="red" /> | |
</g> |
Sobre el fondo vamos a dibujar un texto para indicar de forma numérica el nivel mostrado po el indicador:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<rect x = "105" y = "55" width = "90" height = "30" | |
style = "opacity : .60; | |
fill : white; | |
stroke : black; | |
stroke-width : 2" | |
rx = "10" | |
ry = "10" /> | |
<text id = "text" x = "150" y = "80" | |
style = "fill : black; | |
stroke-width : 2; | |
font-family : sans; | |
font-size : 25; | |
font-weight : bold; | |
text-anchor : middle"> | |
0 | |
</text> |
A continuación reutilizamos la definición indicator_step para las marcas para dibujar los pasos del indicador una marca cada 15 grados:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<g id="steps" transform="translate(150, 148)"> | |
<g transform="rotate(0)"> | |
<use id="step_000" xlink:href="#indicator_step" /> | |
</g> | |
<g transform="rotate(15)"> | |
<use id="step_015" xlink:href="#indicator_step" /> | |
</g> | |
<!-- more repetitions here --> | |
<g transform="rotate(180)"> | |
<use id="step_180" xlink:href="#indicator_step" /> | |
</g> | |
</g> |
Finalmente dibujamos la aguja reutilizando la definición needle. Vemos que dentro se define una animación. Esta animcación ahora no tiene utilidaz, pero la declarración nos ayudará a mover la aguja mediante scripting de forma más sencilla:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<g id="needle" transform="translate(150, 148)"> | |
<g id="needle_rotation" transform="rotate(0)"> | |
<use xlink:href="#needle" /> | |
<animateTransform id="animation" | |
attributeType = "XML" | |
attributeName = "transform" | |
type = "rotate" | |
begin = "indefinite" | |
end = "indefinite" | |
dur = "2s" | |
calcMode = "spline" | |
keySplines = "0 .5 0 1" | |
fill = "freeze" /> | |
</g> | |
</g> |
4. Scripting
Ya tenemos el dibujo, ahora podemos manipularlo gracias a que podemos acceder a él a través del DOM y una serie de APIs extra definidas en el estándar SVG. Este script es realmente sencillo, pero nos da una idea de como realizar unas transformaciones básicas.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function setAngle(finalAngle) { | |
var initialAngle = document | |
.getElementById('needle_rotation') | |
.transform | |
.animVal | |
.getItem(0) | |
.angle; | |
var aElement = document.getElementById('animation'); | |
aElement.setAttribute('values', initialAngle + ';' + finalAngle); | |
aElement.beginElement(); | |
} | |
function start(source) { | |
function iteration() { | |
setAngle(source.next() * 180); | |
setTimeout(iteration, 2000); | |
} | |
function updateText() { | |
document.getElementById('text').textContent = Math.floor( | |
document.getElementById('needle_rotation') | |
.transform | |
.animVal | |
.getItem(0) | |
.angle); | |
setTimeout(updateText, 100); | |
} | |
iteration(); | |
updateText(); | |
} | |
start({ | |
next : function() { | |
return Math.random(); | |
} | |
}); |
No hay comentarios:
Publicar un comentario