ขนาดสูงสุดขององค์ประกอบ <canvas>


112

ฉันกำลังทำงานกับองค์ประกอบผ้าใบที่มีความสูง600ถึง1000พิกเซลและมีความกว้างหลายสิบหรือหลายแสนพิกเซล อย่างไรก็ตามหลังจากจำนวนพิกเซลที่กำหนด (ไม่ทราบแน่ชัด) ผืนผ้าใบจะไม่แสดงรูปร่างที่ฉันวาดด้วย JS อีกต่อไป

มีใครรู้บ้างว่ามีขีด จำกัด ?

ทดสอบทั้งใน Chrome 12 และ Firefox 4


2
@ Šime He said tens OR hundreds of thousands...
Tadeck

6
ฉันก็ประสบกับสิ่งนี้เช่นกัน ฉันมีผืนผ้าใบ 8000x8000 ซึ่งใช้งานได้ดี แต่เมื่อฉันทำให้ใหญ่ขึ้นเนื้อหาจะหายไปและมันก็ไม่ได้วาด ขนาดที่ไม่สามารถใช้งานได้นั้นลดลงมากบน iPad ของฉัน ฉันสงสัยว่ามันเป็นข้อ จำกัด ของหน่วยความจำบางประเภท
Joshua

28
มันแปลกเมื่อคุณพบความคิดเห็นของตัวเองเมื่อ 2 ปีก่อนและคุณยังคงต้องเผชิญกับปัญหายี้เดียวกัน
Joshua

4
@ โจชัวและอีกหนึ่งปีต่อมา!
Eugene Yu

1
คำถามคือฉันจะตรวจจับข้อผิดพลาดเหล่านี้ได้อย่างไรหรือคำเตือนที่ดีกว่านี้คืออะไร ฉันตรวจไม่พบฮาร์ดแวร์ของอุปกรณ์ดังนั้นฉันจึงต้องตอบสนองต่อข้อผิดพลาด
br4nnigan

คำตอบ:


115

อัปเดตเมื่อ 13 ตุลาคม 2557

เบราว์เซอร์ที่ทดสอบทั้งหมดมีขีดจำกัดความสูง / ความกว้างขององค์ประกอบผ้าใบ แต่เบราว์เซอร์จำนวนมากยัง จำกัด พื้นที่ทั้งหมดขององค์ประกอบผ้าใบ ขีด จำกัด ของเบราว์เซอร์ที่ฉันสามารถทดสอบได้มีดังต่อไปนี้:

โครเมียม:

ความสูง / ความกว้างสูงสุด: 32,767 พิกเซล
พื้นที่สูงสุด: 268,435,456 พิกเซล (เช่น 16,384 x 16,384)

Firefox:

ความสูง / ความกว้างสูงสุด: 32,767 พิกเซล
พื้นที่สูงสุด: 472,907,776 พิกเซล (เช่น 22,528 x 20,992)

IE:

ความสูง / ความกว้างสูงสุด: 8,192 พิกเซล
พื้นที่สูงสุด: N / A

IE มือถือ:

ความสูง / ความกว้างสูงสุด: 4,096 พิกเซล
พื้นที่สูงสุด: N / A

อื่น ๆ :

ฉันไม่สามารถทดสอบเบราว์เซอร์อื่นได้ในขณะนี้ ดูคำตอบอื่น ๆ ในหน้านี้สำหรับขีด จำกัด เพิ่มเติม


ความยาว / ความกว้าง / พื้นที่สูงสุดในเบราว์เซอร์ส่วนใหญ่ทำให้ผ้าใบใช้ไม่ได้ (จะละเว้นคำสั่งวาดใด ๆ แม้ในพื้นที่ที่ใช้งานได้) IE และ IE Mobile จะให้เกียรติคำสั่งวาดทั้งหมดภายในพื้นที่ที่ใช้งานได้


3
ดังนั้นคำถามที่เกี่ยวข้อง ... เราจะแก้ไขข้อ จำกัด ได้อย่างไรหากพวกเขาต้องการผืนผ้าใบที่มีขนาดใหญ่กว่าค่าสูงสุดที่อนุญาต
aroth

