HTML5高级程序设计 (2).pdf

上传人:asd****56 文档编号:70322086 上传时间:2023-01-19 格式:PDF 页数:45 大小:1.29MB
返回 下载 相关 举报
HTML5高级程序设计 (2).pdf_第1页
第1页 / 共45页
HTML5高级程序设计 (2).pdf_第2页
第2页 / 共45页
点击查看更多>>
资源描述

《HTML5高级程序设计 (2).pdf》由会员分享,可在线阅读,更多相关《HTML5高级程序设计 (2).pdf(45页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、22 第 2 章 Canvas API 2 Canvas API 本章中,我们将探索如何使用 HTML5 的 Canvas API。Canvas API 很酷,可以通过它来动态生成和展示图形、图表、图像以及动画。本章将使用渲染 API(rendering API)的基本功能来创建一幅可以放大缩小并自适应浏览器环境的图。还会演示如何基于用户输入来动态创建图像,生成热点图。当然,我们也会提醒你在使用 HTML5 Canvas 时需要注意的问题,并且分享解决这些问题的方法。本章只涉及了最基本的图形知识,因此,你大可不必担心学不会而跳过本章。来吧,让我们一起来感受 HTML5 中这个强大的特性吧。2.

2、1 HTML5 Canvas 概述 关于 HTML5 Canvas API 完全可以写一本书(还不会是一本很薄的书)。由于只有一章的篇幅,所以我们将讨论 API 中那些我们认为是最常用的功能。2.1.1 历史 Canvas 的概念最初是由苹果公司提出的,用于在 Mac OS X WebKit 中创建控制板部件(dashboard widget)。在 Canvas 出现之前,开发人员若要在浏览器中使用绘图 API,只能使用 Adobe的 Flash 和 SVG(Scalable Vector Graphics,可伸缩矢量图形)插件,或者只有 IE 才支持的 VML(Vector Markup L

3、anguage,矢量标记语言),以及其他一些稀奇古怪的 JavaScript 技巧。假设我们要在没有canvas元素的条件下绘制一条对角线听起来似乎很简单,但实际上如果没有一套二维绘图 API 的话,这会是一项相当复杂的工作。HTML5 Canvas 能够提供这样的功能,对浏览器端来说此功能非常有用,因此 Canvas 被纳入了 HTML5 规范。起初,苹果公司曾暗示可能会为 WHATWG(Web Hypertext Application Technology Working Group,Web 超文本应用技术工作组)草案中的 Canvas 规范申请知识产权,这在当时引起了一些在 第 2 章

4、 2.1 HTML5 Canvas 概述 23 1 2 3 4 6 9 11 7 5 8 10 Web 标准化追随者的关注。不过,苹果公司最终还是按照 W3C 的免版税专利权许可条款公开了其专利。SVG 和 CANVAS 对比“Canvas 本质上是一个位图画布,其上绘制的图形是不可缩放的,不能像 SVG 图像那样可以被放大缩小。此外,用 Canvas 绘制出来的对象不属于页面 DOM 结构或者任何命名空间这点被认为是一个缺陷。SVG 图像却可以在不同的分辨率下流畅地缩放,并且支持点击检测(能检测到鼠标点击了图像上的哪个点)。既然如此,为什么 WHATWG 的 HTML5 规范不使用 SVG

5、呢?尽管 Canvas 有明显的不足,但 HTML Canvas API 有两方面优势可以弥补:首先,不需要将所绘制图像中的每个图元当做对象存储,因此执行性能非常好;其次,在其他编程语言现有的优秀二维绘图 API 的基础上实现Canvas API 相对来说比较简单。毕竟,二鸟在林不如一鸟在手。”Peter 2.1.2 canvas是什么 在网页上使用canvas元素时,它会创建一块矩形区域。默认情况下该矩形区域宽为 300 像素,高为 150 像素,但也可以自定义具体的大小或者设置canvas元素的其他特性。代码清单 2-1是可放到 HTML 页面中的最基本的canvas元素。代码清单 2-1

6、 基本的canvas元素 24 第 2 章 Canvas API 在页面中加入了canvas元素后,我们便可以通过 JavaScript 来自由地控制它。可以在其中添加图片、线条以及文字,也可以在里面绘图,甚至还可以加入高级动画。大多数主流操作系统和框架支持的二维绘制操作,HTML5 Canvas API 都支持。如果你在近年来曾经有过二维图像编程的经验,那么会对 HTML5 Canvas API 感觉非常顺手,因为这个 API 就是参照既有系统设计的。如果没有这方面经验,则会发现与这么多年来一直使用的图片加 CSS 开发 Web 图形的方式比起来,Canvas 的渲染系统有多么强大。使用ca

7、nvas编程,首先要获取其上下文(context)。接着在上下文中执行动作,最后将这些动作应用到上下文中。可以将canvas的这种编辑方式想象成为数据库事务:开发人员先发起一个事务,然后执行某些操作,最后提交事务。2.1.3 canvas坐标 如图 2-1 所示,canvas中的坐标是从左上角开始的,x 轴沿着水平方向(按像素)向右延伸,y 轴沿垂直方向向下延伸。左上角坐标为x=0,y=0的点称作原点。2.1.4 什么情况下不用canvas 尽管canvas元素功能非常强大,用处也很多,但在某些情况下,如果其他元素已经够用了,就不应该再使用canvas元素。例如,用canvas元素在 HTML

8、 页面中动态绘制所有不同的标题,就不如直接使用标题样式标签(H1、H2 等),它们所实现的效果是一样的。图 2-1 canvas中的 x、y坐标 x 轴 y 轴 0,0 16,0 0,16 16,16 2.1 HTML5 Canvas 概述 25 1 2 3 4 6 9 11 7 5 8 10 2.1.5 替代内容 访问页面的时候,如果浏览器不支持canvas元素,或者不支持 HTML5 Canvas API 中的某些特性,那么开发人员最好提供一份替代代码(2.1.7 节中的表 2-1 详细介绍了浏览器对canvas的支持情况)。例如,开发人员可以通过一张替代图片或者一些说明性的文字告诉访问者

9、,使用最新的浏览器可以获得更佳的浏览效果。代码清单 2-2 展示了如何在canvas中指定替代文本,当浏览器不支持canvas的时候会显示这些替代内容。代码清单 2-2 在canvas元素中使用替代内容 Update your browser to enjoy canvas!除了上面代码中的文本外,同样还可以使用图片,不论是文本还是图片都会在浏览器不支持canvas元素的情况下显示出来。canvas元素的可访问性怎么样“提供替代图像或替代文本引出了可访问性这个话题很遗憾,这是 HTML5 Canvas 规范中明显的缺陷。例如,没有一种原生方法能够自动为已插入到canvas中的图片生成用于替换的

10、文字说明。同样,也没有原生方法可以生成替代文字以匹配由 Canvas Text API 动态生成的文字。在写本书的时候,暂时还没有其他方法可以处理canvas中动态生成的内容,不过已经有工作组开始着手这方面的设计了。让我们一起期待吧。”Peter 26 第 2 章 Canvas API 2.1.6 CSS 和canvas 同大多数 HTML 元素一样,canvas元素也可以通过应用 CSS 的方式来增加边框,设置内边距、外边距等,而且一些 CSS 属性还可以被canvas内的元素继承。比如字体样式,在canvas内添加的文字,其样式默认同canvas元素本身是一样的。此外,在canvas中为c

11、ontext设置属性同样要遵从 CSS 语法。例如,对context应用颜色和字体样式,跟在任何 HTML 和 CSS 文档中使用的语法完全一样。2.1.7 浏览器对 HTML5 Canvas 的支持 除了 Internet Explorer 以外,其他所有浏览器现在都提供对 HTML5 Canvas 的支持。不过,随后我们会列出一部分还没有被普遍支持的规范,Canvas Text API 就是其中之一,但是作为一个整体,HTML5 Canvas 规范已经非常成熟,不会有特别大的改动了。从表 2-1 中可以看到,写本书的时候,已经有很多浏览器支持 HTML5 Canvas 了。表2-1 浏览器

12、对HTML5 Canvas的支持 浏 览 器 支持情况 Chrome 从1.0版本开始支持 Firefox 从1.5版本开始支持 Internet Explorer 不支持 Opera 从9.0版本开始支持 Safari 从1.3版本开始支持 从上面的表格中可以看出,在所有浏览器中,只有 Internet Explorer 不支持 HTML5 Canvas。如果需要在 Internet Explorer 中使用canvas,可以选择使用名为 explorercanvas 的开源项目(http:/ explorercanvas 时,需要先判断当前浏览器是否是2.2 使用 HTML5 Canvas

13、 API 27 1 2 3 4 6 9 11 7 5 8 10 Internet Explorer,如果是则在页面中嵌入script标签来加载 explorercanvas。写法如下:开发者迫切希望 Canvas 可以受到广泛支持,因此不断有项目启动来尝试解决老浏览器或者非标准浏览器不支持 Canvas 的问题。微软已经宣布 Internet Explorer 9 将支持canvas,因此,所有主流浏览器都支持canvas已经指日可待了。由于各家浏览器对canvas的支持程度有差异,所以最好在使用 API 之前,先测试一下HTML5 Canvas 是否被支持。2.2.1 节会讲解怎样通过代码来

14、检测浏览器支持 Canvas 的情况。2.2 使用 HTML5 Canvas API 本节将深入探讨 HTML5 Canvas API。为此,我们将使用各种 HTML5 Canvas API 创建一幅类似于 LOGO 的图像,图像是森林场景,有树,还有适合长跑比赛的美丽跑道。虽然这个示例从平面设计的角度来看毫无竞争力,但却可以合理演示 HTML5 Canvas 的各种功能。2.2.1 检测浏览器支持情况 在创建 HTML5 canvas元素之前,首先要确保浏览器能够支持它。如果不支持,你就要为那些古董级浏览器提供一些替代文字。代码清单 2-3 就是检测浏览器支持情况的一种方法。代码清单 2-3

15、 检测浏览器支持情况 try document.createElement(canvas).getContext(2d);document.getElementById(support).innerHTML=HTML5 Canvas is supported in your browser.;catch(e)document.getElementById(support).innerHTML=HTML5 Canvas is not supported 28 第 2 章 Canvas API in your browser.;上面的代码试图创建一个canvas对象,并且获取其上下文。如果发生错误

16、,则可以捕获错误,进而得知该浏览器不支持canvas。页面中预先放入了 ID 为support的元素,通过以适当的信息更新该元素的内容,可以反映出浏览器的支持情况。以上示例代码能判断浏览器是否支持canvas元素,但不会判断具体支持canvas的哪些特性。写本书的时候,示例中使用的 API 已经很稳定并且各浏览器也都提供了很好的支持,所以通常不必担心这个问题。此外,希望开发人员能够像代码清单 2-3 一样为canvas元素提供备用显示内容。2.2.2 在页面中加入canvas 在 HTML 页面中插入canvas元素非常直观。代码清单 2-4 就是一段可以被插入到 HTML页面中的canvas

17、代码。代码清单 2-4 canvas元素 以上代码会在页面上显示出一块 200200 像素的“隐藏”区域。假如要为其增加一个边框,可以像代码清单 2-5 中的代码一样,用标准 CSS 边框属性来设置。代码清单 2-5 带实心边框的canvas元素 注意,上面的代码中增加了一个值为“diagonal”的 ID 特性,这么做的意义在于以后的开2.2 使用 HTML5 Canvas API 29 1 2 3 4 6 9 11 7 5 8 10 发过程中可以通过 ID 来快速找到该canvas元素。对于任何canvas对象来说,ID 特性都是特别重要的,因为对canvas元素的所有操作都是通过脚本代码

18、控制的,没有 ID 的话,想要找到要操作的canvas元素会很难。代码清单 2-5 在浏览器中的执行效果如图 2-2 所示。图 2-2 HTML页面中的简单canvas元素 看起来好像没什么,但是就像那些艺术家说的,一张白纸可以画出最新最美的图画。现在,就让我们在这张“白纸”上作画吧。前面说过,在没有 HTML5 Canvas 的情况下,很难在页面上绘制一条对角线。现在我们来看看,有了 Canvas 以后,同样的事情会有多么简单。从代码清单2-6 中可以看到,基于上面绘制的画布,仅仅使用几行代码就可以画出一条对角线。代码清单 2-6 在canvas中绘制一条对角线 function drawD

19、iagonal()/取得 canvas 元素及其绘图上下文 var canvas=document.getElementById(diagonal);var context=canvas.getContext(2d);/用绝对坐标来创建一条路径 context.beginPath();context.moveTo(70,140);context.lineTo(140,70);/将这条线绘制到 canvas 上 context.stroke();30 第 2 章 Canvas API window.addEventListener(load,drawDiagonal,true);仔细看一下上面这

20、段绘制对角线的 JavaScript 代码。虽然简单,它却展示出了使用 HTML5 Canvas API 的重要流程。首先通过引用特定的canvas ID 值来获取对canvas对象的访问权。这段代码中 ID 就是diagonal。接着定义一个context变量,调用canvas对象的getContext方法,并传入希望使用的canvas类型。代码清单中通过传入“2d”来获取一个二维上下文,这也是到目前为止唯一可用的上下文。提示 规范未来的某个版本中可能会增加对三维上下文的支持。接下来,基于这个上下文执行画线的操作。在代码清单中,调用了三个方法beginPath、moveTo和lineTo,传

21、入了这条线的起点和终点的坐标。方法moveTo和lineTo实际上并不画线,而是在结束canvas操作的时候,通过调用context.stroke()方法完成线条的绘制。图 2-3 显示了绘制结果。图 2-3 canvas中的对角线 成功了!虽然从这条简单的线段怎么也想象不到最新最美的图画,不过与以前的拉伸图像、怪异的 CSS 和 DOM 对象以及其他怪异的实现形式相比,使用基本的 HTML 技术在任意两点间2.2 使用 HTML5 Canvas API 31 1 2 3 4 6 9 11 7 5 8 10 绘制一条线段已经是非常大的进步了。从现在开始,就把那些怪异的做法永远忘掉吧。从上面的代

22、码清单中可以看出,canvas中所有的操作都是通过上下文对象来完成的。在以后的canvas编程中也一样,因为所有涉及视觉输出效果的功能都只能通过上下文对象而不是画布对象来使用。这种设计使canvas拥有了良好的可扩展性,基于从其中抽象出的上下文类型,canvas将来可以支持多种绘制模型。虽然本章经常提到对canvas采取什么样的操作,但读者应该明白,我们实际操作的是画布所提供的上下文对象。如前面示例演示的那样,对上下文的很多操作都不会立即反映到页面上。beginPath、moveTo以及lineTo这些函数都不会直接修改canvas的展示结果。canvas中很多用于设置样式和外观的函数也同样不

23、会直接修改显示结果。只有当对路径应用绘制(stroke)或填充(fill)方法时,结果才会显示出来。否则,只有在显示图像、显示文本或者绘制、填充和清除矩形框的时候,canvas才会马上更新。2.2.3 变换 现在我们探讨一下在canvas上绘制图像的另一种方式使用变换(transformation)。接下来的代码清单显示结果跟上面是一样的,只是绘制对角线的代码不一样。这个简单示例可能会让你误认为使用变换增加了不必要的复杂性。事实并非如此,其实变换是实现复杂canvas操作的最好方式。在后面的示例中将会看到,我们使用了大量的变换,而这对熟悉 HTML5 Canvas API的复杂功能是至关重要的

24、。也许了解变换最简单的方法(至少这种方法不涉及大量的数学公式,也不需手足并用地去解释)就是把它当成是介于开发人员发出的指令和canvas显示结果之间的一个修正层(modification layer)。不管在开发中是否使用变换,修正层始终都是存在的。修正在绘制系统中的说法是变换在应用的时候可以被顺序应用、组合或者随意修改。每个绘制操作的结果显示在canvas上之前都要经过修正层去做修正。虽然这么做增加了额外的复杂性,但却为绘制系统添加了更为强大的功能,可以像目前主流图像编辑工具那样支持实时图像处理,所以 API 中这部分内容的复杂性是必要的。不在代码中调用变换函数并不意味着可以提升canvas

25、的性能。canvas在执行的时候,变换会被呈现引擎隐式调用,这与开发人员是否直接调用无关。在接触最基本的绘制操作之前,提前了解系统背后的原理至关重要。关于可重用代码有一条重要的建议:一般绘制都应从原点(坐标系中的0,0点)开始,应用变换(缩放、平移、旋转等),然后不断修改代码直至达到希望的效果。如图 2-4 所示。32 第 2 章 Canvas API 代码清单 2-7 展示了如何使用最简单变换方法translate函数。图 2-4 基于原点绘制和变换的示意图 代码清单 2-7 用变换的方式在canvas上绘制对角线 function drawDiagonal()var canvas=docu

26、ment.getElementById(diagonal);var context=canvas.getContext(2d);/保存当前绘图状态 context.save();/向右下方移动绘图上下文 context.translate(70,140);/以原点为起点,绘制与前面相同的线段 context.beginPath();context.moveTo(0,0);context.lineTo(70,-70);context.stroke();/恢复原有的绘图状态 原点(0,0)从原点开始 绘制 浏览器变换:平移、缩放、旋转 新坐标 100,100 最终在画布 上绘制出来 context

27、.translate(100,100);context.beginPath();context.moveTo(0,0);context.lineTo(70,70);context.stroke();2.2 使用 HTML5 Canvas API 33 1 2 3 4 6 9 11 7 5 8 10 context.restore();window.addEventListener(load,drawDiagonal,true);我们详细研究一下上面这段通过平移方式绘制对角线的 JavaScript 代码。(1)首先,通过 ID 找到并访问canvas对象。(ID 是diagonal。)(2)接

28、着通过调用canvas对象的getContext函数获取上下文对象。(3)接下来,保存尚未修改的context,这样即使进行了绘制和变换操作,也可以恢复到初始状态。如果不保存,那么在进行了平移和缩放等操作以后,其影响会带到后续的操作中,而这不一定是我们所希望的。在变换前保存context状态可以方便以后恢复。(4)下一步是在context中调用translate函数。通过这个操作,当平移行为发生的时候,我们提供的变换坐标会被加到结果坐标(对角线)上,结果就是将要绘制的对角线移动到了新的位置上。不过,对角线呈现在canvas上是在绘制操作结束之后。(5)应用平移后,就可以使用普通的绘制操作来画对

29、角线了。代码清单中调用了三个函数来绘制对角线beginPath、moveTo以及lineTo。绘制的起点是原点(0,0),而非坐标点(70,140)。(6)在线条勾画出来之后,可以通过调用context.stroke()函数将其显示在canvas上。(7)最后,恢复context至原始状态,这样后续的canvas操作就不会被刚才的平移操作影 图 2-5 canvas上平移过的对角线 34 第 2 章 Canvas API 响了。图 2-5 显示了用这段代码绘制的对角线。虽然新绘制的对角线看起来跟前面的一模一样,但这次绘制使用了强大的变换功能。学习完本章接下来的内容,就会明白变换的强大之处。2.

30、2.4 路径 关于绘制线条,我们还能提供很多有创意的方法。不过,现在应该进一步学习稍复杂点的图形:路径。HTML5 Canvas API 中的路径代表你希望呈现的任何形状。本章对角线示例就是一条路径,你可能已经注意到了,代码中调用beginPath就说明是要开始绘制路径了。实际上,路径可以要多复杂有多复杂:多条线、曲线段,甚至是子路径。如果想在canvas上绘制任意形状,那么你需要重点关注路径 API。按照惯例,不论开始绘制何种图形,第一个需要调用的就是beginPath。这个简单的函数不带任何参数,它用来通知canvas将要开始绘制一个新的图形了。对于canvas来说,beginPath函数

31、最大的用处是canvas需要据此来计算图形的内部和外部范围,以便完成后续的描边和填充。路径会跟踪当前坐标,默认值是原点。canvas本身也跟踪当前坐标,不过可以通过绘制代码来修改。调用了beginPath之后,就可以使用context的各种方法来绘制想要的形状了。到目前为止,我们已经用到了几个简单的context路径函数。moveTo(x,y):不绘制,只是将当前位置移动到新的目标坐标(x,y)。2.2 使用 HTML5 Canvas API 35 1 2 3 4 6 9 11 7 5 8 10 lineTo(x,y):不仅将当前位置移动到新的目标坐标(x,y),而且在两个坐标之间画一条直线。

32、简而言之,上面两个函数的区别在于:moveTo就像是提起画笔,移动到新位置,而lineTo告诉canvas用画笔从纸上的旧坐标画条直线到新坐标。不过,再次提醒一下,不管调用它们哪一个,都不会真正画出图形,因为我们还没有调用stroke或者fill函数。目前,我们只是在定义路径的位置,以便后面绘制时使用。下一个特殊的路径函数叫做closePath。这个函数的行为同lineTo很像,唯一的差别在于closePath会将路径的起始坐标自动作为目标坐标。closePath还会通知canvas当前绘制的图形已经闭合或者形成了完全封闭的区域,这对将来的填充和描边都非常有用。此时,可以在已有的路径中继续创建

33、其他的子路径,或者随时调用beginPath重新绘制新路径并完全清除之前的所有路径。跟了解所有复杂系统一样,最好的方式还是实践。现在,我们先不管那些线条的例子,使用HTML5 Canvas API 开始创建一个新场景带有长跑跑道的树林。权且把这个图案当成是我们长跑比赛的标志吧。同其他的画图方式一样,我们将从基本元素开始。在这幅图中松树的树冠最简单。代码清单 2-8 演示了如何在canvas上绘制一颗松树的树冠。代码清单 2-8 用于绘制树冠轮廓的函数 function createCanopyPath(context)/绘制树冠 context.beginPath();context.move

34、To(-25,-50);36 第 2 章 Canvas API context.lineTo(-10,-80);context.lineTo(-20,-80);context.lineTo(-5,-110);context.lineTo(-15,-110);/树的顶点 context.lineTo(0,-140);context.lineTo(15,-110);context.lineTo(5,-110);context.lineTo(20,-80);context.lineTo(10,-80);context.lineTo(25,-50);/连接起点,闭合路径 context.closePa

35、th();从上面的代码中可以看到,我们用到的仍然是前面用过的移动和画线命令,只不过调用次数多了一些。这些线条表现的是树冠的轮廓,最后我们闭合了路径。我们为这棵树的底部留出了足够的空间,后面几节将在这里的空白处画上树干。代码清单 2-9 演示如何使用树冠绘制函数将树的简单轮廓呈现到canvas上。代码清单 2-9 在canvas上画树的函数 function drawTrails()var canvas=document.getElementById(trails);var context=canvas.getContext(2d);context.save();context.translat

36、e(130,250);/创建表现树冠的路径 createCanopyPath(context);/绘制当前路径 context.stroke();context.restore();这段代码中所有的调用想必大家已经很熟悉了。先获取canvas的上下文对象,保存以便后续使用,将当前位置变换到新位置,画树冠,绘制到canvas上,最后恢复上下文的初始状态。2.2 使用 HTML5 Canvas API 37 1 2 3 4 6 9 11 7 5 8 10 图 2-6 展示了我们的绘画技艺,一条简单的闭合路径表现了树冠。以后我们会详细扩展这段代码,现在算是一个好的开始。图 2-6 表现树冠的简单路径

37、 2.2.5 描边样式 如果开发人员只能绘制直线,而且只能使用黑色,HTML5 Canvas API 就不会如此强大和流行。下面我们就使用描边样式让树冠看起来更像是树。代码清单 2-10 展示了一些基本命令,其功能是通过修改context的属性,让绘制的图形更好看。代码清单 2-10 使用描边样式/加宽线条 context.lineWidth=4;/平滑路径的接合点 context.lineJoin=round;/将颜色改成棕色 context.strokeStyle=#663300;/最后,绘制树冠 context.stroke();设置上面的这些属性可以改变以后将要绘制的图形外观,这个外观

38、起码可以保持到我们将38 第 2 章 Canvas API context恢复到上一个状态。首先,我们将线条宽度加粗到 4 像素。接着,我们将lineJoin属性设置为round,这是修改当前形状中线段的连接方式,让拐角 变 得 更 圆 滑;也 可 以 把lineJoin属 性 设 置 成bevel或 者miter(相 应 的context.miterLimit值也需要调整)来变换拐角样式。最后,通过strokeStyle属性改变了线条的颜色。在这个例子中,我们使用了 CSS 值来设置颜色,不过在后面几节中,我们将看到strokeStyle的值还可以用于生成特殊效果的图案或者渐变色。还有一个没

39、有用到的属性lineCap,可以把它的值设置为butt、square或者round,以此来指定线条末端的样式。哦,示例中的线是闭合的,没有端点。图 2-7 就是我们加工过的树冠,与之前扁平的黑线相比,现在是一条更粗、更平滑的棕色线条。图 2-7 为树冠应用了描边样式 2.2.6 填充样式 2.2 使用 HTML5 Canvas API 39 1 2 3 4 6 9 11 7 5 8 10 正如你所期望的那样,能影响canvas的图形外观的并非只有描边,另一个常用于修改图形的方法是指定如何填充其路径和子路径。从代码清单 2-11中可以看到,用宜人的绿色填充树冠有多么简单。代码清单 2-11 使用

40、填充样式/将填充色设置为绿色并填充树冠 context.fillStyle=#339900;context.fill();首先,我们将fillStyle属性设置成合适的颜色。(在后面,我们将看到还可以使用渐变色或者图案填充。)然后,只要调用context的fill函数就可以让canvas对当前图形中所有的闭合路径内部的像素点进行填充。结果如图 2-8 所示。图 2-8 填充后的树冠 由于我们是先描边后填充,因此填充会覆盖一部分描边路径。我们示例中的路径是 4 像素宽,这个宽度是沿路径线居中对齐的,而填充是把路径轮廓内部所有像素全部填充,所以会覆盖描边40 第 2 章 Canvas API 路径

41、的一半。如果希望看到完整的描边路径,可以在绘制路径(调用context.stroke())之前填充(调用context.fill())。2.2.7 填充矩形区域 每棵树都有一个强壮的树干。我们在原始图形中为树干预留了足够的空间。从代码清单 2-12中可以看到,通过fillRect函数可以画出树干。代码清单 2-12 调用fillRect函数/将填充色设为棕色 context.fillStyle=#663300;/填充用作树干的矩形区域 context.fillRect(-5,-50,10,50);在上面的代码中,再次将棕色作为填充颜色。不过跟上次不一样的是,我们不用lineTo功能显式画树干的

42、边角,而是使用fillRect一步到位画出整个树干。调用fillRect并设置 x、y 两个位置参数和宽度、高度两个大小参数,随后,Canvas 会马上使用当前的样式进行填充。虽然示例中没有用到,但与之相关的函数还有strokeRect和clearRect。strokeRect的作用是基于给出的位置和坐标画出矩形的轮廓,clearRect的作用是清除矩形区域内的所有内容并将它恢复到初始状态,即透明色。canvas动画“在 HTML5 Canvas API 中,canvas的清除矩形功能是创建动画和游戏的核心功能。通过反复绘制和清除canvas片段,就可能实现动画效果,互联网上有很多这样的例子。

43、但是,如果希2.2 使用 HTML5 Canvas API 41 1 2 3 4 6 9 11 7 5 8 10 望创建运行起来比较流畅的动画,就需要使用剪裁(clipping)功能了,有可能还需要二次缓存canvas,以便最小化由于频繁的清除动作而导致的画面闪烁。本书中不会专门讲解动画,我们鼓励大家自己探索学习。”Brain 图 2-9 显示的是基于树冠图形添加的、一次填充的树干。图 2-9 带有矩形树干的树 2.2.8 绘制曲线 这个世界,特别是自然界,并不是只有直线和矩形。canvas提供了一系列绘制曲线的函数。我们将用最简单的曲线函数二次曲线,来绘制我们的林荫小路。代码清单 2-13

44、演示了如何添加两条二次曲线。剪裁(clipping):本节没有介绍剪裁功能,此功能常用于创建动画,作者本意是希望读者能够自己探索相关的知识领域。译者注 Brain,本书的作者之一。译者注 42 第 2 章 Canvas API 代码清单 2-13 绘制曲线/保存 canvas 的状态并绘制路径 context.save();context.translate(-10,350);context.beginPath();/第一条曲线向右上方弯曲 context.moveTo(0,0);context.quadraticCurveTo(170,-50,260,-190);/第二条曲线向右下方弯曲 c

45、ontext.quadraticCurveTo(310,-250,410,-250);/使用棕色的粗线条来绘制路径 context.strokeStyle=#663300;context.lineWidth=20;context.stroke();/恢复之前的 canvas 状态 context.restore();跟以前一样,第一步要做的事情是保存当前canvas的context状态,因为我们即将变换坐标系并修改轮廓设置。要画林荫小路,首先要把坐标恢复到修正层的原点,向右上角画一条曲线。从图 2-10 中可以看到,quadraticCurveTo函数绘制曲线的起点是当前坐标,带有两组(x,y

46、)参数。第二组是指曲线的终点。第一组代表控制点(control point)。所谓的控制点位于曲线的旁边(不是曲线之上),其作用相当于对曲线产生一个拉力。通过调整控制点的位置,就可以改变曲线的曲率。在右上方再画一条一样的曲线,以形成一条路。然后,像之前描边树冠一样把这条路绘制到canvas上(只是线条更粗了)。HTML5 Canvas API 的其他曲线功能还涉及bezierCurveTo、arcTo和arc函数。这些函2.2 使用 HTML5 Canvas API 43 1 2 3 4 6 9 11 7 5 8 10 数通过多种控制点(如半径、角度等)让曲线更具可塑性。图 2-11 显示了绘

47、制在canvas上的两条曲线,看起来就像是穿过树林的小路一样。图 2-10 曲线的起点、终点和控制点 图 2-11 组成小路的曲线 2.2.9 在canvas中插入图片 在canvas中显示图片非常简单。可以通过修正层为图片添加印章、拉伸图片或者修改图片等,并且图片通常会成为canvas上的焦点。用 HTML5 Canvas API内置的几个简单命令可以轻松地为canvas添加图片内容。不过,图片增加了canvas操作的复杂度:必须等到图片完全加载后才能对其进行操作。浏览器通常会在页面脚本执行的同时异步加载图片。如果试图在图片未完全加载之前就将其呈现到canvas上,那么canvas将不会显示

48、任何图片。因此,开发人员要特别注意,在呈现之前,应确保图片已经加载完毕。我们的示例将加载一张树皮纹理的图片作为树干以供canvas使用。为保证在呈现之前图片控制点 终点 起点 44 第 2 章 Canvas API 已完全加载,我们提供了回调,即仅当图像加载完成时才执行后续代码,如代码清单 2-14 所示。代码清单 2-14 加载图像/加载图片 bark.jpg var bark=new Image();bark.src=bark.jpg;/图片加载完成后,将其显示在 canvas 上 bark.onload=function()drawTrails();从上面的代码中可以看到,我们为 bar

49、k.jpg 图片添加了onload处理函数,以保证仅在图像加载完成时才调用主drawTrails函数。这样做可以保证后续的调用能够把图片正常显示出来,如代码清单 2-15 所示。代码清单 2-15 在canvas上显示图像/用背景图案填充作为树干的矩形 context.drawImage(bark,-5,-50,10,50);在这段代码里,我们用纹理贴图替换了之前调用fillRect函数的填充来作为新的树干。尽管替换的动作很小,但canvas上显示出来的树干更有质感。注意,在drawImage函数中,除了图片本身外,还指定了x、y、width和height参数。这些参数会对贴图进行调整以适应预

50、定的1050 像素树干区域。我们还可以把原图的尺寸传进来,以便在裁切区域内对图片进行更多控制。在图 2-12 中可以看到,同之前用矩形填充的方式相比,树干的变化不大。图 2-12 使用了树干贴图的树 2.2 使用 HTML5 Canvas API 45 1 2 3 4 6 9 11 7 5 8 10 2.2.10 渐变 对树干还是不满意?其实我也是。我们使用另一种可以让树干变得稍微好看点的绘制方法:渐变。渐变是指在颜色集上使用逐步抽样算法,并将结果应用于描边样式和填充样式中。使用渐变需要三个步骤:(1)创建渐变对象;(2)为渐变对象设置颜色,指明过渡方式;(3)在context上为填充样式或者

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