《JavaScript高级程序设计》Chapter 15 canvas + Chapter 16 HTML5

Chapter 15 Canvas

 

  • <canvas>元素:设定区域。JS动态在这个区域中绘制图形。
  • 苹果公司引导的。由几组API构成。
  • 2D上下文普及了。WebGL(3D上下文)还未足够普及。

基本用法

  • 首先:width、height属性确定绘图区域大小。后备信息放在开始和结束标签之间。
  • getContext():DOM获得这个canvas元素对象。再在这个对象上调用getContext()获取上下文,传入参数表示获取的是2d上下文还是WebGL上下文。
  • toDataURL()方法,获取绘图区域中的图形对应的URL。注意,若canvas画布“不干净”,即来自不同的域,这个方法会报错。

2D上下文

  • 绘制简单的2D图形。
  • 坐标原点在canvas元素的左上角,原点坐标(0,0)
  • 填充和描边:fillStyle和strokeStyle属性。
    • 描边宽度由lineWidth属性控制。
    • lineCap属性控制线条末端的形状
    • lineJoin属性控制线条相交的方式。
  • 绘制矩形:fillRect(),strokeRect()方法,clearRect()方法。4个参数:矩形的x,y坐标,矩形的宽度和高度。
  • 绘制路径:
    • 开始:beginPath()
    • 一系列绘制方法
    • 结束:closePath()/fill()/stroke()/clip()
    • 是否在路径上:isPointInPath()
  • 绘制文本:
    • fillText()/strokeText():4个属性:字符串、x、y坐标、可选的最大像素宽度
    • 3个属性:font、textAlign、textBaseline
    • 辅助确定文本大小:measureText()方法,返回TextMetrics对象,只有width属性。
  • 变换:
    • 例如rotate(angle)/scale()/translate()/transform()/setTransform
    • 记录状态:save()
    • 返回上一个状态:restore()
    • 记录和返回都是以栈结构的方式,可以一级级进入或者返回。
    • 记录和返回只作用于状态或者设置。
  • 绘制图像(对<img>或者<canvas>图像进行处理)
    • drawImage():多种控制方式
  • 阴影
  • 渐变:
    • createLinerGradient()/createRadiaGradient() ,addColorStop()
    • 注意坐标匹配。
  • 模式(重复的图像)createPattern()
  • 使用图像数据(获取rgba)
    • getImageData()获取原始图像数据,返回ImageData对象的实例。
    • 上述对象拥有width、height、data属性。
    • data属性是数组,每四位表示一个像素的数据,对应rgba
    • 可以依次设置灰阶过滤器或者其他过滤器。
    • putImageData()将图像数据绘制到画布上。
  • 合成:
    • globalAlpha属性:通用透明度
    • globalCompositionOperation属性:合成方式。存在浏览器差异。

WebGL

  • 类型化数组:视图--类型化视图。是WebGL项目的基础。
  • 上下文:pdf P488-497

 

Chapter 16 HTML5 脚本编程

  • HTML5增加了新标签,同时也花一定篇幅规定了一些JS的API,以简化复杂的操作。本章介绍了跨文档信息传递,拖放API,音频及视频,历史状态管理等一些操作。

跨文档消息传递(cross-document messaging:XDM)

  • 利用postMessage()进行消息传递,postMessage()方法不仅可以在这里使用,功能就是“向另一个地方传送数据”。而XDM中,“另一个地方”指另一个域,一般将消息传给当前页面的<iframe>元素或者由当前页面弹出的窗口。
  • 以当前页面的<iframe>元素包含另一个域为例:
  • 当前页面需要做的:
    • postMessage()传入两个参数:待传入的消息和消息的来源域---这就意味着实际上需要获得“另一个域”的window对象(代理)以在其上使用这个方法。见下个步骤。
    • 可以通过document.getElementById("myframe").contentWindow;即contentWindow属性获取目标域的window对象或者代理。调用该方法即可传入数据。
    • data不一定需要是字符串,但非字符串的情况在不同浏览器之间存在差异。可以利用JSON.stringify()/JSON.parse()处理字符串。
    • 这种方法可以确保安全性,毕竟第二个参数是已知地址。
  • <iframe>中的域需要做的:
    • 会激发message事件。onmessage处理程序的事件对象event有三个重要属性。
    • event的三个属性:data、origin、source
    • 可以在确保origin(来源所在域)符合条件的情况下,处理data,再通过source(指向来源的window对象的代理)向来源发送消息,即调用:event.source.postMessage().
    • 由于source只是可代理,所以能访问的属性和方法有限。建议只是用postMessage()方法。
  • 注意到postMessage()方法是在待向其传送消息的域的代理对象上调用的

