JS笔记:15、16、17章 Canvas、HTML5编程、错误处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012755393/article/details/80019982


15 使用Canvas绘图

不用说,HTML5添加的最受欢迎的功能就是<canvas>元素。这个元素负责在页面中设定一个区域,然后就可以通过JavaScript动态地在这个区域中绘制图形。

除了具备基本绘图能力的2D上下文,<canvas>还建议了一个名为WebGL3D上下文。


基本用法:

<canvas id=drawing width=200 height=200>a drawing of something.</canvas>

如果不添加任何样式或者不绘制任何图形,在页面中是看不到该元素的。

要在这块画布上绘图,需要取得绘图上下文。

Var drawing = document.getElementById(“drawing”);

if(drawing.getContext){ var context = drawing.getContext(“2d”);}

使用toDataURL()方法,可以导出在<canvas>元素上绘制的图像。


2D上下文:

使用2D绘图上下文提供的方法,可以绘制简单的2D图形,比如矩形、弧线和路径。

1)填充和描边

2D上下文的两种基本绘图操作是填充和描边。

操作的结果取决于两个属性:fillStylestrokeStyle,这两个属性的值可以是字符串、渐变对象或模式对象,而且它们的默认值都是“#000000“。

2)绘制矩形

矩形是唯一一种可以直接在2D上下文中绘制的形状。与矩形有关的方法包括fillRect()、strokeRect()和clearRect()。都接收4个参数:矩形的x坐标、y坐标、宽度、高度。

3)绘制路径

2D绘制上下文支持很多在画布上绘制路径的方法。通过路径可以创造出复杂的形状和线条。要绘制路径首先必须调用beginPath()方法,表示要开始绘制新路径。然后用下列方法来实际绘制路径:

Arc():绘制弧线;

arcTo():从上一点开始绘制一条弧线;

bezierCurveTo():从上一点开始绘制一条曲线;

lineTo(x,y):从上一点开始绘制一条直线,到(x,y)为止;

moveTo(x,y):将绘图游标移动到(x,y),不画线;

quadraticCurveTo:从上一点开始绘制一条二次曲线;

Rect(x,y):从点(x,y)开始绘制一个矩形;

4)绘制文本

绘制文本主要有两个方法:fillText()和strokeText()。这两个方法都可以接收4个参数:要绘制的文本字符串、x坐标、y坐标、文本的最大像素宽度(可选)。

5)变换

通过上下文的变换,可以把处理后的图像绘制到画布上。可以通过如下方法来修改变换矩阵:

Rotate(angle):围绕原点旋转图像angle弧度;

scale(scaleXscaleY):缩放图像;

translate(x,y):将坐标原点移动到(x,y);

transform:直接修改变换矩阵;

setTransform:将变换矩阵重置为默认状态后,再调用transform

可以调用save()方法,把当前的上下文设置保存进一个栈结构中,使用restore()方法进行出栈。

6)绘制图像

2D绘图上下文内置了对图像的支持,如果你想把一副图像绘制到画布上,可以使用drawImage()方法。

最简单的调用方式是传入一个HTML <img>元素,以及绘制该图像的起点的xy坐标。

除了给drawImage()方法传入HTML<img>元素外,还可以传入另一个<canvas>元素作为其第一个参数。

7)阴影

2D上下文会根据以下几个属性的值,自动为形状或路径绘制出阴影。

shadowColorshadowOffsetXshadowOffsetYshadowBlur

8)渐变

渐变由CanvasGradient实例表示,要创建一个新的线性渐变,可以调用createLinearGradient()方法。创建的gradient对象可以设置到fillStylestrokeStyle上。

要创建径向渐变(或放射渐变),可以使用createRadialGradient()方法。

9)模式

模式其实就是重复的图像,可以用来填充或描边图形。可以调用createPattern()方法并传入两个参数:一个HTML<img>元素和一个表示如何重复的字符串(和background-repeat属性值相同)。

将模式对象设置到fillStyle上。

createPattern()方法的第一个参数也可以是一个<video>元素,或另一个<canvas>元素。

10)使用图像数据

可以通过getImageData()取得原始图像数据。

11)合成

globalAlpha属性:是一个介于0-1之间的值,用于指定所有绘制的透明度。

globalCompositionOperation:表示后绘制的图形怎样与先绘制的图形结合。


