JS第十五章学习

213 阅读12分钟

Canvas 绘图

使用的条件

设置width和height属性,指定可以绘图的区域大小

<canvas id="drawing" width=" 200" height="200">A drawing of something

</canvas> 后备信息仅当浏览器不支持canvas元素时候出现

可以通过CSS为该元素添加样式,如果不添加任何样式或者不绘制任何图形,在页面上是无法显示元素

画图前需要取得绘画上下文;取得上下文的引用,需要调用getContext()方法,并且传入上下文的名字。

var drawing = document.getElementById("drawing"); 
//确定浏览器支持<canvas>元素
 if (drawing.getContext){ 
var context = drawing.getContext("2d"); 
}

使用 toDataURL()方法,可以导出在<canvas>元素上绘制的图像;该方法接受一个参数,即图像的MIME类型格式(类似png)

2D上下文

2D上下文的 坐标开始于<canvas>元素的左上角,原点坐标是(0,0)

填充和描边

填充,就是用指定的样式(颜色、渐变或图像)填 充图形

描边,就是只在图形的边缘画线。

两个属性:fillStyle 和 strokeStyle

两个属性的值可以是字符串、渐变对象或模式对象,而且它们的默认值都是"#000000"

绘制矩形

与矩形有关的方法包括 fillRect()、 strokeRect()和 clearRect()。这三个方法都能接收 4个参数:矩形的 x坐标、矩形的 y坐标、矩形 宽度和矩形高度

fillRect()方法在画布上绘制的矩形会填充指定的颜色

strokeRect()方法在画布上绘制的矩形会使用指定的颜色描边

描边线条的宽度由 lineWidth 属性控制,该属性的值可以是任意整数

lineCap 属性可以控制线条末端的形状是平头、圆头还是方头("butt"、 "round"或"square")

lineJoin 属性可以控制线条相交的方式是圆交、斜 交还是斜接("round"、"bevel"或"miter")

clearRect()方法用于清除画布上的矩形区域

绘制路径

通过路径可以创造出复 杂的形状和线条。要绘制路径,首先必须调用 beginPath()方法,表示要开始 绘制新路径

调用方法实际地绘制路径

绘制一条连接到路径起点的线条

调用 closePath()

调用 fill()方法进行填充

调用 stroke()方法对路径描边,描边使用的是 strokeStyle。后还可以调用 clip(),这个方法 可以在路径上创建一个剪切区域

绘制文本

绘制文本的方法:fillText()和 strokeText()

接受的参数:要绘制的文本字符串、x 坐 标、y坐标和可选的大像素宽度

属性

为了把文本控制在某一区域中的时候,2D上下文提供辅助确定文本大小的方法 measureText()

变换

修改变换矩阵的方法

绘制图像

把一幅图像绘制到画布上,使用 drawImage() 方法

使用三种不同的参数组合

传入一个HTML<img>元素,绘制图像起点的x,y坐标

按照原图的图像大小进行放置(改变图片的大小,传入多两个:目标宽度和目标高度)

传入一个<canvas>元素,其余与上相同

结合使用 drawImage()和其他方法,可以对图像进行各种基本操作。而操作的结果可以通过 toDataURL()方法获得

阴影

不同浏览器对阴影的支持有一些差异。IE9、Firefox 4和 Opera 11的行为 为规范,其他浏览器多多少少会有一些奇怪的现象,甚至根本不支持阴影。 Chrome(直至第 10 版)不能正确地为描边的形状应用实心阴影。Chrome 和 Safari(直至第 5 版)在为带透明像素的图像应用阴影时也会有问题:不透明 部分的下方本来是该有阴影的,但此时则一概不见了。Safari 也不能给渐变图 形应用阴影,其他浏览器都可以

渐变

渐变由 CanvasGradient 实例表示,很容易通过 2D上下文来创建和修改

新建一个线性渐变,调用createLinearGradient()方法

接受四个参数:起点的X坐标,起点的Y坐标,终点的X坐标,终点的Y坐标

使用 addColorStop()方法来指定色标

