canvas lineWidth繪製原理

admin發表於2018-09-13

關於線條寬度繪製原理在canvas 1px畫素模糊現象解決方案一章節中有所涉及。

如果沒有良好掌握canvas繪製線條原理,可能會導致一系列意想不到問題。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
canvas {
  border: 2px dotted #ccc;
  margin:50px;
}
</style>
<script type="text/javascript">
window.onload = function () {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  ctx.lineWidth = 20;
  ctx.moveTo(0, 0);
  ctx.lineTo(200, 0);
  ctx.lineTo(200, 200);
  ctx.lineTo(0, 200);
  ctx.closePath();
  ctx.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="550" height="450"></canvas>
</body>
</html>

上面程式碼繪製了一個具有四個邊框的矩形圖案,通過lineWidth設定每一個線條的厚度為20px。

但是繪圖的實際表現卻有些讓人匪夷所思。

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201809/14/211042h2sryttnx2rr6yt6.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

是不是對上面繪製的圖形有一些疑問,為什麼左上兩邊只有10px的寬度。

下面通過圖示分析一下出現上述現象的原因。

圖示如下:

a:3:{s:3:\"pic\";s:43:\"portal/201809/13/111852bcj9hgfgaldah7fj.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

當想要繪製從(3,1)到(3,5)的一條直線,那麼這個直線的寬度預設並不會實現第二個圖的效果。

因為寬度會沿著線條寬度的中線(紅線)向兩端擴充套件,根據需求,只要填充深藍色的部分即可,但是計算機並不會這樣。因為它不會只繪製一個畫素單元格的一半,剩餘的的一半也會被填充。

整個區域(淺藍和深藍的部分)會以實際設定顏色一半色調的顏色來填充。

但是如果線條的寬度是偶數,線條同樣會從中線向兩端擴充套件,但是能完整的填滿兩端的畫素,那麼填充顏色會保持不變。第二個網格圖片演示如何實現繪製一畫素直線時候,能夠精準定位和保持填充顏色不變的效果,我們只要從(3.5,1)位置繪製,這樣就能夠完美的填充一個畫素寬度。

程式碼執行怪異出現的原因:

原理介紹完畢,那麼程式碼繪製出現的怪異現象原因也就很明顯了。

[JavaScript] 純文字檢視 複製程式碼
ctx.lineWidth = 20
ctx.moveTo(0, 0);
ctx.lineTo(200, 0)

從左到右繪製一條橫向長度200px,厚度為20px的線條。

線條的繪製在垂直方位上也是從中線在垂直方位向兩端擴充套件繪製。

圖示如下:
a:3:{s:3:\"pic\";s:43:\"portal/201809/14/161426wfnjuwqpcfkfvph5.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上述程式碼左上邊框之所以顯示是10px,是因為由於從中線開始繪製向兩端擴充套件。

所以有一半的寬度被邊緣給遮擋了,只要調一下繪製就會全部顯示出來。

垂直和水平方位的繪製原理都是想通的。

程式碼修改如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
canvas {
    border: 2px dotted #ccc;
    margin:50px;
}
</style>
<script type="text/javascript">
window.onload = function () {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  ctx.lineWidth = 20;
  ctx.moveTo(20, 20);
  ctx.lineTo(200, 20);
  ctx.lineTo(200, 220);
  ctx.lineTo(20, 220);
  ctx.closePath();
  ctx.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="550" height="450"></canvas>
</body>
</html>

上述程式碼只是向右下挪動一下位置,被遮擋的部分邊框就會被顯示出來。

相關文章