2
@aroth ฉันลงเอยด้วยการเขียน wrapper รอบ ๆ canvas API ที่ใช้<canvas>องค์ประกอบที่ซ้อนกันหลายรายการและใช้คำแนะนำการวาดกับบริบทที่เหมาะสมโดยอัตโนมัติ
Brandon Gano

1
ฟังดูมีประโยชน์มาก อย่าคิดว่ามันอยู่ใน github?
aroth

5
Safari (เวอร์ชันที่ไม่ใช่ iOS) ใช้ 32K เหมือน Chrome Firefox นอกจากนี้หากคุณต้องการลองสร้างรหัสเสื้อคลุมนั้นใหม่ฉันเริ่มเวอร์ชันโอเพ่นซอร์สของตัวเองด้วยขีด จำกัด 8K ของ IE: github.com/adam-roth/wrapped-canvas
aroth

7
iOS 9.3.1 Safari บน iPhone 6 Plus ถูก จำกัด ไว้ที่ 16777216 พิกเซล (เช่น 4096 x 4096) ฉันสงสัยว่านี่เป็นหมายเลขทั่วไปในอุปกรณ์ iOS รุ่นใหม่
matb33

16

ฉันพบข้อผิดพลาดของหน่วยความจำบน Firefox ที่มีความสูงผ้าใบมากกว่า 8000 ดูเหมือนว่า chrome จะจัดการได้สูงกว่ามากอย่างน้อยก็ถึง 32000

แก้ไข: หลังจากทำการทดสอบเพิ่มเติมฉันพบข้อผิดพลาดแปลก ๆ กับ Firefox 16.0.2

ขั้นแรกดูเหมือนว่าฉันจะได้รับพฤติกรรมที่แตกต่างจากในผืนผ้าใบในหน่วยความจำ (สร้างในจาวาสคริปต์) ซึ่งตรงข้ามกับผืนผ้าใบที่ประกาศ html

ประการที่สองหากคุณไม่มีแท็ก html และชุดอักขระเมตาที่เหมาะสมผืนผ้าใบอาจถูก จำกัด ไว้ที่ 8196 มิฉะนั้นคุณสามารถเพิ่มได้ถึง 32767

ประการที่สามหากคุณได้รับบริบท 2d ของผืนผ้าใบแล้วเปลี่ยนขนาดผ้าใบคุณอาจถูก จำกัด ไว้ที่ 8196 เช่นกัน เพียงตั้งค่าขนาดแคนวาสก่อนที่จะคว้าบริบท 2d จะช่วยให้คุณมีได้ถึง 32767 โดยไม่ได้รับข้อผิดพลาดของหน่วยความจำ

ฉันไม่สามารถรับข้อผิดพลาดของหน่วยความจำได้อย่างสม่ำเสมอบางครั้งอาจเกิดขึ้นในการโหลดหน้าแรกเท่านั้นจากนั้นการเปลี่ยนแปลงความสูงที่ตามมาจะทำงาน นี้เป็นไฟล์ html ที่ผมได้ทดสอบกับhttp://pastebin.com/zK8nZxdE


4
"ประการที่สองหากคุณไม่มีแท็ก html และชุดอักขระเมตาที่เหมาะสมผืนผ้าใบอาจถูก จำกัด ไว้ที่ 8196 มิฉะนั้นคุณสามารถสูงถึง 32767" - คุณหมายถึงอะไรโดยแท็ก html และชุดอักขระเมตาที่นี่
Jack Aidley

แน่นอนคุณหมายถึง 8192 (2 ^ 13)? 8196 เป็นตัวเลขแปลก ๆ
jamesdlin

14

ขนาดผ้าใบสูงสุดของ iOS (กว้าง x สูง):

 iPod Touch 16GB = 1448x1448
 iPad Mini       = 2290x2289
 iPhone 3        = 1448x1448
 iPhone 5        = 2290x2289

ทดสอบเมื่อเดือนมีนาคม 2557


