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为我们提供了一套更为简单的方法,我们将在下一节给大家详细介绍。