WebGL

WebGL是针对Canvas3D上下文。浏览器中使用的WebGL就是基于OpenGL ES 2.0制定的。

1)类型化数组

类型化数组也是数组,只不过其元素被设置为特定类型的值。类型化数组的核心就是一个名为ArrayBuffer的类型,每个ArrayBuffer对象表示的只是内存中指定的字节数,但不会指定这些字节用于保存什么类型的数据。

Var buffer = new ArrayBuffer(20);

1.视图

使用ArrayBuffer(数组缓冲器类型)的一种特别的方式就是用它来创建数组缓冲器视图。最常见的视图是DataView,通过它可以选择ArrayBuffer中一小段字节。

虽然DataView能让我们在字节级别上读写数组缓冲器中的数据,但我们必须要记住要将数据保存到哪里,需要占用多少字节。这样就有很多工作量,因此类型化视图就应运而生。

2.类型化视图

类型化视图一般也被称为类型化数组,因为它们除了元素必须是某种特定的数据类型外,与常规的数组无异。

2WebGL上下文

drawing.getContext(“experimental-webgl”);取得了WebGL上下文之后,就可以开始3D绘图了。

1.常量

WebGL中,保存在上下文对象中的这些常量都没有GL前缀。

2.方法命名

方法名的后缀会包含参数个数(14)和接收的数据类型(f表示浮点数,i表示整数);也可以接收数组,包含字母v

3.准备绘图

绘图前,调用clearColor()方法来指定要使用的颜色值。

4.视口与坐标

要改变视口的大小,可以调用viewport()方法。

5.缓冲区

顶点信息保存在JavaScript的类型化数组中,使用之前必须转换到WebGL的缓冲区。要创建缓冲区,可以调用gl.createBuffer(),然后使用gl.bindBuffer()绑定到WebGL上下文。这两步做完之后,就可以用数据来填充缓冲区了。

不想要某个缓冲区了,可以调动gl.deleteBuffer(buffer);

6.错误

手工调用gl.getError()方法,输出错误常量。

7.着色器

WebGL中有两种着色器:顶点着色器和片段(或像素)着色器。

8.编写着色器

9.编写着色器程序

为便于使用,通常是把着色器包含在页面的<script>标签内,并为该标签指定一个自定义的type属性。由于无法识别type属性值,浏览器不会解析<script>标签中的内容。

复杂一些的WebGL应用可能会通过Ajax动态加载着色器。

取得了GLSL字符串之后,接下来就是创建着色器对象。可以调用gl.createShader()方法。

10.为着色器传入值

11.调试着色器和程序

调用gl.getShaderParameter()和gl.getShaderInfoLog()方法。

12.绘图

WebGL只能绘制三种形状:点、线和三角。其他所有形状都是由这三种基本形状合成之后,再绘制到三维空间中的。

13.纹理

WebGL的纹理可以使用DOM中的图像。要创建一个新纹理,可以调用gl.createTexture(),然后再将一幅图像绑定到该纹理。

图像、加载到<video>元素中的视频,甚至其他<canvas>元素都可以用作纹理。

14.读取像素

2D上下文类似,通过WebGL上下文也能读取像素值。读取像素值的方法readPixels()与OpenGL中的同名方法只有一点不同,即最后一个参数必须是类型化数组。

3)支持

某个浏览器的某个版本实现了它,并不一定意味着就真能使用它,某个浏览器支持WebGL,至少意味着两件事:首先,浏览器本身必须实现了WebgL API;其次,计算机必须升级显示驱动程序。



16 HTML5脚本编程

HTML5规范定义了很多新HTML标记,为了配合这些标记的变化,HTML5规范也用了显著篇幅定义了很多JavaScript API


跨文档消息传递:

跨文档消息传递(Cross Document Messaging),有时简称为XDM,指的是来自不同域的页面间传递消息。

XDM的核心是postMessage()方法,目的是:向另一个地方传递数据。对XDM而言,“另一个地方”指的是包含在当前页面中的<iframe>元素,或者由当前页面弹出的窗口。

接收两个参数:一条消息和一个表示消息接收方来自哪个域的字符串。

接收到XDM消息时,会触发window对象的message事件。传递给onmessage处理程序的事件对象包含以下三个方面的重要信息:

data:传入的数据;

origin:发送消息的文档所在的域;

