《HTML5游戏编程核心技术与实战》一2.2 图形API

2.2 图形API

HTML5游戏编程核心技术与实战
创建canvas和获取了canvas的环境上下文之后,就可以开始进行绘图了。绘图的方式有两类:一类是进行图形操作,另一类是图像操作。本小节主要涉及图形相关的API,要使用canvas的API进行绘图,通常需要进行下列步骤。

(1)获取canvas元素。通过document.getElementById()取得元素。

(2)获取canvas元素的环境上下文。通过canvas.getContext ("2d")获取2D图像上下文。

(3)确定绘图模式。使用canvas绘图有两种模式,一种是fill,另外一种是stroke。fill是填充的意思,使用该方式模式进行绘图时候会把颜色填充整个图形,而使用stroke的模式只会进行描边框。

(4)设定绘图样式。通过fillStyle和strokeStyle指定绘图样式,fillStyle和strokeStyle分别对应fill模式和stroke模式。绘图样式包括绘图的颜色及渐变方式,通常情况下默认的绘图样式颜色是#000000,也就是黑色。

(5)指定线宽。可以通过lineWidth设定绘制的线宽,默认值是1.0像素。

在进行绘制图形之前,需要先理解路径的概念。

2.2.1 理解路径

canvas中所有的图形可以看成一条路径,这条路径包含0个或者多个子路径。我们可以把路径看成当前canvas中所有图形的集合,而每一个图形就是一条子路径,一条子路径是由一系列点的集合组成。举个例子,我们在canvas中画了一个圆和一条直线,那么可以认为当前canvas中包含两条子路径,一条是圆,一条是直线,这两个图形都是由一个个点集组成,这个圆称为一个闭合的路径,而线是没有闭合的路径。很明显,所谓闭合就是整个图形是封闭的,图形的开始点和结束点相互连接。

事实上,为了提高绘制的效率,当使用canvas进行绘图的时候,所有的图形操作都只是往当前子路径上填加图形,并不是真正的调用绘图操作。比如使用lineTo()进行画线操作,实际上它只是往当前子路径填加一条直线,最终调用stroke或者fill的时候,才是真正进行硬件操作进行绘图。

2.2.2 路径操作API

canvas中常见的创建和渲染路径的方法如表2-1所示。

2.2.3 绘制线条

关于线条的绘制主要包含以下两个常用的方法。

  • context.moveTo (x, y):把画笔移动到(x, y)坐标,建立新的子路径。
  • context.lineTo (x, y):用于建立上一个点到(x, y)坐标的直线,如果没有上一个点,则等同于moveTo (x, y),把(x ,y)点添加到子路径中。

最后使用stroke()可以对路径进行描边。

使用context.lineTo (x, y)绘制直线,代码如下:

代码首先获取can元素的环境上下文,获得can元素的宽度和高度,把画笔移动到原点处,然后使用lintTo (width, height),建立一条从原点到右下角的直线,设定线的宽度为6个像素,笔的颜色是红色,最后通过stroke对整个路径描边。

最后的效果如图2-2所示。

如果,我们需要绘制更复杂的图形,就需要根据一些点的集合,不断的使用lineTo方法,比如下面的代码就绘制了一个向右的箭头:

最后的效果如图2-3所示。

这里需要注意的是,这里定义了7个点,在进行stroke之前使用closePath()函数闭合了路径,这时就会把最后一个点和第一个点连接起来,形成一个封闭的图形,当然,closePath并不是必需的。

2.2.4 绘制矩形

关于矩形的绘制主要包含以下两个常用的方法。

rect (x, y, w, h):建立两个子路径,一个是以点(x, y)为左上角,w和h分别为宽度和高度的矩形,另一个是点(x, y)。这个方法只是建立路径,所以当进行绘制的时候还需要使用stroke()方法描边。
最直接的方法是使用strokeRect (x, y, w, h),该方法会以(x, y)为左上角,(x+width, y+height)为右下角绘制矩形。
fillRect (x, y, w, h)方法则以(x, y)为左上角,(x+width, y+height)为右下角填充矩形。
clearRect (x, y, w, h)则用来清除以(x, y)为左上角,(x+width, y+height)为右下角的矩形区域。这个方法在进行动画处理的时候非常有用,因为在连续绘制动态图形的时候,需要先清除画布上的一块区域。

对于图2-4所示的图形,代码如下:

这段代码使用了strokeRect方法画出了8个同心的矩形。

2.2.5 绘制圆弧

关于圆弧的绘制主要包含以下两个常用的方法。

