Canvas ยืดออกเมื่อใช้ CSS แต่ปกติด้วยคุณสมบัติ“ ความกว้าง” /“ ความสูง”


195

ฉันมี 2 ผืนผ้าใบหนึ่งใช้คุณลักษณะ HTML widthและheightขนาดมันอีกใช้ CSS:

<canvas id="compteur1" width="300" height="300" onmousedown="compteurClick(this.id);"></canvas>
<canvas id="compteur2" style="width: 300px; height: 300px;" onmousedown="compteurClick(this.id);"></canvas>

Compteur1 แสดงอย่างที่ควรจะเป็น แต่ไม่ใช่ compteur2 เนื้อหาถูกวาดโดยใช้ JavaScript บนผืนผ้าใบขนาด 300x300

ทำไมจึงมีความแตกต่างในการแสดงผล?

ข้อความแสดงแทน

คำตอบ:


216

ดูเหมือนว่าwidthและheightคุณลักษณะจะกำหนดความกว้างหรือความสูงของระบบพิกัดผ้าใบส่วนคุณสมบัติ CSS จะกำหนดขนาดของกล่องที่จะแสดง

นี่คือคำอธิบายที่http://www.whatwg.org/html#attr-canvas-width (ต้องการ JS) หรือhttp://www.whatwg.org/c#attr-canvas-width (อาจกินคอมพิวเตอร์ของคุณ) :

canvasองค์ประกอบมีสองคุณลักษณะในการควบคุมขนาดของบิตแมปขององค์ประกอบที่: และwidth heightแอตทริบิวต์เหล่านี้เมื่อระบุต้องมีค่าที่มีจำนวนเต็มไม่ใช่เชิงลบที่ถูกต้อง ต้องใช้กฎสำหรับการวิเคราะห์จำนวนเต็มที่ไม่ใช่ลบเพื่อรับค่าตัวเลข หากแอตทริบิวต์หายไปหรือหากการแยกวิเคราะห์ค่าส่งคืนข้อผิดพลาดจะต้องใช้ค่าเริ่มต้นแทน widthแอตทริบิวต์เริ่มต้นที่ 300 และheightค่าเริ่มต้นแอตทริบิวต์ 150


11
แน่นอน .. ฉันคิดเสมอว่าคุณสมบัติโดยตรงเช่น "ความกว้าง" และ "ความสูง" ถูกคัดค้านในเวอร์ชัน html ที่ผ่านมา ..
Sirber

4
โอ้เห็นได้ชัดว่ามันอธิบายได้ค่อนข้างดีในwhatwg.org/specs/web-apps/current-work/multipage/ … (ส่วน#attr-canvas-width) ปัญหาคือฉันคลิกที่ผิดwidthก่อนและไปที่#dom-canvas-widthส่วนแทน ยื่นw3.org/Bugs/Public/show_bug.cgi?id=9469เกี่ยวกับเรื่องนี้
SamB

3
การมี API ที่มีหน้าตาคล้าย ๆ กัน แต่มีความแตกต่างกันโดยพื้นฐาน (ความกว้างความสูงและความสูง) ว้าว.
เบ็นแอสตัน

1
เป็นสิ่งสำคัญที่จะต้องแยกแยะสิ่งเหล่านี้เป็นครั้งเมื่อคุณต้องการให้ระบบพิกัดภายในแตกต่างกัน (เช่นสำหรับการแสดงเรตินาหรือเกมสไตล์ 8 บิต)
Samy Bencherif

1
นี่มันช่างสับสนจริงๆ เราพยายามตั้งค่าความกว้างและความสูงใน css พาเรา 2 วันของผมดึงความเครียดเพื่อหาข้อมูลเกี่ยวกับการตีความทั้งสองที่แตกต่างกันเกี่ยวกับความกว้างและความสูง เพิ่งว้าว ...
NME New Media Entertainment

39

ในการตั้งค่าwidthและheightคุณต้องการคุณสามารถใช้

canvasObject.setAttribute('width', '475');

6
+1 el.setAttribute('width', parseInt($el.css('width')))ทำอุบายขอบคุณ
Shanimal

9
ถ้าฉันต้องการให้ผืนผ้าใบมีขนาดเท่ากัน กล่าวคือวิธีการเลียนแบบwidth: 100%;คุณสมบัติ CSS?
Maxbester

1
คำตอบที่ดี แต่อย่าลืมเพิ่ม canvasObject.setAttribute ('height', '123') ด้วย!
Tom Wells

ฉันไม่คิดว่าคุณจะต้องใช้. setAttribute () ฉันเคยใช้คุณสมบัติความกว้างและความสูง
Zorgatone

4
ธรรมดา JavaScript (โดยไม่ต้อง jQuery) เวอร์ชันใช้getComputedStylecanvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width")); : ทำซ้ำสำหรับความสูง
Ben J

25

สำหรับ<canvas>องค์ประกอบกฎ CSS สำหรับwidthและheightตั้งค่าขนาดที่แท้จริงขององค์ประกอบ Canvas ที่จะถูกดึงไปยังหน้า ในทางกลับกันคุณลักษณะ HTML ของwidthและheightกำหนดขนาดของระบบพิกัดหรือ 'กริด' ที่ Canvas API จะใช้

ตัวอย่างเช่นพิจารณาสิ่งนี้ ( jsfiddle ):

var ctx = document.getElementById('canvas1').getContext('2d');
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 30, 30);