Source:发送消息的文档的window对象的代理。

XDM已经作为一个规范独立出来,现在它叫做Web Messaging


原生拖放:

最早在网页中引入JavaScript拖放功能的是IE4

1)拖放事件

有些事件是在被拖动的元素上触发的,而有些事件是在放置目标上触发的。

拖动某元素时,将依次触发下列事件:dragstartdragdragend。这三个事件的目标都是被拖动的元素。

当某个元素被拖动到一个有效的放置目标上时,下列事件会依次发生:dragenterdragoverdragleavedrop。这三个事件的目标是作为放置目标的元素。

2)自定义放置目标

如果拖动元素经过不允许放置的元素,无论用户如何操作,都不会发生drop事件。不过,你可以把任何元素变成有效的放置目标,方法是重写dragenterdragover事件的默认行为。

3dataTransfer对象

dataTransfer对象,它是事件对象的一个属性,用于从被拖动元素向放置目标传递字符串格式的数据。

4dropEffecteffectAllowed

dataTransfer对象还有两个属性:dropEffecteffectAllowed

dropEffect属性可以知道被拖动的元素能够执行哪种放置行为:nonemovecopylink;要使用该属性,必须在ondragenter事件处理程序中针对放置目标来设置它。

dragEffect属性只有搭配effectAllowed属性才有用。

effectAllowed属性表示允许拖动元素的哪种dropEffect,必须在ondragstart事件处理程序中设置。

5)可拖动

默认情况下,图像、链接和文本是可以拖动的。

HTML5为所有HTML元素规定了一个draggable属性,表示元素是否可以拖动。

6)其他成员

HTML5规范规定dataTransfer对象还应该包含下列方法和属性:addElement(element)、clearData(format)、setDragImage(element, x,y)、types


媒体元素:

HTML5新增了两个与媒体相关的标签:<audio><video>。这两个标签除了让开发人员方便地嵌入媒体文件之外,都提供了用于实现常用功能的Javascript API,允许为媒体创建自定义的控件。

使用这两个元素时,至少要在标签中包含src属性,还可以设置widthheight属性,而为poster属性指定图像的URI可以在加载视频内容期间显示一幅图像。另外,如果标签中有controls属性,则意味着浏览器应该显示UI控件,以便用户直接操作媒体。

1)属性

autoplaycontrolscurrentTimedurationendedlooppausedvolume等。

2)事件

这些事件监控着不同的属性的变化,这些变化可能是媒体播放的结果,也可能是用户操作播放器的结果。

abort:下载中断;

emptied:网络连接关闭;

ended:媒体已播放到末尾;

pause:播放已暂停;

Play:媒体已接收到指令开始播放;

Progress:正在下载;

TimeupdatecurrentTime被以不合理或意外的方式更新;

Volumechangevolume属性值或muted属性值已改变;

Waiting:播放暂停,等待下载更多数据;

3)自定义媒体播放器

使用<audio><video>元素的play()和pause()方法,可以手工控制媒体文件的播放。组合使用属性、事件和这两个方法,很容易创建一个自定义的媒体播放器。

4)检测编解码器的支持情况

这两个媒体元素都有一个canPlayType()方法,该方法接收一种格式/编解码器字符串,返回“probably“、“maybe”或“”。

5Audio类型

<audio>元素还有一个原生的JavaScript构造函数Audio,可以在任何时候播放音频。从同为DOM元素的角度看,AudioImage很相似,但Audio不用像Image那样必须插入到文档中。


历史状态管理:

通过hashchange事件,可以知道URL的参数什么时候发生了变化,即什么时候该有所反应。而通过状态管理API,能够在不加载新页面的情况下改变浏览器的URL。为此,需要使用history.pushState()方法,这个方法接收3个参数:状态对象、新状态标题、可选的相对URL

执行该方法后,新的状态信息就会被加入历史状态栈,而浏览器地址栏也会变成新的相对URL

按下浏览器“后退”按钮,会触发window对象的popstate事件。该事件对象有一个state属性,这个属性包含着当初以第一个参数传递给pushState()的状态对象。

要更新当前状态,可以调用replaceState(),传入的参数与pushState()的前两个参数相同。



17 错误处理与调试

浏览器报告的错误:

1.IE