接收两个参数: 色标位置和 CSS颜色值。色标位置是一个 0(开始的颜色)到 1(结束的颜色)之间的数字

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

接收 6个参 数,对应着两个圆的圆心和半径。前三个参数指定的是起点圆的原心(x 和 y)及半径,后三个参数指 定的是终点圆的原心(x 和 y)及半径

模式

重复的图像,可以用来填充或描边图形

调用 createPattern()方法

传入两个参数:一个 HTML <img>元素和一个表示如何重复图像的字符串。 其中,第二个参数的值与 CSS的 background-repeat 属性值相同,包括"repeat"、"repeat-x"、 "repeat-y"和"no-repeat"

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

使用图像数据

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

接收4个参数:要取得其数据的画面区域的 x和 y坐标以及该区域的像素宽度和高度

返回一个ImageData对象实例

ImageData 对象都有三个属性:width、height 和 data。其中 data 属性是一个数组,保存着图像中每一个像素的数据

只有在画布“干净”的情况下(即图像并非来自其他域),才可以取得图像数据。 如果画布“不干净”,那么访问图像数据时会导致 JavaScript错误

合成

所有绘制操作的属性:globalAlpha 和 globalComposition- Operation

globalAlpha 是一个介于 0和 1之间的值(包括 0和 1),用于指定所有绘制的透 明度。默认值为 0

如果所有后续操作都要基于相同的透明度,就可以先把 globalAlpha 设置为适当 值,然后绘制,后再把它设置回默认值 0

globalCompositionOperation 表示后绘制的图形怎样与先绘制的图形结合。这个 属性的值是字符串

WebGL

类型化数组

本质还是数组,元素设置为c特定类型的值

核心是一个名为 ArrayBuffer 的类型,通过 ArrayBuffer 为了将来使用而分配一定数量的字节

视图

使用 ArrayBuffer用来创建数组缓冲器视图

常见的视图:DataView

可以选择 ArrayBuffer 中一小段字节。为此,可以在创建 DataView 实例的时候传入一个 ArrayBuffer、一个可选的字节偏移量(从该字节开始选择)和一个可选的要选 择的字节数

实例化之后,DataView 对象会把字节偏移量以及字节长度信息分别保存在 byteOffset 和 byteLength 属性中

通过其 buffer 属性可以取得数组缓冲器

DataView 支持的数据类型以及相应的读写方法

所有这些方法的第一个参数都是一个字节偏移量,表示要从哪个字节开始读取或写入

类型化视图

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

每种视图类型都以不同的方式表示数据,而同一数据视选择的类型不同有可能占用一或多字节

这些视图都继承自 DataView,因而可以使用相同的构造函数参数来实例化。第一个参数是要 使用 ArrayBuffer 对象,第二个参数是作为起点的字节偏移量(默认为 0),第三个参数是要包含的字 节数。三个参数中只有第一个是必需的

类型化视图的目的在于简化对二进制数据的操作

使用类型化视图时,可以通过方括号语法访问每一个数据成员,可以通过 length 属性确定数组中 有多少元素

可以使用方括号语法为类型化视图的元素赋值

注意:数据类型不匹配时不会抛出错误

类型化视图还有一个方法,即 subarray(),使用这个方法可以基于底层数组缓冲器的子集创建一 个新视图。这个方法接收两个参数:开始元素的索引和可选的结束元素的索引。返回的类型与调用该方 法的视图类型相同

WebGL上下文

WebGL 的名字叫"experimental-webgl"

如果浏览器不支持 WebGL, 那么取得该上下文时会返回 null。在使用 WebGL上下文时,务必先检测一下返回值

通过给 getContext()传递第二个参数,可以为 WebGL上下文设置一些选项

如果 getContext()无法创建 WebGL上下文,有的浏览器会抛出错误。为此,好把调用封装到 一个 try-catch 块中

常量

在 WebGL 中,保存在上下文对象中的这些常量都没有 GL_前缀(OpenGL的前缀)

方法命名

OpenGL(以及 WebGL)中的很多方法都试图通过名字传达有关数据类型的信息

