在上一次教学中我们简单的了解了canvas的一些基础,现在我们开始学习canvas是如何通过JS绘制出一个个图形的。
良好的开始是必须的,如同每一次学习一样,第一次的例子总是让人愤怒,因为我们没法在什么都没有学习的情况下对它有一个全面的了解。没关系,让我一点一点的为你解答它的奥秘吧。
首先,我们来一个简单的绘画,绘制两个交错的矩形,一个拥有alpha透明效果。
<html>
<head>
<scripttype="application/x-javascript">
function draw() {
var canvas = document.getElementByIdx_x("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect (10, 10, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}
}
</script>
</head>
<bodyonload="draw();">
<canvas id="canvas" width="150"height="150"></canvas>
</body>
</html>
好的,我们展示了一段代码。在学习之前,我想先补一下基础知识。canvas中的参数是以像素为单位的,也就是说,canvas就像一张大的坐标纸,上面都是格子,只不过它的Y轴是向下的。在绘画时,我们的起始坐标点就是左上角,该点坐标是0,0,后面的教程中我们将学会如何把移动原点,旋转以及缩放网格。不过现在我们会使用默认的状态。
canvas 只支持一种基本形状——矩形,所以其它形状都是有一个或多个路径组合而成。还好,有一组路径绘制函数让我们可以绘制相当复杂的形状。
我们首先看看矩形吧,有三个函数用于绘制矩形的:
fillRect(x,y,width,height) : 绘制填充的矩形
strokeRect(x,y,width,height) : 绘制矩形边框
clearRect(x,y,width,height) : 用透明效果清除出一块矩形
fillRect的作用我们了解了,现在知道在第一个例子里面fillRect的作用了吧。没错,以10,10与30,30为坐标绘制两个55*50的矩形。
好的,让我们上一个绘制矩形的代码:
functiondraw(){
var canvas =document.getElementByIdx_x('tutorial');
if(canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.fillRect(25,25,100,100);
ctx.clearRect(45,45,60,60);
ctx.strokeRect(50,50,50,50);
}
}
出来的结果应该是这样的:fillRect 函数画了一个大的黑色矩形(100x100),clearRect 函数清空了中间 60x60大小的方块,然后strokeRect 函数又在清空了的空间内勾勒出一个 50x50 的矩形边框。
好的,我们了解了矩形绘制的基本规则,但是是不是还有一个疑惑呢?对了,那个填充颜色和透明的效果怎么做的?等着吧,我会慢慢告诉你的。
不像画矩形那样的直截了当,绘制路径是需要一些额外的步骤的。我们需要以下四个函数:
beginPath()
closePath()
stroke()
fill()
第一步是用beginPath创建一个路径。在内存里,路径是以一组子路径(直线,弧线等)的形式储存的,它们共同构成一个图形。每次调用beginPath,子路径组都会被重置,然后可以绘制新的图形。
第二步就是实际绘制路径的部分,很快我们就会看到。
第三步是调用closePath方法,它会尝试用直线连接当前端点与起始端点来关闭路径,但如果图形已经关闭或者只有一个点,它会什么都不做。这一步不是必须的。
最后一步是调用stroke或fill方法,这时,图形才是实际的绘制到canvas上去。stroke是绘制图形的边框fill会用填充出一个实心图形。
当调用fill时,开放的路径会自动闭合,而无须调用closePath。这点一定注意。
让我们画一个简单的三角形吧:
ctx.beginPath();
ctx.moveTo(75,50);
ctx.lineTo(100,75);
ctx.lineTo(100,25);
ctx.fill();
是不是又发现了新的方法呢?moveTo方法是干什么的呢?好问题,它的作用我们马上就会看到。
moveTo是一个十分有用的方法,虽然并不能用它来画什么,但却是绘制路径的实用方法的一部分。你可以把它想象成是把笔提起,并从一个点移动到另一个点的过程。
moveTo(x,y)
它接受x和y(新的坐标位置)作为参数。
不难理解,这个方法的作用就是制定下一次绘制动作的起始点。就好比我们想画两个鸡蛋,画完第一个需要把笔拿起来放到第二个鸡蛋的位置开始画,而不能在纸上直接的拖出一条线再去画它。moveTo方法就是这样的一个方法,它模拟了拿起笔的动作,也就是进行一个点的转移。我们已经了解到要是想画一个路径那么起始点就是一开始的位置,moveTo方法就是改变这个位置的方法。
当canvas初始化或者调用beginPath的时候,起始坐标设置就是原点(0,0)。大多数情况下,我们用moveTo方法将起始坐标移至其它地方,或者用于绘制不连续的路径。
废话不多说,上代码,啥都明白了:
functiondrawShape(){
// get the canvas elementusing the DOM
var canvas =document.getElementByIdx_x('tutorial');
// Make sure we don'texecute when canvas isn't supported
if(canvas.getContext){
// use getContext to use the canvas for drawing
var ctx = canvas.getContext('2d');
// Draw shapes
ctx.beginPath();
ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle
ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false);// Mouth
ctx.moveTo(65,65);
ctx.arc(60,65,5,0,Math.PI*2,true);// Left eye
ctx.moveTo(95,65);
ctx.arc(90,65,5,0,Math.PI*2,true);// Right eye
ctx.stroke();
} else {
alert('You need Safari or Firefox 1.5+ to see thisdemo.');
}
}
咱先不管arc方法的作用,将每一个moveTo方法注释,你就会明白它的作用了。
lineTo是直线绘制的方法。
lineTo(x,y)
lineTo方法接受终点的坐标(x,y)作为参数。起始坐标取决于前一路径,前一路径的终点即当前路径的起点,起始坐标也可以通过moveTo方法来设置。
没有例子,哪有人生啊~上代码:
//填充三角形
ctx.beginPath();
ctx.moveTo(25,25);
ctx.lineTo(105,25);
ctx.lineTo(25,105);
ctx.fill();
//勾边三角形
ctx.beginPath();
ctx.moveTo(125,125);
ctx.lineTo(125,45);
ctx.lineTo(45,125);
ctx.closePath();
ctx.stroke();
示例画的是两个三角形,一个实色填充,一个勾边。首先调用beginPath方法创建一个新路径,然后用moveTo方法将起始坐标移至想要的位置,然后画两条直线来构成三角形的两条边。
可以注意到fill和strok绘三角形的区别,上面也提到过,使用fill路径会自动闭合,但使用stroke不会,如果不关闭路径,勾画出来的只有两边。所以,我们可以注释closePath方法,来看一下效果。还记得closePath方法吗?不记得翻回去查吧~