原生拖放

  • 注意到,HTML5提供了一些JS的API,向程序员暴露可以使用的属性或者方法,它本身更多的是规定浏览器在这些方法或者属性(或者事件)响应的时候提供一些怎样的显示效果。
  • 拖放一般考虑3个阶段:被拖放的对象、拖放过程、放置的目标对象。
  • 对应一些拖放事件:对于被拖放的对象,有dragstart/drag/dragend;对于放置的目标对象,有dragenter/dragover/dragleave或drop。很好理解。
  • 自定义放置目标:针对有些元素默认是不允许作为放置目标的情况,由于默认是不允许,所以可以在dragenter和dragover中重写默认行为,即阻止默认行为的发生。以此来自定义放置目标。
  • dataTransfer对象,为了在拖放操作时实现数据交换,是event的属性,用于从被拖放的元素向放置目标元素传递字符串格式的数据。
    • setData()/getData()方法:设置和获取数据。getData()在drop事件中处理。注意在跨浏览器处理setData()的时候注意对短数据类型和MIME类型的处理。
    • dropEffect/effectAllowed:两者配合,可以确定被拖放的元素能够执行哪种放置行为(而浏览器会对应给出显示的效果)。dropEffect在ondragenter事件处理程序中针对放置目标进行设置。而effectAllowed属性在ondragstart中针对被拖放的目标进行设置。
    • 其他成员:addElement()/clearData()/setDragImage()/types等
  • draggable属性:HTML5中的全局属性,规定元素是否可以被拖动。

媒体元素

  • 针对HTML5中的<audio>和<video>元素。这两个元素的产生可以让我们减少使用FLASH插件等,更方便实现跨浏览器操作。
  • 元素本身就拥有一些属性,且可以进行多个MIME类型和编解码器的选择。
  • JS又规定了他俩的一些更加具体和详细的属性和事件,以减轻实现一些操作的繁琐的程序编写过程。
  • 可以依赖play()或pause()实现自定义的媒体播放器,这只是代码编写的逻辑问题,比较简单。
  • JS提供canPlayType()来检测编解码器的支持情况
    • 注意到可能性probably>maybe>空值
    • 所以传入MIME类型和编解码器的可能性大于只传入MIME类型的。很好理解。
  • JS有原生的Audio构造函数,可以穿件audio实例并进行一些操作。

历史状态管理

  • 针对“后退”和“前进”按钮失去作用,使得用户难以在不同的状态(页面状态)间进行切换。可以使用之前(13章)提到过的haschange事件监测状态的变化,以执行某些处理;或者使用HTML5中的历史状态管理API进行操作。
  • haschange事件:URL参数列表(包括#后的所有字符串)发生变动的时候触发,主要用在Ajax中,用URL参数数列来保存状态或者导航信息。属性oldURL、newURL可以实现location.hash的功能。一般使用后者,因为支持oldURL和newURL的浏览器不多
  • 状态管理API同样可以在不加载新页面的情况下改变浏览器的状态:history.pushState(),传入3个参数:状态对象,新状态标题和可选的URL,注意第二个参数至今不支持,所以可以写入空字符串,而第一个信息最好详尽的记录状态对象各方面的信息,以便随后只用。
  • 在执行完这个方法后,新的状态信息会被加入历史状态栈。并且不会真正的向服务器发送请求。
  • popstate事件:由于上述方法改变了历史栈,“后退”按钮可用了。在点击后退按钮的时候,触发popstate事件,其事件对象event包含pushState()第一个参数所指的状态对象(这就是为什么上面要求信息详尽的原因了)。注意到,浏览器加载第一个状态(页面)的时候,这个对象为null。
  • replaceState():传入参数与pushState()的一样,然而不会在历史状态栈中创建新状态,指挥重写当前状态。
  • 注意pushState()的第三个参数务必是实际的URL,不然刷新的时候会导致404错误。

 

posted @ 2017-11-09 18:48  nebulium  阅读(169)  评论(0编辑  收藏  举报