var ctx2 = document.getElementById('canvas2').getContext('2d');
ctx2.fillStyle = "red";
ctx2.fillRect(10, 10, 30, 30);
canvas {
  border: 1px solid black;
}
<canvas id="canvas1" style="width: 50px; height: 100px;" height="50" width="100"></canvas>
<canvas id="canvas2" style="width: 100px; height: 100px;" height="50" width="100"></canvas>

ทั้งสองมีสิ่งเดียวกันกับพวกเขาเมื่อเทียบกับพิกัดภายในขององค์ประกอบผ้าใบ แต่ในผืนผ้าใบที่สองสี่เหลี่ยมสีแดงจะกว้างเป็นสองเท่าเนื่องจากผ้าใบโดยรวมกำลังถูกขยายไปทั่วพื้นที่ที่ใหญ่กว่าโดยกฎ CSS

หมายเหตุ: หากไม่ได้ระบุกฎ CSS สำหรับwidthและ / หรือheightเบราว์เซอร์จะใช้แอตทริบิวต์ HTML เพื่อกำหนดขนาดขององค์ประกอบที่ค่า 1 หน่วยของค่าเหล่านี้เท่ากับ 1px ในหน้า ถ้าแอตทริบิวต์เหล่านี้ไม่ได้ระบุไว้แล้วพวกเขาก็จะเริ่มต้นกับwidthของ300และของheight150


16

ผืนผ้าใบจะยืดถ้าคุณตั้งค่าความกว้างและความสูงใน CSS ของคุณ หากคุณต้องการจัดการมิติของผืนผ้าใบแบบไดนามิกคุณต้องใช้ JavaScript ดังนี้:

canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');

1
ที่ดี! ขอบคุณสำหรับคำตอบนี้ ฉันต้องใส่canvas.setAttributeก่อนcanvas.getContext('2d')เพื่อหลีกเลี่ยงการยืดภาพ
hhh

6

เบราว์เซอร์ใช้ความกว้างและความสูง css แต่องค์ประกอบผ้าใบปรับขนาดตามความกว้างและความสูงของผ้าใบ ใน javascript อ่านความกว้างและความสูงของ css และตั้งค่าความกว้างผ้าใบและความสูงเป็น

var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();


0

CSS ตั้งค่าความกว้างและความสูงขององค์ประกอบผ้าใบเพื่อให้มีผลกับพื้นที่พิกัดโดยปล่อยทุกอย่างที่วาดเอียง

นี่คือวิธีของฉันในการตั้งค่าความกว้างและความสูงด้วย Vanilla JavaScript

canvas.width = numberForWidth

canvas.height = numberForHeight

-1

หากคุณต้องการพฤติกรรมแบบไดนามิกโดยยึดตามเช่นคำสั่งสื่อ CSS ไม่ใช้คุณสมบัติความกว้างและความสูง ใช้กฎ CSS จากนั้นก่อนที่จะรับบริบทการเรนเดอร์ผืนผ้าใบกำหนดให้กับแอตทริบิวต์ความกว้างและความสูงสไตล์ CSS และความสูง:

var elem = document.getElementById("mycanvas");

elem.width = elem.style.width;
elem.height = elem.style.height;

var ctx1 = elem.getContext("2d");
...

เป็นที่ชัดเจนว่าผ้าใบจะได้รับขนาดพิกัดเริ่มต้น (300 x 150) หากระบุขนาดใน CSS เท่านั้น อย่างไรก็ตามคำแนะนำนี้ใช้ไม่ได้สำหรับฉัน แต่วิธีแก้ปัญหาด้านล่างใช้ได้
ต่อ Lindberg

@PerLindberg - วิธีนี้ใช้ได้ผลถ้าคุณกำหนดความกว้างและความสูง CSS เป็นพิกเซลสำหรับองค์ประกอบ Canvas
Manolo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.