Ho provato a capire a livello di codice il limite: impostare la dimensione della tela a partire da 35000, scendere di 100 fino a trovare una dimensione valida. In ogni passaggio scrivendo il pixel in basso a destra e poi leggendolo. Funziona con cautela.
La velocità è accettabile se la larghezza o altezza è impostata su un valore basso (ad esempio 10-200.) In questo modo: get_max_canvas_size('height', 20)
.
Ma se chiamato senza larghezza o altezza come get_max_canvas_size()
, la tela creata è così grande che la lettura del colore di un SINGOLO pixel è molto lenta e in IE causa un grave blocco.
Se questo test simile potesse essere eseguito in qualche modo senza leggere il valore dei pixel, la velocità sarebbe accettabile.
Ovviamente il modo più semplice per rilevare la dimensione massima sarebbe un modo nativo per interrogare la larghezza e l'altezza massime. Ma Canvas è "uno standard di vita", quindi potrebbe essere un giorno.
http://jsfiddle.net/timo2012/tcg6363r/2/ (Attenzione! Il tuo browser potrebbe bloccarsi!)
if (!Date.now)
{
Date.now = function now()
{
return new Date().getTime();
};
}
var t0 = Date.now();
//var size = get_max_canvas_size('width', 200);
var size = get_max_canvas_size('height', 20);
//var size = get_max_canvas_size();
var t1 = Date.now();
var c = size.canvas;
delete size.canvas;
$('body').append('time: ' + (t1 - t0) + '<br>max size:' + JSON.stringify(size) + '<br>');
//$('body').append(c);
function get_max_canvas_size(h_or_w, _size)
{
var c = document.createElement('canvas');
if (h_or_w == 'height') h = _size;
else if (h_or_w == 'width') w = _size;
else if (h_or_w && h_or_w !== 'width' && h_or_w !== 'height' || !window.CanvasRenderingContext2D)
return {
width: null,
height: null
};
var w, h;
var size = 35000;
var cnt = 0;
if (h_or_w == 'height') w = size;
else if (h_or_w == 'width') h = size;
else
{
w = size;
h = size;
}
if (!valid(w, h))
for (; size > 10; size -= 100)
{
cnt++;
if (h_or_w == 'height') w = size;
else if (h_or_w == 'width') h = size;
else
{
w = size;
h = size;
}
if (valid(w, h)) break;
}
return {
width: w,
height: h,
iterations: cnt,
canvas: c
};
function valid(w, h)
{
var t0 = Date.now();
var color, p, ctx;
c.width = w;
c.height = h;
if (c && c.getContext)
ctx = c.getContext("2d");
if (ctx)
{
ctx.fillStyle = "#ff0000";
try
{
ctx.fillRect(w - 1, h - 1, 1, 1);
p = ctx.getImageData(w - 1, h - 1, 1, 1).data;
}
catch (err)
{
console.log('err');
}
if (p)
color = p[0] + '' + p[1] + '' + p[2];
}
var t1 = Date.now();
if (color == '25500')
{
console.log(w, h, true, t1 - t0);
return true;
}
console.log(w, h, false, t1 - t0);
return false;
}
}
tens OR hundreds of thousands
...