arc (x, y, radius, startAngle, endAngle, anticlockwise):arc方法用来绘制一段圆弧路径,以(x, y)为圆心位置、radius为半径、startAngle为起始弧度、endAngle为终止弧度来画,而在画圆弧时的旋转方向则由最后一个参数 anticlockwise 来指定,如果为 true 就是逆时针,false则为顺时针,如果startAngle和endAngle分别为0和2*Math.PI,则就变成了绘制圆形。
arcTo (x1, y1, x2, y2, radius):这个函数实际上用来绘制同时和两条直线相切的,半径为radius的最短圆弧,一条直线以上一个点和(x1, y1)构成,另一条直线以(x1, y1)和(x2, y2)构成。
这两个函数只是把圆弧添加到了路径中,如果绘制,则还需要通过stroke或者fill函数。

使用arc方法绘制图2-5所示的8个同心圆的代码如下:

需要注意的是,代码在for循环中,进行绘制圆形之前,使用了beginPath()方法,beginPath()方法用于清除掉之前的路径。如果不清除的话,那么,每次绘制的时候都会把之前的路径又绘制,这样会降低绘制的效率。所以通常情况下,如果我们决定要绘制一个新的图形,最好先使用beginPath()清除上一次的路径。

2.2.6 绘制贝塞尔曲线

关于贝塞尔曲线的绘制主要包含以下两个常用的方法。

bezierCurveTo (cp1x, cp1y, cp2x, cp2y, x, y):绘制一条三次贝塞尔曲线,这条曲线的开始点是子路径的最后一个点,结束点是(x, y),而贝塞尔曲线的控制点是(cp1x, cp1y)和(cp2x, cp2y)。
quadraticCurveTo (cpx, cpy, x, y):绘制一条二次贝塞尔曲线,这条曲线的开始点是子路径的最后一个点,结束点是(x, y),而贝塞尔曲线的控制点是(cpx, cpy)。
贝塞尔曲线是应用非常广泛的函数曲线,通常在计算机图形中用来为平滑曲线建立模型,图2-6分别显示了三次和二次的贝塞尔曲线,区别在于三次的贝塞尔曲线多了一个控制点。

以下代码在canvas中显示了一个可以调节控制点的贝塞尔曲线,c1和c2表示控制点,s和e表示曲线的开始和终止点:

注意在绘制所有图形之前一定要使用clearRect()方法来清除屏幕,因为如果不清除屏幕,将会在屏幕上留下所有的绘制图像。

2.2.7 线条属性

在进行图形绘制的时候,线条有一些常用的属性会影响到线条的样式。

lineWidth:该属性用来设置线条的粗细,默认为1个像素大小,小于0的值将被忽略。
这里有一个比较经典的问题,就是绘制1像素大小的直线。如果绘制1像素大小的线条,看起来像2个像素,当直线呈水平或者垂直方向时,这个现象非常明显,这是为什么呢?W3C在canvas规范中解释到,当使用canvas绘制图形时候,它是由路径向两边扩展的,各占绘制线条宽度的一半,但canvas的坐标并不是直接和屏幕上的像素对应,假设需要绘制一条(3, 1)到(3, 5)的直线,把屏幕放大,得到图2-7。

图2-7中的每一个格子代表显示屏的一个像素,当绘制(3, 1)到(3, 5)的直线的时候,首先,路径就定位在屏幕中第三列像素和第四列像素的中间位置。此时,绘制1像素的时候,就需要从这条路径分别向两边扩展0.5个像素,但实际上显示屏是不可能绘制半个像素的,这个时候就只能同时绘制第三列和第四列两列像素。所以如果需要屏幕绘制一个像素大小的线,只需要把canvas的路径定位到某一个像素的中间位置,这时候刚好向两边扩展为一个像素,如图2-8所示。

所以,如果需要绘制1像素大小的直线,需要把坐标加上0.5的偏移,这时候就显示正常了,当然,如果画大于1像素的或者绘制斜线就没有必要额外处理了。

  • lineCap:lineCap用来指定线条两端的端点,常用的值有3个,分别是butt(无端点)、round(圆端点)以及square(方端点),其中默认值是butt,三种样式显示的效果如图2-9所示。
  • lineJoin:lingJoin用来设置两条线连接的方式,常用值有round(圆角)、bevel(斜角)以及miter(尖角),其中miter是默认值,三种样式如图2-10所示。
    ..\tu\图2.9.tif

miterLimit:当lineJoin为miter时有效,表示的是斜面长度和线宽的比例,默认为10。

2.2.8 线条颜色

线条的颜色使用stokeStyle属性指定,颜色的值可以使用类似CSS的方式指定,比如红色可以采用以下3种方式:

2.2.9 填充

前面所介绍的绘图方式都是适用描边处理(stroke),我们可以通过fill方法进行图形填充。