IE是唯一一个在浏览器的界面窗体中显示JavaScript错误信息的浏览器。在发生JavaScript错误时,浏览器左下角会出现一个黄色的图标。

2.Firefox

3.Safari

4.Opera

5.Chrome


错误处理:

1try-catch语句

发生错误时,catch块会接收到一个包含错误信息的对象。与其他语言不同的是,即使你不想使用这个错误对象,也要给它起个名字。这个对象中包含的实际信息会因浏览器而异,但共同的是有一个保存着错误消息的message属性。ECMA-262还规定了一个保存错误类型的name属性。

1.finally子句

如果提供了finally子句,则catch子句就成了可选的。finally子句中的return会覆盖trycatch语句中的return语句。

2.错误类型

ECMA-262定义了7种错误类型:

Error:基类型,其他错误类型都继承自该类型;

EvalError:在使用eval()函数而发生异常时被抛出;

RangeError:在数值超出相应范围时触发;

ReferenceError:在找不到对象的情况下,访问不存在变量时,就会发生这种错误;

SyntaxError:当我们把语法错误的JavaScript字符串传入eval()函数时,就会导致此类错误;

TypeError:在变量中保存着意外的类型时,或者访问不存在的方法时,都会导致这种错误;

URIError:在使用encodeURI()或decodeURI(),而URI格式不正确时,就会导致URIError错误。

3.合理使用try-catch

比如在使用一个大型JavaScript库中的函数,该函数可能会有意无意地抛出一些错误。由于我们不能修改这个库的源代码,所以最好处理一下。

2)抛出错误

try-catch语句相配的还有一个throw操作符,用于随时抛出自定义错误。抛出错误时,必须要给throw操作符指定一个值,这个值是什么类型,没有要求。

在遇到throw操作符时,代码会立即停止执行。仅当有try-catch语句捕获到被抛出的值时,代码才会继续执行。

1.抛出错误的时机

Throw new Error(“process():Argument must be an array.”);

2.抛出错误与使用try-catch

3)错误(error)事件

任何没有通过try-catch处理的错误都会触发window对象的error事件。在任何Web浏览器中,onerror事件处理程序都不会创建event对象,但它可以接收三个参数:错误消息、错误所在的URL和行号。

Window.onerror = function(message, url, line){}

在上述事件处理程序中返回false,可以阻止浏览器报告错误的默认行为。

图像也支持error事件。只要图像的src特性中的URL不能反悔可以被识别的图像格式,就会触发error事件。

4)处理错误的策略

5)常见的错误类型

1.类型转换错误

2.数据类型错误

3.通信错误

第一种通信错误与格式不正确的URL或发送的数据有关。最常见的问题是在将数据发送给服务器之前,没有使用encodeURIComponent()对数据进行编码。

6)区分致命错误和非致命错误

7)把错误记录到服务器

使用Image对象来发送错误日志请求,这样做有几点好处:所有浏览器都支持Image对象,包括那些不支持XMLHttpRequest对象的浏览器;可以避免跨域限制;在记录错误的过程中出问题的概率较低,大多数ajax库可能会出问题。


调试技术:

1)将消息记录到控制台

2)将消息记录到当前页面

3)抛出错误


常见的IE错误:

1)操作终止

IE8之前的版本中,存在一个难于调试的错误:操作终止。

例如:Javascript代码在页面尚未加载完毕时就要修改document.body

准确一点说,当<script>节点被包含在某个元素中,而且JavaScript代码又要使用appendChild()、innerHTML或其他DOM方法修改该元素的父元素或祖先元素时,将会发生操作终止错误(因为只能修改已经加载完毕的元素)。

2)无效字符

3)未找到成员

IE中的所有DOM对象都是COM对象,而非原生JavaScript对象的形式实现的。

具体来说,如果在对象被销毁之后,又给对象赋值,就会导致未找到成员错误。而导致这个错误的,一定是COM对象。

4)未知运行时错误

当使用innerHTMLouterHTML以下列方式指定HTML时,就会发生未知运行时错误:一是把块级元素插入到行内元素时,二是访问表格任意部分的任意属性时。

5)语法错误

6)系统无法找到指定资源

在使用JavaScript请求某个资源URL,而该URL的长度超过了IEURL最长不能超过2083个字符的限制时,就会发生这个错误。IEURL路径还有一个不能超过2048个字符的限制。














阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页