Tôi đã cố gắng lập trình để tìm ra giới hạn: đặt kích thước canvas bắt đầu từ 35000, giảm dần 100 cho đến khi tìm thấy kích thước hợp lệ. Trong mỗi bước, viết pixel dưới cùng bên phải và sau đó đọc nó. Nó hoạt động - một cách thận trọng.
Tốc độ có thể chấp nhận nếu một trong hai chiều rộng hoặc chiều cao được thiết lập để một số giá trị thấp (ví dụ 10-200.) Theo cách này: get_max_canvas_size('height', 20)
.
Nhưng nếu được gọi mà không có chiều rộng hoặc chiều cao như trên get_max_canvas_size()
, canvas được tạo quá lớn nên việc đọc màu pixel SINGLE rất chậm và trong IE gây ra hiện tượng treo nghiêm trọng.
Nếu thử nghiệm tương tự này có thể được thực hiện bằng cách nào đó mà không cần đọc giá trị pixel, thì tốc độ có thể chấp nhận được.
Tất nhiên, cách dễ nhất để phát hiện kích thước tối đa là một số cách gốc để truy vấn chiều rộng và chiều cao tối đa. Nhưng Canvas là 'một tiêu chuẩn sống', vì vậy có thể nó sẽ đến vào một ngày nào đó.
http://jsfiddle.net/timo2012/tcg6363r/2/ (Hãy lưu ý! Trình duyệt của bạn có thể bị treo!)
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
...