canvas beginPath()

admin發表於2018-09-28

beginPath方法可以新建一個路徑,使用方式十分簡單。

正是由於它的簡單,反而會導致不少初學者忽略此方法所涉及的一些概念。

下面舉一個初學者最容易犯的錯誤,程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
window.onload = function () {
  let canvas = document.getElementById("ant");
  let ctx = canvas.getContext("2d");
  ctx.lineWidth = 6;
  ctx.beginPath();
  //目的繪製一條紅色的豎線
  ctx.strokeStyle = "red";
  ctx.moveTo(100, 10);
  ctx.lineTo(100, 80);
  ctx.stroke();

  //目的繪製一條藍色的豎線
  ctx.lineTo(200, 80);
  ctx.strokeStyle = "blue";
  ctx.stroke();
}
</script>
</head>
<body>
  <canvas id="ant"></canvas>
</body>
</html>

上述程式碼的初衷是繪製一條紅色豎線和藍色的橫線。

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

a:3:{s:3:\"pic\";s:43:\"portal/201809/28/212710lkhl39f49gv34tj4.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

很明顯,程式碼實際執行效果與預期效果有偏差,豎線並非紅色而是藍色。

出現上述問題,主要對路徑概念理解不夠導致。

出現問題的原因:

(1).canvas中,任何時刻只有一條路徑,此路徑可以擁有多個子路徑。

(2).建立繪圖環境會隱式呼叫beginPath方法建立一個路徑,所以第一個beginPath方法可以省略。

(3).建立路徑後,可以在其上面建立多個子路徑,子路徑的建立非常簡單,比如利用lineTo, arcTo和quadraticCurveTo等方法建立,但如果這些子路徑在一個路徑中,那麼描邊或者填充用顏顏色是統一的(後面覆蓋前面)。

(4).上面的程式碼中,首先繪製紅色的豎線,描邊顏色是紅色,然後再繪製一條橫線,描邊顏色是藍色,由於它們在同一條路徑中,那麼整個路徑會被重新進行一次描邊操作,紅色將會被後面繪製的藍色所覆蓋。

程式碼修改如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<script>
window.onload = function () {
  let canvas = document.getElementById("ant");
  let ctx = canvas.getContext("2d");
  ctx.lineWidth = 6;
  ctx.beginPath();
  //目的繪製一條紅色的豎線
  ctx.strokeStyle = "red";
  ctx.moveTo(100, 10);
  ctx.lineTo(100, 80);
  ctx.stroke();
  //目的繪製一條紅色的豎線
  ctx.beginPath();
  ctx.moveTo(100, 80);
  ctx.lineTo(200, 80);
  ctx.strokeStyle = "blue";
  ctx.stroke();
}
</script>
</head>
<body>
  <canvas id="ant"></canvas>
</body>
</html>

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

a:3:{s:3:\"pic\";s:43:\"portal/201809/28/212755dpkjj2mv4tgwjzvj.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上述程式碼成功實現了繪製兩條不同顏色直線的效果。

與第一個例子唯一不同是新增了兩行程式碼:

[JavaScript] 純文字檢視 複製程式碼
ctx.beginPath();
ctx.moveTo(100, 80);

解決方案分析如下:

(1).beginPath方法可以建立一個新的路徑,並清除之前路徑和子路徑(不是已經繪製的圖案)。

(2).那麼從現在開始,我們在一個全新的路徑中進行繪圖,這也是為什麼要再次使用moveTo方法的原因,因為已經在新的路徑,所以需要重新設定畫筆的起點位置。

相關閱讀:

(1).關於路徑知識更多內容可以參閱canvas路徑與子路徑詳解一章節。

(2).moveTo方法可以參閱canvas moveTo方法一章節。