【E800编译】相信到目前你应该已经对Canvas这一神奇的HTML5新元素有了必定的了解。在本文中,咱们将深刻了解画布的功能及特色,学习如何在HTML中利用Canvas绘制图形以及其它类型对象。理解如何改变图形形状和对象是如何绘制在画布上,以及如何将其擦除。最后,实例演示如何创建与浏览器窗口的大小相同的画布,以及一些开发游戏必不可缺的技巧等等。 javascript
熟悉canvas元素 css
如同视频和音频元素,canvas元素绝对没有使用外部插件。你惟一须要的只是2D渲染上下文API,即便你不了解2D渲染上下文API也不用担忧。 html
使用canvas元素很简单,咱们从下面的代码开始: java
<canvaswidth="500" height="500"> jquery
<!--Insert fallback content here --> web
</canvas> ajax
它的做用是建立一个新的空白画布元素,目前还不可以看到什么,由于你没有作任何2D渲染上下文。 canvas
建立canvas元素时要特别注意宽度和高度属性,显然这些属性定义canvas元素的大小,进而定义了2D渲染上下文的大小。在没有定义的状况下,将被设置默认的宽度和高度分别为300,150。稍后在本章,咱们将着眼于建立一个动态改变大小并填满整个浏览器窗口的画布。 api
注:canvas元素的位置在你的HTML文档中定义。与其余HTML元素同样,它能够按CSS所需处处移动。 浏览器
浏览器支持
目前大多数浏览器都支持canvas元素和其大部分功能,但对于Internet Explorer,至少任何早于Internet Explorer 9的版本没法提供支持。一种方式是提醒旧版IE用户升级,另外一种选择是使用谷歌开发的一些ExplorerCanvas脚本。这种方法的优势是,你只须要在页面中潜入一个脚本,那么canvas元素在旧版IE中也能正常显示。
ExplorerCanvas脚本可在ExplorerCanvaswebsite下载,并按照说明安装。
2D渲染上下文
canvas元素的目的是充当2D渲染上下文的封装,为您提供全部必要的方法调用以及绘制和操做的功能点。如下这一点很是重要:绘图是在2D渲染上下文中进行,而不是在canvas元素中。你能够经过canvas元素访问并显示2D渲染上下文。
坐标系统
2D渲染上下文是一标准的基于屏幕的绘图平台。与其余2D平台一样,使用同一个平面直角坐标系左上角的原点(0,0)。向右移动会增长x的值,向下移动则增长y值。因此绘图前必需要先了解坐标系统是如何工做的。
2D渲染上下文中直角坐标系
一般一个坐标系统中的单个单元至关于在屏幕上的1个像素,因此位置(24,30)位于向右24像素,向下30像素。也有一些场合坐标系统的单位可能等于2个像素,如高清显示器,不过通常的经验法则是:1坐标单位等于1个屏幕像素。
访问2D渲染系统
不用多说,下面让咱们建立一个基本的带空白画布元素的HTML页:
<!DOCTYPE html>
<html>
<head>
<title>Learning thebasics of canvas</title>
<metacharset="utf-8">
<scripttype="text/javascript" src="http://ajax.googleapis.com
/ajax/libs/jquery/1/jquery.min.js"></script>
<scripttype="text/javascript">
$(document).ready(function() {
});
</script>
</head>
<body>
<canvasid="myCanvas" width="500" height="500">
<!-- Insert fallbackcontent here -->
</canvas>
</body>
</html>
若是如今就运行它,将看不到任何东西。在真正开始绘图以前,咱们先访问2D渲染上下文。将如下代码写入jQuery声明语句中:
var canvas = $("#myCanvas");
var context =canvas.get(0).getContext("2d");
咱们在这里所要作的只是给canvas元素分配一个变量,而后经过调用getContext方法为2D渲染上下文分配另外一个变量的。这里须要注意的是,咱们使用了jQuery,咱们须要调用get方法来获取canvas元素的DOM,这样咱们就能够获取canvas的getContext方法。记住一点, get方法与画布自己无关。
如今咱们就有了一个包含2D渲染上下文的变量,在声明上下文变量后添加如下代码:
context.fillRect(40, 40, 100, 100);
此时刷新页面,你会发现已经出现了一个黑色的正方形!
图形是黑色的,这是在画布上绘制时的默认颜色。在稍后章节中,咱们会学习如何使用默认以外的颜色进行图形绘制。
绘制基本形状与线条
正如你所看到的,绘制一个正方形是很是简单的,它只需一行代码,fillRect()方法以下:
context.fillRect(40, 40, 100, 100);
你会发现所调用的方法为fillRect()而不是fillSquare()。而咱们都知道正方形实际是具备相同长度的边的矩形。
建立一个矩形须要四个参数,前两个是矩形起点(左上角)的坐标值(X,Y),最后两个为矩形的宽度和高度。fillRect()方法能够形象化改写成以下形式:
context.fillRect(x, y, width, height);
为清晰起见,改变矩形的宽度值为200,保存该文件并刷新页面。
固然,这是一个矩形。在不一样的位置绘制矩形只是改变起点的坐标(x,y)。例如在(200,300)该点处:
在不一样位置绘制一个矩形
注意:若是你绘图时原点超出了canvas元素尺寸范围,它将不会出如今屏幕上,而只有原点或者图形的某些部分处于画布元素范围内时才是可见的。
fillRect()与strokeRect()是对双胞胎,fillRect方法绘制一个矩形并填充一种颜色(本例以黑色为例),strokeRect方法绘制一个矩形并描边,也就是说矩形的轮廓有线条描边。固然你也能够在fillRect实例中改用strokeRect方法。
绘制一个描边的矩形
如今出现的是一个中空的矩形轮廓。
直线
直线与以上形状略有不一样,他们实际上为路径。建立一个简单的路径,你必须首先在2D渲染上下文中调用beginPath方法,接着调用moveTo方法,设置咱们即将绘制路径的起点坐标(X,Y)。最后调用closePath开始路径绘制,其参数(X,Y)指定了路径终点。示例代码以下:
context.beginPath(); // Start the path
context.moveTo(40, 40); // Set the pathorigin
context.lineTo(340, 40); // Set the pathdestination
context.closePath(); // Close the path
context.stroke(); // Outline the path
路径效果如图:
经过改变lineTo方法的参数(X,Y)能够实现直线的倾斜:
context.lineTo(340, 340);
圆
在画布上建立一个圈的方式远区别于建立一个矩形。圆是一个至关复杂的形状,甚至在Canvas中没有单独的方法调用来绘制。不过Canvas中提供了绘制圆弧的方法,而咱们所要作的就是将弧的两端拼接。下面咱们来看看如何在Canvas中绘制一个圆:
context.beginPath(); // Start the path
context.arc(230, 90, 50, 0, Math.PI*2,false); // Draw a circle
context.closePath(); // Close the path
context.fill(); // Fill the path
第一个与最后两行分别是开启和关闭路径(弧)并填充。
其中共有六个参数,(X,Y)指定了圆弧原点的坐标(本例中圆的圆心),弧的半径,起始角度,终止角度以及一个布尔值(布尔值为true则逆时针绘制圆弧,反之顺时针)。Arc()方法中具体参数以下:
context.arc(x, y, radius, startAngle,endAngle, anticlockwise);
圆的绘制图示以下:
这里须要注意的是,角度的单位都为弧度,360度(一个完整的圆)为2π(圆周率乘以2)弧度。能够利用下面的公式完成弧度转换:
var degrees = 1; // 1 degree
var radians = degrees * (Math.PI / 180); //0.0175 radians
度和弧度之间的转换
注意:在JavaScript中能够经过调用数学函数Math对象获取PI值,除此以外数学函数的做用也十分普遍,如咱们后面即将提到的随机数生成。
运最后行这个实例,实际效果以下:
若是只是绘制一个半圆,很简单,只需将角度改成π,代码以下:
context.arc(230, 90, 50, 0, Math.PI,false); // Draw a semi-circle
若是一切顺利,应该有一个可爱的半圈,在您的浏览器。
Arc()中的第六个参数是可选的,不过在Firefox浏览器下,若是它被省略了则会抛出一个错误,因此在绘图时最好保留以明肯定义绘制的方向。
样式
下面咱们看看在本章开头说起的定义图形颜色的问题:
context.fillStyle = "rgb(255, 0,0)";
context.fillRect(40, 40, 100, 100);
经过设置2D渲染上下文中的FillStyle属性,可以实现改变图形和路径的填充色。在前面的实例中,分配了一个RGB(红,绿,蓝)颜色值,固然你也可使用任何有效的十六进制代码形式的CSS颜色值(如#FF0000或“red”)。在本例中颜色设置为全红(红色,没有绿色与蓝色),实际效果将会以下:
这样会有一个缺点,问题在于设置了FillStyle属性后就意味着你以后的一切图形绘制都会按该颜色方案执行。当你只是想改变其中一个对象的颜色,需在完成绘制后将FillStyle属性设置为黑色(或另外某颜色),以下列代码所示:
context.fillStyle = "rgb(255, 0,0)";
context.fillRect(40, 40, 100, 100); // Redsquare
context.fillRect(180, 40, 100, 100); // Redsquare
context.fillStyle = "rgb(0, 0,0)";
context.fillRect(320, 40, 100, 100); //Black square
在浏览器中的效果为:
一样你也能够经过使用strokeStyle属性勾勒图形和路径,例如,下面用stroke代替本例中的fill:
context.strokeStyle = "rgb(255, 0,0)";
context.strokeRect(40, 40, 100, 100); //Red square
context.strokeRect(180, 40, 100, 100); //Red square
context.strokeStyle = "rgb(0, 0,0)";
context.strokeRect(320, 40, 100, 100); //Black square
注:固然也能够同时使用fillStyle与strokeStyle属性,就绘制出填充与轮廓颜色大相径庭的图形。
context.strokeStyle = "rgb(255, 0,0)";
context.beginPath();
context.moveTo(40, 180);
context.lineTo(420, 180); // Red line
context.closePath();
context.stroke();
context.strokeStyle = "rgb(0, 0,0)";
context.beginPath();
context.moveTo(40, 220);
context.lineTo(420, 220); // Black line
context.closePath();
context.stroke();
调整线宽
想要在画布上改变线宽,就要用到2D渲染上下文中的lineWidth属性。lineWidth属性默认值为1,你能够将它设置为所需的任意值。例如,咱们改变红色与黑色线条的宽度:
context.lineWidth = 5; // Make lines thick
context.strokeStyle = "rgb(255, 0,0)";
context.beginPath();
context.moveTo(40, 180);
context.lineTo(420, 180); // Red line
context.closePath();
context.stroke();
context.lineWidth = 20; // Make lines eventhicker
context.strokeStyle = "rgb(0, 0,0)";
context.beginPath();
context.moveTo(40, 220);
context.lineTo(420, 220); // Black line
context.closePath();
context.stroke();
运行结果显示为稍厚的红线与过厚的黑线:
lineWidth属性在图形上一样适用:
context.lineWidth = 5; // Make lines thick
context.strokeStyle = "rgb(255, 0,0)";
context.strokeRect(40, 40, 100, 100); //Red square
context.strokeRect(180, 40, 100, 100); //Red square
context.lineWidth = 20; // Make lines eventhicker
context.strokeStyle = "rgb(0, 0,0)";
context.strokeRect(320, 40, 100, 100); //Black square
绘制文本
Canvas不只仅是用来绘制图形和图像,也能够用它来显示文本。尽管在不少状况下这并非一个较好的选择,尤为是相比使用更为传统的HTML元素(如AP元素)而言。
画布上的文字是做为一个图像绘制出来,准确来说它并非文字,也就意味着它没法像普通HTML文档中的文本那样被光标选中。若是你以前使用Microsoft画图,那么你就会明白:一旦文本已经绘制,就不能再次编辑,除非删除重绘。在画布上绘制文本的好处是,你可使用各类精彩功能在画布上绘制。这里须要强调的是,不该在画布上建立文本,你应该使用正常的HTML元素建立文本,而后经过CSS定位到画布的顶层。这里的关键区别在于,HTML处理文本(内容),而Canvas直接针对像素和图形的处理。
如下代码演示了如何绘制文本:
var text = "Hello, World!";
context.fillText(text, 40, 40);
2D渲染上下文中fillText方法共有四个参数(一个可选,咱们暂时忽略);首先是要绘制的文本字符串,第二和第三参数是文本原点(左下角)的坐标值(X,Y)。
这里没有演示实例效果,由于它过小以至于很难看到,这是由于画布上的文本字体的默认设置为10px sans-serif(绝对微小)。可按下列代码所示更改字体属性:
var text = "Hello, World!";
context.font = "30px serif"; //Change the size and font
context.fillText(text, 40, 40);
与CSS中的字体属性相似,字体属性为一个字符串值。在前面的例子中,给出的字体属性是像素尺寸,以及所要使用的字体名称。实例中已将它设置为serif,效果以下:
若是须要你甚至能够设置为斜体:
var text = "Hello, World!";
context.font = "italic 30pxserif";
context.fillText(text, 40, 40);
在这里惟一要作的只是将italic添入字体属性字符串中。除此以外还能够做不少设置,诸如行的高度以及其它备用字体等等,这里就不一一描述。
注:不难发现画布的基础功能使用极其简单方便,由于2D渲染上下文API中使用的方法与属性都是以易于理解的方式命名,这些都可以轻松掌握。
进行下一步以前,咱们先来了解下如何勾勒文本,这是很是有用的:
var text = "Hello, World!";
context.font = "italic 60pxserif";
context.strokeText(text, 40, 100);
其中调用的strokeText()方法的参数与fillText()彻底相同,为了能更清晰的显示,调整了上例中字体的大小及位置:
画布擦除
当你在绘图过程当中出了错或要擦拭重绘时,能够有两种选择:调用clearRect()方法,或者宽度/高度技巧。咱们首先看看2D渲染上下文中clearRect()方法。
例如刚刚在画布上绘制一个正方形和一个圆:
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2,false);
context.closePath();
context.fill();
如今须要作的就是调用clearRect()方法,指定擦除区域的原点坐标(X,Y),以及其宽度和高度。若是画布500像素宽,500像素高,那么调用方式能够以下:
context.clearRect(0, 0, 500, 500);
此时再运行,将显示为空白。当不清楚画布的大小时,还能够调用clearRect(),参数能够由jQuery宽度与高度的方法获取:
context.clearRect(0, 0, canvas.width(),canvas.height());
完整代码以下:
var canvas = $("#myCanvas");
var context = canvas.get(0).getContext("2d");
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2,false);
context.closePath();
context.fill();
context.clearRect(0, 0, canvas.width(),canvas.height());
注:canvas元素实际上提供了宽度和高度属性,因此选择哪一种方式彻底取决于你,使用jQuery方式,或纯JavaScript方式获取画布的尺寸。
其实能够没必要清除整个画布,彻底能够很容易地清除某一特定区域。例如,在本例中仅删除正方形,就可按下列方式调用clearRect():
context.clearRect(40, 40, 100, 100);
这样就能够单独留下一个圆。
这种方式能够指定clearRect()中的参数以清除一个特定的区域。在本例中,咱们将擦除区域的起点(左上角)设定在正方形的左上角(40,40),并将擦除区域的宽度与高度设置为正方形的宽高度(100)。其结果是只有正方形被清除。一样你也能够经过改变clearRect()参数将圆形擦除:
context.clearRect(180, 40, 100, 100);
这样保留下来的就会只是一个正方形。
需注意的是,一个弧形的圆心是它的中心,因此要获得clearRect方法正确的起点,咱们须要首先获取弧的圆心,且X,Y的值需分别减去半径。
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2,false);
context.closePath();
context.fill();
context.clearRect(230, 90, 50, 50);
以上代码会截去圆形的一部分:
有时这种方式能够用于快速方便地绘制复杂图形,先绘制出基本形状再加以裁剪。
宽度/高度技巧
若是你想擦除画布上的一切从头开始,那么能够考虑宽度/高度的技巧。这能够用来重置画布至默认设置并刷新状态。这种方法确实有一些缺点,先举个例子:
context.fillStyle = "rgb(255, 0,0)";
context.fillRect(40, 40, 100, 100);
context.beginPath();
context.arc(230, 90, 50, 0, Math.PI*2,false);
context.closePath();
context.fill();
先在画布上绘制一个红色的正方形和圆形,而后添加画布复位:
canvas.attr("width",canvas.width());
canvas.attr("height",canvas.height());
这只是一个jQuery技巧应用,您须要改变的是canvas元素的宽度与高度属性,而且能够经过jQuery的attr()方法作到这一点。咱们需传递参数名(宽度和高度),以及所要设置的参数值(与以前的的宽度和高度相同)。正常状况下你会看到一个空白的画布。
添加如下代码行:
context.fillRect(40, 40, 100, 100);
宽度/高度技巧的缺点是,在画布上全部一切都会复位,包括样式和颜色等。
Canvas填充浏览器窗口
到目前为止canvas元素一直在500像素这一固定的宽度和高度上,但那么如何才能让它填满整个浏览器窗口呢?对于一个普通的HTML元素来讲,你只需正常将其宽度和高度属性设置为100%便可。不过画布元素并不支持该方法,这里咱们来看另外一种方式。
最简单的方式作就是将canvas元素的宽度和高度精确设置为浏览器窗口的宽度和高度。咱们能够经过window浏览器对象和jQuery技巧获取宽度和高度:
var canvas = $("#myCanvas");
var context = canvas.get(0).getContext("2d");
canvas.attr("width",$(window).get(0).innerWidth);
canvas.attr("height",$(window).get(0).innerHeight);
context.fillRect(0, 0, canvas.width(),canvas.height());
使用$(window).get(0).innerHeight代替$(window).height()是由于后者没法返回全部浏览器窗口的完整高度值。这种方法实际效果并不完美,浏览器窗口中canvas元素和滚动条的四周仍存在白色区域:
为了解决这个问题,咱们须要用到CSS。在文本编辑器中建立一个canvas.css,并保存在HTML文档的同一目录下,将下列代码加入CSS文件中并保存:
* { margin: 0; padding: 0; }
html, body { height: 100%; width: 100%; }
canvas { display: block; }
要使用HTML文档中这一CSS,须要添加如下代码行至jQuery script元素前的head元素内:
<link href="canvas.css"rel="stylesheet" type="text/css">
其效果是canvas元素完美地填充了整个浏览器窗口。
固然,这并无结束。你会发现无论怎么调整浏览器窗口大小,画布都会保持着以前的尺寸:
这就须要在浏览器窗口大小改变的同时来调整画板的大小。
$(window).resize(resizeCanvas);
function resizeCanvas() {
canvas.attr("width", $(window).get(0).innerWidth);
canvas.attr("height", $(window).get(0).innerHeight);
context.fillRect(0, 0, canvas.width(), canvas.height());
};
resizeCanvas();
此时你会发现画布实现完美调整,而且不会出现滚动条。
总结
本章中涵盖了各类有趣的东西,特别是在你从未使用过的Canvas以前。如今你已经学会如何使用canvas元素进行基本形状和路径的绘制,改变图形和路径的颜色,以及如何绘制文本,擦除画布,如何使画布填充浏览器窗口等等。