ค่าเหล่านี้เป็นค่าตามอำเภอใจ โปรดดูโพสต์ของฉันด้านล่างซึ่งอ้างอิงถึงคู่มือเนื้อหาของซาฟารี
dcbarans

11

หากต้องการขยายความเกี่ยวกับคำตอบของ @FredericCharette: ตามคู่มือเนื้อหาของ Safariภายใต้หัวข้อ "Know iOS Resource Limits":

ขนาดสูงสุดสำหรับองค์ประกอบผ้าใบคือ 3 ล้านพิกเซลสำหรับอุปกรณ์ที่มี RAM น้อยกว่า 256 MB และ 5 ล้านพิกเซลสำหรับอุปกรณ์ที่มี RAM มากกว่าหรือเท่ากับ 256 MB

ดังนั้นการเปลี่ยนแปลงขนาด 5242880 (5 x 1024 x 1024) พิกเซลจะทำงานบนอุปกรณ์หน่วยความจำขนาดใหญ่มิฉะนั้นจะเป็น 3145728 พิกเซล

ตัวอย่างแคนวาส 5 ล้านพิกเซล (กว้าง x สูง):

Any total <= 5242880
--------------------
5 x 1048576 ~= 5MP   (1048576 = 1024 x 1024)
50 x 104857 ~= 5MP
500 x 10485 ~= 5MP

และอื่น ๆ ..

ผืนผ้าใบ SQUARE ที่ใหญ่ที่สุด ได้แก่ ("MiB" = 1024x1024 Bytes):

device < 256 MiB   device >= 256 MiB   iPhone 6 [not confirmed]
-----------------  -----------------   ---------------------
<= 3145728 pixels  <= 5242880 pixels   <= 16 x 1024 x 1024 p
1773 x 1773        2289 x 2289         4096 x 4096

1
เพื่อให้เจาะจงมากขึ้นขีด จำกัด ของ iPhone5 คือ 3 * 1024 * 1024 = 3145728 พิกเซล (หลังจากสงสัยว่าเหตุใดผืนผ้าใบของฉันจึงใช้ได้บน Android แต่ว่างเปล่าบน iOS ฉันพบคำตอบนี้และยังมีstackoverflow.com/questions/12556198/…และทำให้แอป Phonegap ของฉันทำงานได้)
Magnus Smith

FYI Apple ได้ลบข้อมูลขนาดเฉพาะออกจาก "Safari / Know iOS Resource Limits" ตอนนี้เป็นเพียงคำแนะนำทั่วไปเกี่ยวกับการลดแบนด์วิดท์โดยใช้รูปภาพขนาดเล็ก
ToolmakerSteve

@ matb33 รายงานในความคิดเห็นเกี่ยวกับคำถามที่ว่า iPhone 6 มีขีด จำกัด 16 * 1024 * 1024
ToolmakerSteve

11

อัปเดตสำหรับปี 2018:

เมื่อเวลาผ่านไปข้อ จำกัด ของผ้าใบก็เปลี่ยนไป น่าเสียดายที่สิ่งที่ไม่เปลี่ยนแปลงคือความจริงที่ว่าเบราว์เซอร์ยังไม่ให้ข้อมูลเกี่ยวกับข้อ จำกัด ขนาดผ้าใบผ่าน Canvas API

สำหรับผู้ที่ต้องการกำหนดขนาดแคนวาสสูงสุดของเบราว์เซอร์โดยใช้โปรแกรมหรือทดสอบการสนับสนุนสำหรับขนาดแคนวาสแบบกำหนดเองโปรดดูขนาดแคนวาส

จากเอกสาร:

องค์ประกอบผ้าใบ HTML ได้รับการสนับสนุนอย่างกว้างขวางโดยเบราว์เซอร์รุ่นใหม่และเบราว์เซอร์รุ่นเก่า แต่การรวมกันของเบราว์เซอร์และแพลตฟอร์มแต่ละชุดมีข้อ จำกัด ด้านขนาดที่ไม่ซ้ำกันซึ่งจะทำให้ผืนผ้าใบใช้ไม่ได้เมื่อมีขนาดเกิน น่าเสียดายที่เบราว์เซอร์ไม่มีวิธีระบุข้อ จำกัด ของพวกเขาและไม่ได้ให้ข้อเสนอแนะใด ๆ หลังจากสร้างผ้าใบที่ใช้ไม่ได้แล้ว ทำให้การทำงานกับองค์ประกอบผ้าใบขนาดใหญ่เป็นเรื่องท้าทายโดยเฉพาะอย่างยิ่งสำหรับแอปพลิเคชันที่รองรับเบราว์เซอร์และแพลตฟอร์มต่างๆ

ไมโครไลบรารีนี้ให้พื้นที่สูงสุดความสูงและความกว้างขององค์ประกอบผ้าใบ HTML ที่เบราว์เซอร์สนับสนุนตลอดจนความสามารถในการทดสอบขนาดผ้าใบที่กำหนดเอง ด้วยการรวบรวมข้อมูลนี้ก่อนที่จะสร้างองค์ประกอบผ้าใบใหม่แอปพลิเคชันจะสามารถตั้งค่าขนาดพื้นที่ทำงานได้อย่างน่าเชื่อถือภายในข้อ จำกัด ขนาดของแต่ละเบราว์เซอร์ / แพลตฟอร์ม

ลิงก์สาธิตและผลการทดสอบมีอยู่ในREADMEตลอดจนส่วนปัญหาที่ทราบซึ่งเกี่ยวข้องกับการพิจารณาประสิทธิภาพและเครื่องเสมือน

การเปิดเผยข้อมูลทั้งหมดฉันเป็นผู้เขียนห้องสมุด ฉันสร้างมันในปี 2014 และเพิ่งกลับมาดูโค้ดสำหรับโปรเจ็กต์ที่เกี่ยวข้องกับแคนวาสใหม่ ฉันรู้สึกประหลาดใจที่พบว่าไม่มีเครื่องมือสำหรับตรวจจับข้อ จำกัด ขนาดผ้าใบในปี 2018 ดังนั้นฉันจึงอัปเดตโค้ดปล่อยออกมาและหวังว่าจะช่วยให้ผู้อื่นพบปัญหาที่คล้ายกัน


8

ตามข้อกำหนด w3อินเทอร์เฟซความกว้าง / ความสูงเป็นแบบยาวที่ไม่ได้ลงนาม - ดังนั้น 0 ถึง 4,294,967,295 (ถ้าฉันจำตัวเลขนั้นถูกต้อง - อาจไม่เพียงพอ)

แก้ไข: แปลกมันบอกว่าไม่ได้ลงนามยาว แต่การทดสอบแสดงให้เห็นเพียงค่ายาวปกติเป็นค่าสูงสุด: 2147483647 Jsfiddle - 47 ใช้งานได้ แต่สูงสุด 48 และจะเปลี่ยนกลับเป็นค่าเริ่มต้น


อืมมม น่าสนใจ แต่ฉันไม่ถึง 1.5 พันล้าน
ร้ายแรง

แก้ไขแล้วขออภัย (นั่นคือสิ่งที่ฉันได้รับจากการไม่ได้ทดสอบก่อน) - เพิ่ม jsfiddle เพื่อแสดง
WSkid

7

แม้ว่าผ้าใบจะช่วยให้คุณสามารถใส่ height = 2147483647 ได้ แต่เมื่อคุณเริ่มวาดก็จะไม่มีอะไรเกิดขึ้น

การวาดจะเกิดขึ้นก็ต่อเมื่อฉันนำความสูงกลับมาที่ 32767


7

iOS มีขีด จำกัด ที่แตกต่างกัน

การใช้โปรแกรมจำลอง iOS 7 ฉันสามารถแสดงให้เห็นว่าขีด จำกัด คือ 5MB ดังนี้:

var canvas = document.createElement('canvas');
canvas.width = 1024 * 5;
canvas.height = 1024;
alert(canvas.toDataURL('image/jpeg').length);
// prints "110087" - the expected length of the dataURL

แต่ถ้าฉันเขยิบขนาดผ้าใบขึ้นด้วยพิกเซลแถวเดียว:

var canvas = document.createElement('canvas');
canvas.width = 1024 * 5;
canvas.height = 1025;
alert(canvas.toDataURL('image/jpeg'));
// prints "data:," - a broken dataURL

2
คุณไม่ควรใช้ข้อมูลดังกล่าวบนโปรแกรมจำลอง iOS
Zoltán

5

บนพีซี -
ฉันไม่คิดว่าจะมีข้อ จำกัด แต่ใช่คุณสามารถออกจากข้อยกเว้นของหน่วยความจำได้

บนอุปกรณ์มือถือ -
นี่คือข้อ จำกัด สำหรับผ้าใบสำหรับอุปกรณ์มือถือ: -

ขนาดสูงสุดสำหรับองค์ประกอบผ้าใบคือ 3 ล้านพิกเซลสำหรับอุปกรณ์ที่มี RAM น้อยกว่า 256 MB และ 5 ล้านพิกเซลสำหรับอุปกรณ์ที่มี RAM มากกว่าหรือเท่ากับ 256 MB

ตัวอย่างเช่นหากคุณต้องการรองรับฮาร์ดแวร์รุ่นเก่าของ Apple ขนาดผ้าใบของคุณต้องไม่เกิน 2048 × 1464

หวังว่าแหล่งข้อมูลเหล่านี้จะช่วยดึงคุณออกมา


3

ข้อ จำกัด สำหรับ Safari (ทุกแพลตฟอร์ม) ต่ำกว่ามาก

ข้อ จำกัด iOS / Safari ที่ทราบ

ตัวอย่างเช่นฉันมีบัฟเฟอร์ผ้าใบขนาด 6400x6400px พร้อมข้อมูลที่ดึงมา ด้วยการติดตาม / ส่งออกเนื้อหาและจากการทดสอบบนเบราว์เซอร์อื่นฉันก็พบว่าทุกอย่างเรียบร้อยดี แต่ใน Safari มันจะข้ามการวาดบัฟเฟอร์เฉพาะนี้ไปยังบริบทหลักของฉัน


yeep! Safari ข้ามการวาดผืนผ้าใบของคุณเนื่องจากคุณใช้ผืนผ้าใบที่ใหญ่กว่าตามที่ "อนุญาต" ดูขนาดสูงสุดที่ฉันโพสต์ไว้ด้านบน! นั่นคือสูงสุด ผ้าใบบนซาฟารี / อุปกรณ์นี้
Dado

ขนาดของคุณค่อนข้างเป็นไปตามอำเภอใจใช่หรือไม่? คุณมีเอกสารประกอบหรือไม่? ขั้นตอนการทดสอบของคุณคืออะไร?
NodeNodeNode

3

ฉันพยายามหาขีด จำกัด โดยใช้โปรแกรม: การตั้งค่าขนาดแคนวาสเริ่มจาก 35000 ลดลง 100 จนกว่าจะพบขนาดที่ถูกต้อง ในทุกขั้นตอนการเขียนพิกเซลด้านขวาล่างแล้วอ่าน ใช้งานได้ - ด้วยความระมัดระวัง

ความเร็วเป็นที่ยอมรับได้หากตั้งค่าความกว้างหรือความสูงเป็นค่าต่ำ (เช่น 10-200) ด้วยวิธีนี้: get_max_canvas_size('height', 20)ด้วยวิธีนี้:

แต่ถ้าเรียกโดยไม่มีความกว้างหรือความสูงเช่นget_max_canvas_size()ผืนผ้าใบที่สร้างขึ้นจะมีขนาดใหญ่มากจนการอ่านสีพิกเซลเดียวจะช้ามากและใน IE ทำให้เกิดอาการค้างอย่างรุนแรง

หากการทดสอบเช่นนี้สามารถทำได้ในบางครั้งโดยไม่ต้องอ่านค่าพิกเซลความเร็วจะเป็นที่ยอมรับได้

