Patrón de cubos
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.
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
}
}
}
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.
// 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++;
}
}
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.