Crear un canvas adaptativo
Tenemos que decirlo alto y claro: El <canvas>
( HTML5 ) no es un elemento que se adapte fácilmente a los diferentes tamaños de pantalla. No es "responsive". LasĀ dimensiones del <canvas>
vienen especificadas en pixeles en el HTML.
<canvas id= "Canvas1" width="250" height="220">Su navegador no soporta canvas :( </canvas>
Redimensionar el canvas con CSS
Podemos redimensionar el <canvas>
con CSS pero esto sería como una imagen redimensionada.
En el siguiente ejemplo los dos <canvas>
son iguales, con la única diferencia que el <canvas>
de la derecha está redimensionado con CSS. Al cambiar tamaño de la ventana se puede apreciar claramente que el segundo <canvas>
cambia de tamaño, pero sigue teniendo el mismo número de pixeles.
.contenedor{
box-sizing:border-box;
float:left;
width:50%;
padding:10px;
}
.lienzo{
border:1px solid #d9d9d9;
}
#lienzo1{float:right;}
#lienzo2{width:50%;float:left;}
var canvasP = document.createElement("canvas");
var ctxP = canvasP.getContext("2d");
if (ctxP) {
// creamos el patrón.
ctxP.canvas.width = 20;
ctxP.canvas.height = 20;
ctxP.rect(0, 0, 10, 10);
ctxP.rect(10, 10, 20, 20);
ctxP.fillStyle = "#d9d9d9";
ctxP.fillRect(0, 0, 10, 10);
ctxP.fillRect(10, 10, 20, 20);
}
var canvas = document.getElementsByClassName("lienzo");
var ctx;
for( var i = 0; i < canvas.length; i++){
if (canvas[i] && canvas[i].getContext) {
ctx = canvas[i].getContext("2d");
if (ctx) {console.log("Habemus context")
ctx.restore();
// aplicamos el patrón
ctx.fillStyle = ctx.createPattern(canvasP,"repeat");
ctx.fillRect(0,0, canvas[i].width, canvas[i].height);
ctx.save();
}
}
}
Redimensionar el canvas con JavaScript
En este caso queremos cambiar el tamaño del <canvas>
de manera programática, utilizando JavaScript. Para esto en el HTML no especificamos las dimensiones del lienzo.
En el CSS damos al <canvas>
una altura y una anchura de 100%, y al <div>
que lo contiene le damos width=50%
. Se trata de 50% del <article>
en este caso. Al redimensionar la ventana, el
<canvas>
también cambia de tamaño.
#div{ width:50%; height:80%; margin:0 auto;}
#canvas{border:1px solid #d9d9d9; width: 100%; height: 100%;}
Queremos dibujar un circulo en el <canvas>
y queremos que sea "responsive", que cambie de tamaño con el <canvas>
.
La idea principal
Cada vez que la ventana cambia de tamaño, JavaScript calcula las nuevas dimensiones del <canvas>
, y dibuja el circulo en base a estas dimensiones. Lo hace llamando la función inicializarCanvas()
.
setTimeout(function() {
inicializarCanvas();
addEventListener("resize", inicializarCanvas);
}, 15);
Cómo lo hace
El método getComputedStyle()
devuelve un objeto ( CSSStyleDeclaration
) con todos los estilos computados del elemento. Utilizamos este método para calcular la anchura y la altura del <canvas>
redimensionado.
var s = getComputedStyle(canvas);
var w = s.width
var h = s.height;
La anchura y la altura del <canvas>
vienen en pixeles así que tenemos que extraer el valor numérico.
var W = canvas.width = w.split('px')[0]; var H = canvas.height = h.split('px')[0];
A continuación calculamos las coordenadas del centro del circulo ( X, Y
) y el radio ( r
) utilizando la anchura ( W
) y la altura ( H
) calculadas. Utilizamos Math.floor
para deshacernos de los decimales.
X = Math.floor(W/2); Y = Math.floor(H/2); r = Math.floor(W/3);
Y finalmente dibujamos en el <canvas>
dibujarEnElCanvas(ctx);
function inicializarCanvas(){
if (canvas && canvas.getContext) {
var ctx = canvas.getContext("2d");
if (ctx) {
// calcula la anchura y la altura del canvas
var s = getComputedStyle(canvas);
var w = s.width;
var h = s.height;
// extrae el valor numerico
W = canvas.width = w.split("px")[0];
H = canvas.height = h.split("px")[0];
// calcula las coordenadas del centro y el radio
X = Math.floor(W/2);
Y = Math.floor(H/2);
r = Math.floor(W/3);
// dibuja el circulo en el canvas
dibujarEnElCanvas(ctx);
}
}
}
La función dibujarEnElCanvas()
es una función que tenemos que escribir:
function dibujarEnElCanvas(ctx){
ctx.strokeStyle = "#006400";
ctx.fillStyle = "#6ab155";
ctx.lineWidth = 5;
ctx.arc(X,Y,r,0,2*Math.PI);
ctx.fill();
ctx.stroke();
}
Ahora lo ponemos todo junto
var canvas = document.querySelector("#canvas");
var X,Y,W,H,r;
canvas.height = 250;
function inicializarCanvas(){
if (canvas && canvas.getContext) {
var ctx = canvas.getContext("2d");
if (ctx) {
var s = getComputedStyle(canvas);
var w = s.width;
var h = s.height;
W = canvas.width = w.split("px")[0];
H = canvas.height = h.split("px")[0];
X = Math.floor(W/2);
Y = Math.floor(H/2);
r = Math.floor(W/3);
dibujarEnElCanvas(ctx);
}
}
}
function dibujarEnElCanvas(ctx){
ctx.strokeStyle = "#006400";
ctx.fillStyle = "#6ab155";
ctx.lineWidth = 5;
ctx.arc(X,Y,r,0,2*Math.PI);
ctx.fill();
ctx.stroke();
}
setTimeout(function() {
inicializarCanvas();
addEventListener("resize", inicializarCanvas);
}, 15);
Al redimensionar la ventana tanto el <canvas>
como el circulo dibujado dentro cambia de tamaño. El borde queda siempre de 5px ( ctx.lineWidth = 5
) como establecido en la función dibujarEnElCanvas()
.