fill():该方法使用当前的fillStyle填充当前路径,通过fillStyle = 颜色值可以指定填充的颜色,颜色表示和strokeStyle一样。
以下代码就填充了8个红色的同心圆:

最后的效果如图2-11所示。

除了可以填充纯色以外,canvas还提供了填充渐变色以及填充贴图,先来看看渐变对象。

经常使用Photoshop处理图像的读者知道,在Photoshop中就有这种渐变工具,可以通过拖拉一条辅助线来实现渐变。在canvas中提供的渐变对象有两种,一种是线性渐变,另一种是径向渐变。

  • createLinearGradient (x0, y0, x1, y1):创建一个线性的渐变对象,开始点是(x0, y0),结束点是(x1, y1)。
  • createRadialGradient (x0, y0, r0, x1, y1, r1):创建一个径向渐变对象,开始点以(x0, y0)为圆心,r0为半径,结束点以(x1, y1)为圆心,r1为半径。
    一旦创建完了渐变对象之后,就可以通过该对象的addColorStop()方法,在渐变的某一点中增加一个颜色值,这个点可以认为是关键点,这样,每个关键点之间的色彩就会出现渐变效果。
  • addColorStop(offset, color):offset表示偏移大小,值在0.0~1.0之间,其实就是一个百分比值;color是使用类似CSS字符串描述的色彩颜色,比如addColorStop (0, "red")表示初始关键点是一个红色点。
    当使用fillStyle属性指定一个渐变对象的时候,就可以使用渐变的方式填充路径了,以下代码以渐变对象填充了两个矩形区域。

效果如图2-12所示。

以上是使用渐变颜色进行填充,另外一种填充方式是使用一张图片作为贴图进行填充,使用的API如下。

  • createPattern (image,repetition):image表示需要填充的图像,可以是img、canvas、video元素等;repetition定义图像按照什么方式贴图,通常的贴图方式有以下几种。
  • repeat:水平和垂直方向重复贴图,默认值。
  • repeat-x:水平方向重复贴图。
  • repeat-y:垂直方向重复贴图。
  • no-repeat:使用一次贴图。
    通过createPattern方法创建了一个模式对象后,就可以通过fillStyle或者strokeStyle等属性指定,然后就可以使用指定的图形进行填充。

以下代码创建了两个分别使用stroke()和fill()填充的图形:

效果如图2-13所示。

2.2.10 绘图状态

conext中有一些全局的属性,如前面提到的strokeStyle、fillStyle、lineWidth等。当我们进行绘图的时候,有时,在改变这些值之前,需要保存上一次绘图的状态,下次绘制的时候又需要进行恢复,这种情况很常见。当然,不需要我们自己定义一个全局的对象进行保存,context中本身定义了以下方法用于保存和恢复canvas的状态。

  • save():把当前绘图状态压到绘图状态堆中。
  • restore():弹出绘图状态堆最上面保存的绘图状态。

状态堆中包含以下部分。

  • 当前的transformation matrix(换矩阵)前的clipping region(区域)。
  • 当前的属性值:fillStyle、font、globalAlpha、globalCompositeOperation、lineCap、lineJoin、lineWidth、miterLimit、shadowBlur、shadowColor、shadowOffsetX、shadowOffsetY、strokeStyle、textAlign、textBaseline。
    为了避免本次绘图状态影响到下次绘图,通常情况下在绘图之前,都会使用contex.save()方法保存当前绘图状态,绘制完成后再使用context.restore()进行恢复。

对于图形的操作,在HTML4时代可以使用SVG进行矢量绘图,而canvas除了支持矢量图形外,还可以直接针对图像以及像素操作,这才是canvas强大的地方。接下来,看看canvas关于图像处理的部分。

时间: 2024-10-30 22:13:05

《HTML5游戏编程核心技术与实战》一2.2 图形API的相关文章

《HTML5游戏编程核心技术与实战》——2.2 图形API

2.2 图形API 创建canvas和获取了canvas的环境上下文之后,就可以开始进行绘图了.绘图的方式有两类:一类是进行图形操作,另一类是图像操作.本小节主要涉及图形相关的API,要使用canvas的API进行绘图,通常需要进行下列步骤. (1)获取canvas元素.通过document.getElementById()取得元素. (2)获取canvas元素的环境上下文.通过canvas.getContext ("2d")获取2D图像上下文. (3)确定绘图模式.使用canvas绘

《HTML5游戏编程核心技术与实战》——2.3 图像API