แน่นอนว่าวิธีที่ง่ายที่สุดในการตรวจจับขนาดสูงสุดก็คือวิธีดั้งเดิมในการค้นหาความกว้างและความสูงสูงสุด แต่แคนวาสคือ 'มาตรฐานชีวิต' ดังนั้นอาจจะมาสักวันหนึ่ง

http://jsfiddle.net/timo2012/tcg6363r/2/ (โปรดทราบ! เบราว์เซอร์ของคุณอาจค้าง!)

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;
  }
}

2
สิ่งนี้จะได้รับการปรับให้เหมาะสมอย่างมากโดยใช้en.wikipedia.org/wiki/Exponential_search
Brendan Annable

1
มันบ้าจริงๆที่ความล้มเหลวของการสร้างผืนผ้าใบขนาดใหญ่นี้จะเงียบเพื่อให้มีวิธีการตรวจสอบไม่ ... ไม่ได้เลวร้ายโดยวิธีใด ๆ ในส่วนของคุณมันเป็นเพียงสิ่งที่บ้าสำหรับเบราว์เซอร์ในฤดูใบไม้ผลิกับเรา
โคลิน D

@ColinD ฉันเห็นด้วย มันคงเป็นเพียงข้อมูลเล็ก ๆ น้อย ๆ จากที่ไหนสักแห่ง มันจะ. และควร
Timo Kähkönen

3

เมื่อคุณใช้ภาพวาด WebGL เบราว์เซอร์ (รวมถึงเดสก์ท็อป) จะกำหนดขีด จำกัด เพิ่มเติมเกี่ยวกับขนาดของบัฟเฟอร์ที่อยู่เบื้องหลัง แม้ว่าผืนผ้าใบของคุณจะมีขนาดใหญ่เช่น 16,000x16,000 เบราว์เซอร์ส่วนใหญ่จะแสดงภาพที่เล็กลง (สมมติว่า 4096x4096) และขยายขนาดขึ้น ที่อาจทำให้เกิดพิกเซลที่น่าเกลียดเป็นต้น

ฉันได้เขียนโค้ดบางอย่างเพื่อกำหนดขนาดสูงสุดนั้นโดยใช้การค้นหาแบบเอ็กซ์โปเนนเชียลหากมีใครต้องการ determineMaxCanvasSize()เป็นฟังก์ชันที่คุณสนใจ

function makeGLCanvas()
{
    // Get A WebGL context
    var canvas = document.createElement('canvas');
    var contextNames = ["webgl", "experimental-webgl"];
    var gl = null;
    for (var i = 0; i < contextNames.length; ++i)
    {
        try
        {
            gl = canvas.getContext(contextNames[i], {
                // Used so that the buffer contains valid information, and bytes can
                // be retrieved from it. Otherwise, WebGL will switch to the back buffer
                preserveDrawingBuffer: true
            });
        }
        catch(e) {}
        if (gl != null)
        {
            break;
        }
    }
    if (gl == null)
    {
        alert("WebGL not supported.\nGlobus won't work\nTry using browsers such as Mozilla " +
            "Firefox, Google Chrome or Opera");
        // TODO: Expecting that the canvas will be collected. If that is not the case, it will
        // need to be destroyed somehow.
        return;
    }

    return [canvas, gl];
}

// From Wikipedia
function gcd(a,b) {
    a = Math.abs(a);
    b = Math.abs(b);
    if (b > a) {var temp = a; a = b; b = temp;}
    while (true) {
        if (b == 0) return a;
        a %= b;
        if (a == 0) return b;
        b %= a;
    }
}

function isGlContextFillingTheCanvas(gl) {
    return gl.canvas.width == gl.drawingBufferWidth && gl.canvas.height == gl.drawingBufferHeight;
}

