Rueda cromática

facebook-svg gplus-svg twitter-svg

Esta es una continuación de Dibujar un sector circular

Si sabemos dibujar un sector circular lo demás es muy fácil. Para construir la rueda cromática necesitamos 360 sectores circulares de 1º cada, cuyo relleno fill  tiene como valor un color HSL. Para dibujar cada sector circular utilizamos el elemento <path>.

Que son los colores HSL

Empezamos calculando algunas variables necesarias. Queremos poder modificar el tamaño del lienzo SVG y del gráfico, sin tener que volver a calcular el centro del circulo. Para esto obtenemos una referencia al lienzo SVG y la almacenamos en una variable ( var lienzoSVG ). Ahora podemos calcular la anchura y la altura del lienzo SVG, y todo lo demás.


var lienzoSVG = document.getElementById("lienzoSVG");
// encuentra la anchura del lienzo SVG
var w = lienzoSVG.clientWidth;
// encuentra la altura del lienzo SVG
var h = lienzoSVG.clientHeight;
// calcula las coordenadas del centro
var cx = w/2,cy = h/2;
// calcula radio del grafico
var r = (w/2) -10;

A continuación definimos algunas funciones necesarias: la función dGajo que calcula el valor del parámetro d para <path> y la función nuevoGajo crea un nuevo elemento <path> ( el nuevo sector circular )  y lo adjunta al lienzo SVG.

La función dGajo calcula el valor del parametro d para path:

function dGajo(ap,af){
       var Xap = cx+r * Math.cos((Math.PI / 180) * ap);
       var Yap = cy+r * Math.sin((Math.PI / 180) * ap);
				
       var Xaf = cx+r * Math.cos((Math.PI / 180) * af);
       var Yaf = cy+r * Math.sin((Math.PI / 180) * af);
				
       var parametro_d = 
                   "M" + cx + ", " + cy+
                   " L"+Xap+","+Yap+ 
                   " A"+r+","+r+" 0 0, 1 "+" "+Xaf+","+Yaf+ 
                   " z";
       return parametro_d;
	 }

La función nuevoGajo crea un nuevo elemento path y lo adjunta al lienzo SVG:

function nuevoGajo(ap,af, color){
var nuevoGajo=document.createElementNS("http:\/\/www.w3.org/2000/svg","path");
nuevoGajo.setAttributeNS(null,"d", dGajo(ap,af));
nuevoGajo.setAttributeNS(null,"fill",  color); 
nuevoGajo.setAttributeNS(null,"stroke",  color);
nuevoGajo.setAttributeNS(null,"id",  "gajo"+i); 
lienzoSVG.appendChild(nuevoGajo);
}

NOTA: para entender la función dGajo y nuevoGajo por favor lea este articulo: Dibujar un sector circular

Ahora viene lo interesante. Queremos construir 360 sectores circulares de 1º cada. El relleno fill de estos sectores circulares es un color HSL.

Hablemos un poco de colores HSL

La sintaxis para los colores HSL es: hsl( hue, saturation%, lightness% )

<path fill = "hsl(180,100%,50%)" . . .

El primer parámetro hue ( hsl(180,100%,50%) ) puede tomar valores de 0 a 359 ya que se trata de un ángulo en la rueda de los colores: un azul en este caso.
Podemos conseguir varios tonos de este color, modificando la saturación ( hsl(180,100%,50%) ) o podemos crear colores más claros o más oscuros modificando la luminosidad ( ( hsl(180,100%,50%) ), pero lo que realmente nos interesa para construir una rueda cromática es el primer parámetro: hue.
Si queremos construir una rueda cromática, con cada grado, con cada nuevo sector circular, el valor del componente hue del color se ve incrementado en un punto. O sea tenemos que escribir un bucle for que calcula el color HSL y dibuja el nuevo sector circular.


for( var i = 0; i < 360; i++){
  var ap = i; // el ángulo inicial
  var af = i+1; // el ángulo final
  var color="hsl("+i+",100%,50%)";
  // dibuja un nuevo sector circular
  nuevoGajo(ap,af,color);
}

Al final añadimos unas cuantas líneas más de código, para que al hacer clic en uno de los sectores circulares que componen la rueda de los colores podamos recuperar el código hsl del color.


// al hacer click en un punto de la rueda obtenemos el color   
var gajos = lienzoSVG.getElementsByTagName("path");
for(var i=0; i < gajos.length; i++){
(function () { //---------------------------------------------------
var elId = gajos[i].id;
var elPath = lienzoSVG.getElementById(elId);
elPath.addEventListener("click", function(){ alert(elPath.getAttribute('fill'))})
})()
}

Todo junto




// establecemos el valor de algunas variables necesarias
var lienzoSVG = document.getElementById("lienzoSVG");
var w = lienzoSVG.clientWidth; console.log(w); // la anchura del lienzo
var h = lienzoSVG.clientHeight; console.log(h); // la altura del lienzo
var cx = w/2,cy = h/2; // las coordenadas del centro
var r = (w/2) -10; // el radio
  
// la función dGajo calcula el valor del parametro d para path
function dGajo(ap,af){
       var Xap = cx+r * Math.cos((Math.PI / 180) * ap);
       var Yap = cy+r * Math.sin((Math.PI / 180) * ap);
				
       var Xaf = cx+r * Math.cos((Math.PI / 180) * af);
       var Yaf = cy+r * Math.sin((Math.PI / 180) * af);
				
       var parametro_d = 
                   "M" + cx + ", " + cy+
                   " L"+Xap+","+Yap+ 
                   " A"+r+","+r+" 0 0, 1 "+" "+Xaf+","+Yaf+ 
                   " z";
       return parametro_d;
	 }
   
// la función nuevoGajo crea un nuevo elemento path	y lo adjunta al lienzo SVG 
function nuevoGajo(ap,af, color){
var nuevoGajo=document.createElementNS("http:\/\/www.w3.org/2000/svg","path");
nuevoGajo.setAttributeNS(null,"d", dGajo(ap,af));
nuevoGajo.setAttributeNS(null,"fill",  color); 
nuevoGajo.setAttributeNS(null,"stroke",  color);
nuevoGajo.setAttributeNS(null,"id",  "gajo"+i); 
lienzoSVG.appendChild(nuevoGajo);
} 

// el bucle FOR que genera todos los arcos circulares necesarios
for( var i = 0; i < 360; i++){
var ap = i;// el ángulo inicial
var af = i+1;// el ángulo final
var color="hsl("+i+",100%,50%)";	
// dibuja un nuevo sector circular.	
nuevoGajo(ap,af,color);
}


// al hacer click en un punto de la rueda obtenemos el color   
var gajos = lienzoSVG.getElementsByTagName("path");
for(var i=0; i < gajos.length; i++){
(function () { //---------------------------------------------------
var elId = gajos[i].id;
var elPath = lienzoSVG.getElementById(elId);
elPath.addEventListener("click", function(){ alert(elPath.getAttribute('fill'))})
})()
}