准备绘图

使用 clearColor()方法来指定要使用的颜色值,该方法接收 4个参数:红、绿、蓝和透明度。 每个参数必须是一个 0到 1之间的数值,表示每种分量在终颜色中的强度

视口与坐标

视口可以使用整个<canvas> 区域。要改变视口大小,可以调用 viewport()方法并传入 4个参数:(视口相对于<canvas>元素的) x坐标、y坐标、宽度和高度

视口坐标的原点(0,0)在<canvas>元素的左下角,x 轴和 y轴的正方向分别是向右和向上,可以定义为(width-1, height-1)

缓冲区

创建缓冲区调用 gl.createBuffer(),然后使用 gl.bindBuffer()绑定到 WebGL 上下文

gl.bufferData()的后一个参数用于指定使用缓冲区的方式

错误

WebGL 操作一般不会抛出错误,手工调用 gl.getError()方法。这个方法返回一个 表示错误类型的常量

着色器

着色器(shader)是 OpenGL中的另一个概念

WebGL中有两种着色器:顶点着色器和片段(或像 素)着色器。顶点着色器用于将 3D 顶点转换为需要渲染的 2D 点。片段着色器用于准确计算要绘制的每个像素的颜色

编写着色器

GLSL是一种类 C语言,专门用于编写 OpenGL着色器

每个着色器都有一个 main()方法,该方法在绘图期间会重复执行

为着色器传递数据的方式有两 种:Attribute和 Uniform。通过 Attribute可以向顶点着色器中传入顶点信息,通过 Uniform可以向任何 着色器传入常量值

Attribute 和 Uniform 在 main()方法外部定义,分别使用关键字 attribute 和 uniform。在这两个值类型关键字之后,是数据类型和变量名

编写着色器程序

浏览器不能理解 GLSL程序,因此必须准备好字符串形式的 GLSL程序

需要先取得GLSL字符串才能进行创建着色器对象

创建着色器对象,可以调用 gl.create- Shader()方法并传入要创建的着色器类型(gl.VERTEX_SHADER 或 gl.FRAGMENT_SHADER)

为着色器传入值

着色器都必须接收一个值才能工作

为了给着色器传入这个值,必须先找到要接收这个 值的变量

对于 Uniform变量,可以使用 gl.getUniformLocation(),这个方法返回一个对象,表示 Uniform变量在内存中的位置。然后可以基于变量的位置来赋值

调试着色器和程序

着色操作也可能失败,并且是静默失败

对于着色器,可以在操作之后调用 gl.getShaderParameter(),取得着色器的编译状态

如果着色器编译成功,调用 gl.getShader- Parameter()会返回true。如果返回的是false,说明编译期间发生了错误,此时调用gl.getShader- InfoLog()并传入相应的着色器就可以取得错误消息

绘图

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

执行绘图操作要调用 gl.drawArrays()或 gl.drawElements()方法,前者用于 数组缓冲区,后者用于元素数组缓冲区

gl.drawArrays()或 gl.drawElements()的第一个参数都是一个常量,表示要绘制的形状

gl.drawArrays()方法接收上面列出的常量中的一个作为第一个参数,接收数组缓冲区中的起始 索引作为第二个参数,接收数组缓冲区中包含的顶点数(点的集合数)作为第三个参数

纹理

WebGL的纹理可以使用 DOM中的图像

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

读取像素

与 2D 上下文 类似,通过 WebGL 上下文也能读取像素值

读取像素值的方法 readPixels()与 OpenGL 中的同名方法只有一点不同,即后一个参数必须是类型化数组

readPixels()方法的参数有:x、y、宽度、高度、图像格式、数据类 型和类型化数组

限制

支持

Firefox 4+和 Chrome都实现了 WebGL API。Safari 5.1也实现了 WebGL,但默认是禁用的

WebGL 还是一个正在制定和发展中的规范。不管是函数名、函数签名,还是数据类 型,都有可能改变。可以说,WebGL目前只适合实验性地学习,不适合真正开发和应用