Próbowałem programowo określić limit: ustawienie rozmiaru płótna zaczynając od 35000, zmniejszanie o 100, aż zostanie znaleziony prawidłowy rozmiar. Na każdym kroku zapisuj prawy dolny piksel, a następnie go odczytuj. Działa - z ostrożnością.
Prędkość jest do zaakceptowania, jeśli zarówno szerokość lub wysokość jest ustawiany na pewną wartość w niskich (na przykład 10-200). Ten sposób: get_max_canvas_size('height', 20)
.
Ale jeśli zostanie wywołany bez szerokości lub wysokości get_max_canvas_size()
, utworzone płótno jest tak duże, że odczytanie koloru POJEDYNCZEGO piksela jest bardzo powolne, aw IE powoduje poważne zawieszenie.
Gdyby ten podobny test można było przeprowadzić bez odczytywania wartości piksela, prędkość byłaby akceptowalna.
Oczywiście najłatwiejszym sposobem wykrycia maksymalnego rozmiaru byłby natywny sposób zapytania o maksymalną szerokość i wysokość. Ale płótno to „standard życia”, więc może kiedyś nadejdzie.
http://jsfiddle.net/timo2012/tcg6363r/2/ ( Uwaga ! Twoja przeglądarka może się zawiesić!)
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
...