前言
我們使用canvas的時候一般在canvas元素中直接設置它的width和height:
<canvas id="myCanvas" width="300" height="150">browser don't support canvas</canvas>
當然,也可以不在canvas中進行設置,直接在css樣式中設置,因為canvas本身也是一個html節點
canvas{width:600px;height:300px}
設置以后,打開頁面,發現canvas畫布展示大小也ok,這個時候,我們在上面畫一個40*40矩形,看下效果
var canvas = document.getElementById('canvas'), context = canvas.getContext('2d'); context.fillStyle = 'cornflowerblue'; context.fillRect(0, 0, 40, 40);
運行頁面,展示如下
canvas大小為600px,高為300px,沒有任何問題,符合預期。但是矩形...這顯然不是40*40好吧,這是80*80
為什么會發生這種情況呢?
canvas的元素大小與繪圖表面大小
canvas的大小分為兩種,一個是canvas作為html元素本身的尺寸,另外一個canvas作為繪圖容器的繪圖表面大小。
在canvas元素中設置寬高,同時指定了canvas的元素尺寸以及繪圖表面的尺寸,兩者相等,繪圖不會有任何問題
但如果使用css設置canvas高寬,其實只是指定了canvas的元素尺寸,而不會影響canvas的繪圖表面的尺寸,如果兩者尺寸是一致的,並不會產生什么問題,但如果不一致,就會出現各種奇怪的問題,這個時候瀏覽器會有自動縮放的機制,對繪圖表面進行縮放,使之適應canvas元素的尺寸。
看我們前面的例子,canvas元素以及繪圖表面的尺寸是300*150,但css中設置了canvas元素尺寸是600*300,實際矩形的繪制是在300*150的繪圖表面中進行繪制的,繪制完成以后要顯示在canvas元素中,需要進行縮放,故產生了圖形變化的問題。
在前面的例子我們打印一下日志:
var box = canvas.getBoundingClientRect(); //canvas元素的邊界框 console.log(canvas.width + "---" + canvas.height) //300-150 console.log(box.width + "---" + box.height); //600-300
其中canvas對象獲取的其實是繪圖表面大小,box獲取的是canvas元素的大小
那縮放的規則是什么?
我們用幾個例子來看一下
1. css中設置canvas元素600*300,繪圖表面300*100,畫矩形40*40
實際矩形80*120
寬度是預期的兩倍,高度是預期3倍
2. Css中設置canvas元素600*300,繪圖表面200*150,畫矩形40*40
實際矩形120*80
寬度是預期的3倍,高度是預期的2倍
3. Css中設置canvas元素600*300,繪圖表面1200*900,畫矩形60*60
實際矩形30*20
寬度是預期的1/2,高度是預期的1/3
4. Css中設置canvas元素600*300,繪圖表面1800*600,畫矩形60*60
實際矩形20*30
寬度是預期的1/3,高度是預期的1/2
我們用element表示canvas元素,用canvas表示繪圖表面,src表示繪制的內容,dest表示展示的內容,縮放規則為:dest.size = src.size * (element.size / canvas.size)
其它
其實不僅僅是大小縮放的問題,坐標也會偏移,在canvas中畫圓,如果canvas元素與繪圖表面的尺寸不一致,會發現實際展示的圓心位置並不是你指定的坐標,實際展示的坐標位置同樣遵循上面所述的規則。
當然,解決這些問題非常簡單,就是不要使用css來指定canvas元素大小,保持canvas元素尺寸與繪圖表面尺寸的一致性