2.3 图像API 除了绘制常用的图形以外,canvas提供了一系列的API能够对图像进行操作,常见的图像API有以下3个方法. drawImage (image, dx, dy):把image图像绘制到画布上(dx, dy)坐标位置.drawImage (image, dx, dy, w, h):把image图像绘制到画布上(dx, dy)坐标位置,图像的宽度是w,高度是h.drawImage (image, sx, sy, sw, sh, dx, dy, dw, dh):截取image图像以

《HTML5游戏编程核心技术与实战》一2.1 基本知识

2.1 基本知识 HTML5游戏编程核心技术与实战在HTML4时代,不安装插件的情况下,基于浏览器的绘图组件是最初由微软向W3C递交的VML(Vector Markup Language矢量标记语言)技术,但未被W3C采纳,只能在IE5.0及其后续版本中使用,后来VML和PGML(由Adobe和SUN提出)合并成SVG(Scalable Vector Graphics,可伸缩矢量图形)规范.SVG技术是基于XML的矢量图形绘制技术,对于普通的图像应用来说足够,但是对于性能要求较高的游戏渲染来说,

《HTML5游戏编程核心技术与实战》一2.4 坐标变换

2.4 坐标变换 HTML5游戏编程核心技术与实战在绘制图像的过程中,经常可能需要对图像进行旋转.缩放等变形处理,canvas也提供了一系列的API帮助我们完成这些操作. 关于画布的坐标变换,canvas提供了以下常用的API,这些API的操作必须要在绘制之前调用,否则不会产生任何效果. translate (x, y):平移,把画布的原点坐标移动到(x, y)位置,x表示将坐标原点向左移x个像素,y表示将坐标原点向下移动y个像素.正常情况下canvas的原点坐标位于左上角,那么我们可以通过tr

《HTML5游戏编程核心技术与实战》一导读

前 言 HTML5游戏编程核心技术与实战为什么写这本书对游戏的热爱使我萌发了写书的念头.漫画和电子游戏是童年最美好的回忆,任天堂的红白机陪伴着我度过了童年最快乐的时光,20世纪80年代,大街小巷的街机室成了孩子们快乐的天堂.随着时光流逝,许多经典的游戏画面已成为过去,但对游戏的热情依然不减,希望能借此书得以慰藉逝去的青春.青春不在,游戏热血永存! IT技术可谓日新月异,要想不被社会淘汰,就必须要不断学习,不断充实自己.HTML5是Web技术中提出的新规范.新生的HTML5技术虽然目前还不十分成熟

《HTML5游戏编程核心技术与实战》一2.8 小结

2.8 小结 HTML5游戏编程核心技术与实战本章介绍了canvas的一些常用的操作,作为HTML5的最重要的特性,canvas使得在Web中开发免插件的较高性能的游戏提供了条件,接下来的第3章中,我们介绍HTML5中的多媒体元素.

《HTML5游戏编程核心技术与实战》一2.5 绘制文字

2.5 绘制文字 HTML5游戏编程核心技术与实战canvas中除了可以绘制图形图像外,还可以绘制文字,同时也可以指定文字的字体.大小.对齐方式以及填充文字的纹理. fillText (text, x, y, [maxWidth]):在canvas上填充文字,text表示需要绘制的文字,x.y分别表示绘制在canvas上的横.纵坐标,最后一个参数可选,表示显示文字的最大宽度,防止文字显示溢出.strokeText (text, x, y, [maxWidth]):在canvas上描边文字,参数的

《HTML5游戏编程核心技术与实战》一2.7 案例:《你画我猜》

2.7 案例:<你画我猜> HTML5游戏编程核心技术与实战在这一小节中,我们将利用前面介绍的知识,来创作一个<你画我猜>游戏中的主要功能.<你画我猜>是一款老少皆宜的多人在线的网络游戏,2012年风靡一时,玩法其实也来源于生活当中,经常在娱乐节目中出现.通常在节目中是这样玩的,主持人写出一个词语,然后由一个参与者根据这个词语画出相应的图案,由另一个参与者来根据这个图案猜出这个词语,而<你画我猜>就把现实生活中的这个玩法转到了电脑上,玩法就是这么简单.当然,

《HTML5游戏编程核心技术与实战》一2.6 其他全局属性

2.6 其他全局属性 HTML5游戏编程核心技术与实战在context中还有一些常见的全局属性,做一些了解. globalAlpha:透明度,这个值用来设置在画布上绘制的透明度,值的范围从0-1之间,使用这个属性我们可以完成一些常见的效果,比如游戏中常见的淡入淡出效果. 以下代码展示了一张图片淡入,也就是逐渐显示的效果. globalCompositeOperation:全局混合模式,这个属性定义了如果在画布上绘制多个图像时,图像进行叠加的方式,也称为混合模式,类似于Photoshop这种图像处