边实践边学习Html5中的Canvas之平面图形绘制
1、Canvas是什么
1.1、Canvas简介
在HTML5之前,为了使页面更加绚丽多彩,我们很多情况下都是借助“图片”来实现。不过,使用图片这种方式,都是以“低性能”为代价的。因为图片体积大、下载速度慢等。为了应对日渐复杂的Web应用开发,W3C在HTML5标准中引入了Canvas这一门技术。Canvas,又称“画布”,是HTML5的核心技术之一。HTML5新增了一个Canvas元素,我们常说的Canvas技术,指的就是使用Canvas元素结合JavaScript来绘制各种图形的技术。既然Canvas是HTML5核心技术,那它都有哪些厉害之处呢?
- 绘制图形:Canvas可以用来绘制各种基本图形,如矩形、曲线、圆等,也可以绘制各种复杂绚丽的图形;
- 绘制图表:Canvas可以绘制满足各种需求的图表;
- 动画效果:使用Canvas,我们也可以制作各种华丽的动画效果;
- 游戏开发:游戏开发在HTML5领域具有举足轻重的地位,现在我们也可以使用Canvas来开发各种游戏。
1.2、Canvas与SVG
HTML5有两个主要的2D图形技术:Canvas和SVG。事实上,Canvas和SVG是两门完全不同的技术,两者具有以下区别:
- Canvas是使用JavaScript动态生成的,SVG是使用XML静态描述的。
- Canvas是基于“位图”的,适用于像素处理和动态渲染,图形放大会影响质量;SVG是基于“矢量”的,图形放大不会影响质量。也就是说,使用Canvas绘制出来的是一个“位图”,而使用SVG绘制出来的是一个“矢量图”。
- 每次发生修改,Canvas需要重绘,而SVG不需要重绘。
- Canvas与SVG的关系,简单来说就像“美术与几何”的关系一样。
1.3、Canvas使用
简单来说,HTML5 Canvas就是一门使用JavaScript来操作Canvas元素的技术。使用Canvas元素来绘制图形,需要以下3步:
- 获取Canvas对象;
- 获取上下文环境对象Context;
- 开始绘制图形。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.moveTo(100, 200);
cxt.lineTo(300, 100);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
说明:
在Canvas中,我们使用document.getElementById()方法来获取Canvas对象(这是一个DOM对象),然后使用Canvas对象的getContext(“2d”)方法获取上下文环境对象Context,最后使用Context对象的属性和方法来绘制各种图形。
1.4、Canvas元素
Canvas是一个行内块元素,我们一般需要指定其3个属性:id、width和height。width和height分别定义Canvas的宽度和高度。默认情况下,Canvas的宽度为300px,高度为150px。对于Canvas的宽度和高度,我们有两种方法来定义:在HTML属性中定义;在CSS样式中定义。但是在实际开发中,我们一定不要在CSS样式中定义,而是应该在HTML属性中定义。下面举例说明为什么不能在CSS样式定义Canvas的宽度和高度:
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
width: 400px;
height: 300px;
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取canvas宽度和高度
var str = "canvas的宽度为:" + cnv.width + ",高度为:" + cnv.height;
alert(str);
}
</script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
效果图:
说明:
从这个例子中我们可以看出:如果在CSS样式中定义,我们使用Canvas对象获取到的是宽度和高度的默认值,而不是实际的宽度和高度,这样我们就无法获取Canvas对象正确的宽度和高度。因此对于Canvas的宽度和高度,我们一定要在HTML属性中定义,而不是在CSS样式中定义。
1.5、Canvas对象
在Canvas中,我们使用document.getElementById()来获取Canvas对象。Canvas对象常用的属性和方法如下表:
属性 | 说明 | 方法 | 说明 |
---|---|---|---|
width | Canvas的宽度 | getContext(“2d”) | 获取Canvas2D上下文环境对象 |
height | Canvas的高度 | toDataURL() | 获取Canvas对象产生的位图的字符串 |
也就是说,我们可以使用cnv.width和cnv.height分别获取Canvas的宽度和高度,可以使用cnv.getContext(“2d”)来获取Canvas 2D上下文环境对象,也可以使用toDataURL()来获取Canvas对象产生的位图的字符串。在这里,cnv指的是Canvas对象。
2、直线
2.1、Canvas坐标系
在使用Canvas之前,我们先来介绍一下Canvas使用的坐标系。了解Canvas使用的坐标系,是使用Canvas的最基本的前提。我们经常见到的坐标系是数学坐标系,不过Canvas使用的坐标系是W3C坐标系,这两种坐标系唯一的区别在于y轴正方向的不同,如下图所示。
- 数学坐标系:y轴正方向向上。
- W3C坐标系:y轴正方向向下。
2.2、直线的绘制
2.2.1、一条直线
在Canvas中,我们可以配合使用moveTo()和lineTo()这两个方法来画直线。利用这两个方法,我们可以画一条直线,也可以同时画多条直线。
语法:
cxt.moveTo(x1, y1);
cxt.lineTo(x2, y2);
cxt.stroke();
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.moveTo(100, 200);
cxt.lineTo(300, 100);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
说明:
cxt表示上下文环境对象Context。(x1,y1)表示直线“起点”的坐标。moveTo的含义是“将画笔移到该点(x1,y1)位置上,然后开始绘图”。(x2,y2)表示直线“终点”的坐标。lineTo的含义是“从起点(x1,y1)开始画直线,一直画到终点坐标(x2,y2)”。cxt.moveTo(x1, y1);
和cxt.lineTo(x2, y2);
两句代码仅仅是确定直线的“起点坐标”和“终点坐标”这两个状态,但是实际上画笔还没开始“动”。因此,我们还需要调用上下文对象的stroke()方法才有效。
2.2.2、多条直线
从上面我们知道,使用moveTo()和lineTo()这两个方法可以画一条直线。其实,如果我们想要同时画多条直线,也是使用这两个方法。
语法:
cxt.moveTo(x1, y1);
cxt.lineTo(x2, y2);
cxt.lineTo(x3, y3);
......
cxt.stroke();
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.moveTo(100, 100);
cxt.lineTo(100, 200);
cxt.lineTo(300, 200);
cxt.lineTo(300, 100);
cxt.lineTo(100, 100);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
说明:
lineTo()方法是可以重复使用的。第1次使用lineTo()后,画笔将自动移到终点坐标位置,第2次使用lineTo()后,Canvas会以“上一个终点坐标”作为第2次调用的起点坐标,然后再开始画直线。
3、矩形
从2.2.2可以知道,我们可以配合使用moveTo()和lineTo()来画一个矩形。但是这种画矩形的方法代码量过多,因此在实际开发中并不推荐使用。对于绘制矩形,Canvas另外为我们提供了独立的方法来实现。在Canvas中,矩形分为两种:一种是“描边矩形”,另一种是“填充矩形”。
3.1、描边矩形
在Canvas中,我们可以配合使用strokeStyle属性和strokeRect()方法来画一个描边矩形。
语法:
cxt.strokeStyle = 属性值;
cxt.strokeRect(x, y, width, height);
strokeStyle是Context对象的一个属性,strokeRect()是Context对象的一个方法。
1、strokeStyle属性:
strokeStyle属性取值有3种:颜色值、渐变色和图案。strokeStyle取值为颜色值的几种情况如下:
//十六进制颜色值
cxt.strokeStyle = "#FFO000";
//颜色关键字
cxt.strokeStyle = "red";
//rgb颜色值
cxt.strokeStyle = "rgb(255,0,0)";
//rgba颜色值
cxt.strokeStyle = "rgba(255,0,0,0.8)";
2、strokeRect(x, y, width, height)方法:
strokeRect()方法用于确定矩形的坐标,其中x和y为矩形左上角的坐标,width表示矩形的宽度,height表示矩形的高度。我们还要特别注意一点,strokeStyle属性必须在strokeRect()方法之前定义,否则strokeStyle属性无效。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.strokeStyle = "red";
cxt.strokeRect(100, 100, 200, 100);
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
3.2、填充矩形
在Canvas中,我们可以配合使用fillStyle属性和fillRect()方法来画一个填充矩形。
语法:
cxt.fillStyle = 属性值;
cxt.fillRect(x, y, width, height);
fillStyle是Context对象的一个属性,fillRect()是Context对象的一个方法。
1、fillStyle属性:
fillStyle属性取值有3种:颜色值、渐变色和图案。fillStyle取值为颜色值的几种情况如下:
//十六进制颜色值
cxt.fillStyle = "#FFO000";
//颜色关键字
cxt.fillStyle = "red";
//rgb颜色值
cxt.fillStyle = "rgb(255,0,0)";
//rgba颜色值
cxt.fillStyle = "rgba(255,0,0,0.8)";
2、fillRect(x, y, width, height)方法:
fillRect()方法用于确定矩形的坐标,其中x和y为矩形左上角的坐标,width表示矩形的宽度,height表示矩形的高度。我们还要特别注意一点,fillStyle属性必须在fillRect()方法之前定义,否则fillStyle属性无效。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.fillStyle = "red";
cxt.fillRect(100, 100, 200, 100);
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
3.3、rect()方法
在Canvas中,如果想要绘制一个矩形,除了使用strokeRect()和fillRect()这两个方法之外,我们还可以使用rect()方法。
语法:
cxt.rect(x, y, width, height);
x和y为矩形左上角的坐标,width表示矩形的宽度,height表示矩形的高度。
举例1-用rect绘制描边矩形:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.strokeStyle = "blue";
cxt.rect(100, 100, 200, 100);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
举例2-用rect绘制填充矩形:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.fillStyle = "blue";
cxt.rect(100, 100, 200, 100);
cxt.fill();
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
说明:
strokeRect()、fillRect()和rect()都可以画矩形。这3种方法的参数是相同的,不同之处在于实现效果方面。其中,strokeRect()和fillRect()方法在调用之后,会立即把矩形绘制出来。而rect()方法在调用之后,并不会把矩形绘制出来。只有在使用rect()方法之后再调用stroke()或者fill()方法,才会把矩形绘制出来。
3.4、清空矩形
在Canvas中,我们可以使用clearRect()方法来清空“指定矩形区域”。
语法:
cxt.clearRect(x, y, width, height);
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.fillStyle = "green";
cxt.fillRect(100, 100, 200, 100);
cxt.clearRect(120, 120, 160, 60);
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
说明:
x和y分别表示清空矩形区域左上角的坐标,width表示矩形的宽度,height表示矩形的高度。
4、多边形
在Canvas中中我们可以配合使用moveTo()和lineTo()来画三角形和矩形。其实多边形也是使用moveTo()和lineTo()这两个方法画出来的。如果想要在Canvas中画多边形,我们需要事先计算出多边形中各个顶点的坐标,然后再使用moveTo()和lineTo()在Canvas中画出来。跟矩形不一样,Canvas没有专门用来绘制三角形和多边形的方法。对于三角形和多边形,我们也是使用moveTo()和lineTo()这两个方法来实现的。
4.1、Canvas绘制箭头
对于箭头,我们都是事先确定箭头的7个顶点坐标,然后使用moveTo()和lineTo()来绘制。
坐标确定如图:
举例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3.开始绘制图形
cxt.moveTo(80, 110);
cxt.lineTo(80, 190);
cxt.lineTo(200, 190);
cxt.lineTo(200, 230);
cxt.lineTo(320, 150);
cxt.lineTo(200, 70);
cxt.lineTo(200, 110);
cxt.lineTo(80, 110);
cxt.stroke();
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
4.2、Canvas绘制正多边形
正多边形在实际开发中也经常见到,要想绘制正多边形,我们首先来了解一下最简单的正多边形——正三角形。正三角形分析图如图所示。
根据正三角形的特点,我们可以封装一个绘制正多边形的函数:createPolygon()。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#canvas {
border: 1px dashed gray;
}
</style>
<script type="text/javascript">
window.onload = function () {
// 1.获取Canvas对象
var cnv = document.getElementById("canvas");
// 2.获取上下文环境对象Context
var cxt = cnv.getContext("2d");
// 3、绘制正三角形
createPolygon(cxt, 3, 200, 150, 100);
cxt.fillStyle = "yellow";
cxt.fill();
}
/**
* 绘制正多边形的函数
* @param cxt Canvas画笔对象
* @param n 正多边形的边数
* @param dx 正多边形中心坐标x
* @param dy 正多边形中心坐标y
* @param size 正多边形顶点到中心的距离
*/
function createPolygon(cxt, n, dx, dy, size) {
cxt.beginPath();
var degree = (2 * Math.PI) / n;
for (var i = 0; i < n; i++) {
var x = Math.cos(i * degree);
var y = Math.sin(i * degree);
cxt.lineTo(x * size + dx, y * size + dy);
}
cxt.closePath();
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
效果图:
说明:
cxt.beginPath();
用于开始一条新路径,cxt.closePath();
用于关闭路径。绘制其他正多边形只需修改对应边数和其他参数即可:
// 绘制正n边形
createPolygon(cxt, n, 200, 150, 100);
- 点赞
- 收藏
- 关注作者
评论(0)