// (See issue #2) All browsers reduce the size of the WebGL draw buffer for large canvases 
// (usually over 4096px in width or height). This function uses a varian of binary search to
// find the maximum size for a canvas given the provided x to y size ratio.
//
// To produce exact results, this function expects an integer ratio. The ratio will be equal to:
// xRatio/yRatio.
function determineMaxCanvasSize(xRatio, yRatio) {
    // This function works experimentally, by creating an actual canvas and finding the maximum
    // value, the browser allows.
    [canvas, gl] = makeGLCanvas();

    // Reduce the ratio to minimum
    gcdOfRatios = gcd(xRatio, yRatio);
    [xRatio, yRatio] = [xRatio/gcdOfRatios, yRatio/gcdOfRatios];

    // if the browser cannot handle the minimum ratio, there is not much we can do
    canvas.width = xRatio;
    canvas.height = yRatio;

    if (!isGlContextFillingTheCanvas(gl)) {
        throw "The browser is unable to use WebGL canvases with the specified ratio: " + 
            xRatio + ":" + yRatio;
    }

    // First find an upper bound
    var ratioMultiple = 1;  // to maintain the exact ratio, we will keep the multiplyer that
                            // resulted in the upper bound for the canvas size
    while (isGlContextFillingTheCanvas(gl)) {
        canvas.width *= 2;
        canvas.height *= 2;
        ratioMultiple *= 2;
    }

    // Search with minVal inclusive, maxVal exclusive
    function binarySearch(minVal, maxVal) {
        if (minVal == maxVal) {
            return minVal;
        }

        middle = Math.floor((maxVal - minVal)/2) + minVal;

        canvas.width = middle * xRatio;
        canvas.height = middle * yRatio;

        if (isGlContextFillingTheCanvas(gl)) {
            return binarySearch(middle + 1, maxVal);
        } else {
            return binarySearch(minVal, middle);
        }
    }

    ratioMultiple = binarySearch(1, ratioMultiple);
    return [xRatio * ratioMultiple, yRatio * ratioMultiple];
}

นอกจากนี้ใน jsfiddle https://jsfiddle.net/1sh47wfk/1/


มีเอกสารอย่างเป็นทางการเกี่ยวกับพฤติกรรมการปรับขนาดหรือไม่?
Magnus Lind Oxlund

1
@MagnusLindOxlund ข้อมูลจากคำตอบได้รับการพิจารณาจากการทดลอง สิ่งที่ใกล้เคียงที่สุดที่ฉันพบหลังจากการค้นหาอย่างรวดเร็วคือkhronos.org/registry/webgl/specs/latest/1.0/#2.2โดยกล่าวว่า: "ข้อ จำกัด ด้านบนไม่ได้เปลี่ยนจำนวนพื้นที่ที่องค์ประกอบผ้าใบใช้บนหน้าเว็บ "เมื่อพูดถึงการ จำกัด ขนาดของบัฟเฟอร์รูปวาด ดูเหมือนว่ามาตรฐาน WebGL จะไม่ได้ลงรายละเอียดเกี่ยวกับวิธีที่องค์ประกอบผ้าใบควรจะแสดงบัฟเฟอร์รูปวาด
Michał

1

คุณสามารถแยกชิ้นส่วนและใน javascript auto ให้เพิ่มผืนผ้าใบขนาดเล็กได้มากเท่าที่จำเป็นและวาดองค์ประกอบบนผืนผ้าใบที่เหมาะสม คุณอาจยังมีหน่วยความจำไม่เพียงพอในที่สุด แต่จะช่วยให้คุณได้รับจากขีด จำกัด ผ้าใบเดียว


0

ฉันไม่รู้วิธีตรวจจับขนาดสูงสุดที่เป็นไปได้โดยไม่ต้องวนซ้ำ แต่คุณสามารถตรวจจับได้ว่าขนาดผ้าใบที่กำหนดทำงานได้หรือไม่โดยการเติมพิกเซลแล้วอ่านสีกลับออกไป หากผ้าใบไม่ได้แสดงผลสีที่คุณได้รับกลับมาจะไม่ตรงกัน W

รหัสบางส่วน:

function rgbToHex(r, g, b) {
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
}
var test_colour = '8ed6ff';
working_context.fillStyle = '#' + test_colour;
working_context.fillRect(0,0,1,1);
var colour_data = working_context.getImageData(0, 0, 1, 1).data;
var colour_hex = ("000000" + rgbToHex(colour_data[0], colour_data[1], colour_data[2])).slice(-6);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.