从0到1:HTML5 Canvas动画开发
上QQ阅读APP看书,第一时间看更新

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