Patrón de cubos

facebook-svg gplus-svg twitter-svg

Dibujar un "cubo"

Observamos que para dibujar un cubo, o algo que se parezca a un cubo, podemos dibujar un hexágono dividido en 3 rombos. Cada rombo representa una de las tres caras visibles del cubo.
Por lo tanto seria aconsejable entender primero como dibujar un hexágono.
Para dibujar el cubo utilizamos 2 bucles for ( for loops ). El primer bucle ( var i ) construye cada rombo.
Utilizamos un segundo bucle for ( var j ) para construir los tres rombos que representan las tres caras visibles del cubo.

Su navegador no soporta canvas :( 

var canvas = document.getElementById("cubo");
if (canvas && canvas.getContext) {
  var ctx = canvas.getContext("2d");
  if (ctx) {
    var colors = ["#dde2f0", "#b3bedd", "#506ab1"];
    var R = 40;
    var X = 0;
    var Y = 0;
    // recalculamos la altura y la anchura del Canvas
    canvas.height = 2 * R;
    canvas.width = Math.sqrt(3) * R;
    // un angulo de 60ª en radianes
    var rad = (2 * Math.PI) / 6;
    // traslada el contexto en el centro del canvas 
    // para poder girar el contexto alrededor del centro 
    ctx.translate(canvas.width / 2, canvas.height / 2);
    //gira el contexto unos 90º
    ctx.rotate(Math.PI / 2);

    // construye el cubo
    var c = 0; // un contador
    for (var j = 3; j < 12; j += 4) {
      ctx.beginPath();
      // utilizamos el valor del contador c para determinar el color
      ctx.fillStyle = colors[c];
      for (var i = j - 3; i < j; i++) {
        x = X + R * Math.cos(rad * i);
        y = Y + R * Math.sin(rad * i);
        ctx.lineTo(x, y);
      }
      ctx.lineTo(X, Y);
      ctx.closePath();
      ctx.fill();
      c++; // incrementa con 1 el valor del contador
    }
  }
}
Su navegador no soporta canvas :(

Patrón de cubos

Para dibujar el patróns utilizaremos la misma estratégia que hemos utilizado para dibujar el panal de abejas, con la única diferencia que en lugar de dibujar el cubo una y otra vez,  lo dibujaremos una sola vez en un <canvas> flotante, que se encuentra fuera de pantalla ( offscreen canvas ) y utilizaremos la imagen generada para crear el patrón.

El <canvas> flotante

Para crear el <canvas> flotante ( bufferCanvas ) utilizamos el método createElement:

var bufferCanvas = document.createElement("canvas");

Esto crea un elemento <canvas> que se encuentra fuera de la pantalla, ya que todavía no pertenece al DOM.
A continuación definimos tanto el contexto:

bufferCanvasCtx = bufferCanvas.getContext("2d");

como la altura y la anchura del canvas:

bufferCanvasCtx.canvas.width = Math.sqrt(3)*R;
bufferCanvasCtx.canvas.height = 2*R;

Para entender las formulas utilizadas por favor vea primero como dibujar un panal de abejas. Tenga en cuenta que esta vez hemos girado el hexágono unos 90°.
Utilizaremos este canvas flotante para dibujar el cubo, un cubo como el que ya hemos dibujado más arriba, y utilizaremos esta imagen para crear el patrón.

Su navegador no soporta canvas :( 

	// el radio R del círculo circunscrito
	var R = 40;
	// la gama de colores elegida 
	var colores = ["#dde2f0", "#506ab1", "#b3bedd"];
	// las coordinadas del centro del círculo circunscrito
	var X = 0;
	var Y = 0;
	//el canvas flotante
	var bufferCanvas = document.createElement("canvas");
	bufferCanvasCtx = bufferCanvas.getContext("2d");
	bufferCanvasCtx.canvas.width = Math.sqrt(3) * R;
	bufferCanvasCtx.canvas.height = 2 * R;
	// traslada el contexto en el centro del canvas 
	// para poder girar el contexto alrededor del centro 
	bufferCanvasCtx.translate(bufferCanvas.width / 2, bufferCanvas.height / 2);
	//gira el contexto unos 90º
	bufferCanvasCtx.rotate(Math.PI / 2);
	dibujaCubo(X, Y, R, bufferCanvas);

	// el patron de cubos
	var canvas = document.getElementById("lienzo");
	if (canvas && canvas.getContext) {
	  var ctx = canvas.getContext("2d");
	  if (ctx) {
	    // calculamos el desplazamiento lateral
	    var xoffset = (Math.sqrt(3) * R) / 2;
	    var yoffset = (3 * R) / 2;
	    // para unas juntas perfectas y sin costuras recalculamos el tamaño del canvas
	    canvas.width = Math.round(canvas.width / (2 * xoffset)) * (2 * xoffset);
	    canvas.height = Math.round(canvas.height / (2 * yoffset)) * (2 * yoffset);
	    canvas.style.backgroundColor = colores[0];
	    // Utilizaremos el canvas flotante como imagen para crear el patrón.												
	    var img = bufferCanvas;

	    for (Y = 0; Y <= canvas.height + R; Y += 2 * yoffset) {
	      for (X = 0; X <= canvas.width + R; X += 2 * xoffset) {
	        //1-a fila	
	        ctx.drawImage(img, X - xoffset, Y - yoffset);
	        //2-a fila
	        ctx.drawImage(img, X, Y);
	      }
	    }
	  }
	}

	function dibujaCubo(X, Y, R, canvas) {
	  var ctx = canvas.getContext("2d");
	  // un ángulo de 60°
	  var rad = (2 * Math.PI) / 6;
	  // inicia un contador c
	  var c = 0;
	  for (var j = 3; j < 12; j += 4) {
	    ctx.beginPath();
	    ctx.fillStyle = colores[c];
	    for (var i = j - 3; i < j; i++) {
	      // construye un rombo	
	      x = X + R * Math.cos(rad * i);
	      y = Y + R * Math.sin(rad * i);
	      ctx.lineTo(x, y);
	    }
	    ctx.lineTo(X, Y);
	    ctx.closePath();
	    ctx.fill();
	    // incrementa con 1 el valor del contador c
	    c++;
	  }
	}
Su navegador no soporta canvas :(

Para recuperar la imagen utilice toDataURL
Nota: Firefox nos permite abrir y guardar la imagen generada haciendo clic con el botón derecho del ratón, y escogiendo la opción deseada.