- 從0到1:HTML5 Canvas動畫開發
- 莫振杰
- 1389字
- 2020-06-15 16:26:06
2.2 直線
2.2.1 Canvas坐標系
在學習之前,我們先來介紹一下Canvas使用的坐標系,這是學習Canvas最基本的前提。
我們經常見到的坐標系是數學坐標系,不過Canvas使用的坐標系是W3C坐標系,這兩種坐標系唯一的區別在于y軸正方向的不同,如圖2-1所示。
數學坐標系:y軸正方向向上。
W3C坐標系:y軸正方向向下。
小伙伴們一定要記住:W3C坐標系的y軸正方向是向下的。很多人學到后面對Canvas中的某些代碼感到很困惑,那是因為他們沒有清楚地意識到這一點。
數學坐標系一般用于數學上的應用,而在前端開發中幾乎所有涉及坐標系的技術使用的都是W3C坐標系,這些技術包括CSS3、Canvas、SVG等。了解這一點,以后在學習CSS3或者SVG的時候,我們一下子就可以串起很多知識。

圖2-1 數學坐標系和W3C坐標系
2.2.2 直線的繪制
在Canvas中,我們可以將moveTo()和lineTo()這兩個方法配合使用來畫直線。利用這兩個方法,我們可以畫一條直線,也可以同時畫多條直線。
1.一條直線
語法
cxt.moveTo(x1, y1);
cxt.lineTo(x2, y2);
cxt.stroke();
說明
cxt表示上下文環境對象context。
(x1,y1)表示直線“起點”的坐標。moveTo(x1,y1)的含義是“將畫筆移到點(x1,y1)位置,然后開始繪圖”。
(x2,y2)表示直線“終點”的坐標。lineTo(x2,y2)的含義是“使用畫筆從起點(x1,y1)開始畫直線,一直畫到終點(x2,y2)”。
對于moveTo()和lineTo()這兩個方法,我們從英文含義角度更容易理解和記憶。
cxt.moveTo(x1, y1);
cxt.lineTo(x2, y2);
上面兩句代碼僅僅是確定直線的“起點坐標”和“終點坐標”,但是實際上畫筆還沒“動”。因此,我們還需要調用上下文環境對象的stroke()方法才有效。
使用Canvas畫直線,跟我們平常用筆在紙張上畫直線的道理一樣,都是先確定直線起點(x1,y1)與終點(x2,y2),然后再用筆連線,即stroke()。
舉例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
function $$(id){
return document.getElementById(id);
}
window.onload = function () {
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
cxt.moveTo(50, 100);
cxt.lineTo(150, 50);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="200" height="150" style="border:1px dashed gray;"></canvas>
</body>
</html>
預覽效果如圖2-2所示。

圖2-2 畫一條直線
分析
在這個例子中,我們定義了一個獲取DOM對象元素的函數$$(id),這樣減少了重復代碼量,使得思路更加清晰。記住,Canvas中使用的坐標系是W3C坐標系,這個例子的分析思路如圖2-3所示。

圖2-3 分析思路
2.多條直線
使用moveTo()和lineTo()這兩個方法可以畫一條直線。其實,如果我們想同時畫多條直線,也是使用這兩個方法。
語法
cxt.moveTo(x1, y1);
cxt.lineTo(x2, y2);
cxt.lineTo(x3,y3);
……
cxt.stroke();
說明
lineTo()方法是可以重復使用的:第1次使用lineTo()后,畫筆將自動移到終點;第2次使用lineTo()后,Canvas會以“上一個終點的坐標”作為第2次調用的起點,然后再開始畫直線,依此類推。我們還是先來看一個例子,這樣更容易理解。
舉例:畫兩條直線
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
function $$(id){
return document.getElementById(id);
}
window.onload = function () {
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
cxt.moveTo(50,50);
cxt.lineTo(100,50);
cxt.moveTo(50,100);
cxt.lineTo(100,100);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="200" height="150" style="border:1px dashed gray;"></canvas>
</body>
</html>
預覽效果如圖2-4所示。

圖2-4 畫兩條直線
分析
記住,moveTo()的含義是“將畫筆移到該點的位置,然后開始繪圖”。lineTo()的含義是“將畫筆從起點開始畫直線,一直到終點”。
如果我們將cxt.moveTo(50,100);改為cxt.lineTo(50,100);,預覽效果如圖2-5所示。大家根據這個例子,仔細琢磨一下moveTo()與lineTo()兩個方法的區別。

圖2-5 cxt.moveTo(50,100);改為cxt.lineTo(50,100);
舉例:用直線畫一個三角形
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
function $$(id){
return document.getElementById(id);
}
window.onload = function () {
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
cxt.moveTo(50, 100);
cxt.lineTo(150, 50);
cxt.lineTo(150, 100);
cxt.lineTo(50, 100);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="200" height="150" style="border:1px dashed gray;"></canvas>
</body>
</html>
預覽效果如圖2-6所示。

圖2-6 用直線畫一個三角形
分析
這里使用moveTo()與lineTo()方法畫了一個三角形。在畫三角形之前,我們先要確定三角形3個頂點的坐標。
舉例:用直線畫一個矩形
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
function $$(id){
return document.getElementById(id);
}
window.onload = function () {
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
cxt.moveTo(50, 100);
cxt.lineTo(50, 50);
cxt.lineTo(150, 50);
cxt.lineTo(150, 100);
cxt.lineTo(50, 100);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="200" height="150" style="border:1px dashed gray;"></canvas>
</body>
</html>
預覽效果如圖2-7所示。

圖2-7 用直線畫一個矩形
分析
這里使用moveTo()和lineTo()方法畫了一個矩形。在畫矩形之前,我們也是要先確定矩形的4個頂點坐標(這幾個坐標值不是隨便來的,而是計算出來的)。
在Canvas中,使用moveTo()和lineTo()方法可以畫三角形、矩形、多邊形等。在實際開發中,對于三角形和多邊形,我們都用moveTo()和lineTo()方法來實現。但是對于矩形來說, Canvas為我們提供了一套更為簡單的方法,我們將在下一節給大家詳細介紹。
- .NET之美:.NET關鍵技術深入解析
- DevOps with Kubernetes
- GitLab Cookbook
- Delphi程序設計基礎:教程、實驗、習題
- 數據庫原理及應用(Access版)第3版
- PHP 從入門到項目實踐(超值版)
- ASP.NET Core 2 and Vue.js
- ArcGIS By Example
- Mastering Drupal 8 Views
- 打開Go語言之門:入門、實戰與進階
- Machine Learning With Go
- 超簡單:Photoshop+JavaScript+Python智能修圖與圖像自動化處理
- SQL Server 2014 Development Essentials
- Python程序設計:基礎與實踐
- Java程序性能優化實戰