图形和动画已经日益成为浏览器中现代 Web 应用程序的必备功能,但实现起来仍然比较困难。

视 觉上复杂的功能要求性能调优和硬件加速,不能拖慢浏览器。

目前已经有一套日趋完善的 API 和工具可 以用来开发此类功能。

毋庸置疑,是 HTML5 最受欢迎的新特性。

这个元素会占据一块页面区域,让 JavaScript 可以动态在上面绘制图片。

最早是苹果公司提出并准备用在控制面板中的,随着其他浏览器 的迅速跟进,HTML5 将其纳入标准。

目前所有主流浏览器都在某种程度上支持元素。

与浏览器环境中的其他部分一样,自身提供了一些 API,但并非所有浏览器都支持这些 API,其中包括支持基础绘图能力的 2D 上下文和被称为 WebGL 的 3D 上下文。

支持的浏览器的最新版 本现在都支持 2D 上下文和 WebGL。

requestAnimationFrame

浏览器需要知道 CSS 过渡和动画应该什么时候开始,并据此计算出正确的时间间隔,到时间就去刷新用户界面。

新方法,用以通知浏览器某些 JavaScript 代码要执行动画了。这样浏览器就可以在运行某些代码后进 行适当的优化。

requestAnimationFrame()告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。

方法接收一个参数,此参数是一个要在重绘屏幕前调用的函数。

回调函数执行次数通常是每秒60次,但在大多数遵循W3C建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。

节流(触发事件间隔)

通过 requestAnimationFrame()递归地向队列 中加入回调函数,可以保证每次重绘最多只调用一次回调函数。

这是一个非常好的节流工具。在频繁执 行影响页面外观的代码时(比如滚动事件监听器),可以利用这个回调队列进行节流。

  1. let div1 = document.getElementById("myDiv");
  2. // 滚动时触发代码,会极其频繁触发,很快就触发上百次
  3. div1.addEventListener("mousemove",(event) => {console.log(123)})
  4. // 优化后:
  5. let enabled = true;
  6. function expensiveOperation() {
  7. console.log(123);
  8. }
  9. window.addEventListener('scroll', () => {
  10. if (enabled) {
  11. enabled = false;
  12. window.requestAnimationFrame(expensiveOperation);
  13. window.setTimeout(() => enabled = true, 500);
  14. }
  15. });

基本画布功能

创建元素时至少要设置其 width 和 height 属性,这样才能告诉浏览器在多大面积上绘 图。

备用数据

出现在开始和结束标签之间的内容是后备数据,会在浏览器不支持元素时显示。

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

上下文引用

  1. let drawing = document.getElementById("drawing");
  2. // 确保浏览器支持<canvas>
  3. if (drawing.getContext) {
  4. let context = drawing.getContext("2d");
  5. // 其他代码
  6. }

导出

要从画布上导出一张 PNG 格式的图片

  1. let drawing = document.getElementById("drawing");
  2. // 确保浏览器支持<canvas>
  3. if (drawing.getContext) {
  4. // 取得图像的数据 URI
  5. let imgURI = drawing.toDataURL("image/png");
  6. // 显示图片
  7. let image = document.createElement("img");
  8. image.src = imgURI;
  9. document.body.appendChild(image);
  10. }

如果画布中的图像是其他域绘制过来的,toDataURL()方法就会抛出错误。

2D绘制

2D 绘图上下文提供了绘制 2D 图形的方法,包括矩形、弧形和路径。

2D 上下文的坐标原点(0, 0)在

元素的左上角。

所有坐标值都相对于该点计算,因此 x 坐标向右增长,y 坐标向下增长。

默认 情况下,width 和 height 表示两个方向上像素的最大值。

填充 fillStyle 和 描边 strokeStyle

填充以指定样式(颜色、渐变或图像)自动填充形 状,而描边只为图形边界着色。

大多数 2D 上下文操作有填充和描边的变体,显示效果取决于两个属性: fillStyle 和 strokeStyle。

这两个属性可以是字符串、渐变对象或图案对象,默认值都为”#000000”。

字符串表示颜色值,可 以是 CSS 支持的任意格式:名称、十六进制代码、rgb、rgba、hsl 或 hsla。

  1. let drawing = document.getElementById("drawing");
  2. // 确保浏览器支持<canvas>
  3. if (drawing.getContext) {
  4. let context = drawing.getContext("2d");
  5. context.strokeStyle = "red"; // 描边
  6. context.fillStyle = "#0000ff"; // 填充
  7. }

所有与描边和填充相关的操作都会使用这两种样式,除非再次修改。

描边宽度由 lineWidth 属性控制,它可以是任意整数值。

lineCap 属性控 制线条端点的形状[”butt”(平头)、”round”(出圆头)或”square”(出方头)]

lineJoin 属性控制线条交点的形状[”round”(圆转)、”bevel”(取平)或”miter”(出尖)]

绘制矩形

矩形是唯一一个可以直接在 2D 绘图上下文中绘制的形状。

与绘制矩形相关的方法有 3 个:
fillRect():绘制填充了的矩形
strokeRect():绘制只有边框的矩形
clearRect():擦除画布中的某个矩形的区域

这些方法都接收 4 个参数:矩形 x 坐标、矩形 y 坐标、 矩形宽度和矩形高度。这几个参数的单位都是像素。

  1. let drawing = document.getElementById("drawing");
  2. // 确保浏览器支持<canvas>
  3. if (drawing.getContext) {
  4. let context = drawing.getContext("2d");
  5. /*
  6. * 引自 MDN 文档
  7. */
  8. // 绘制红色矩形
  9. context.fillStyle = "#ff0000";
  10. context.fillRect(10, 10, 50, 50);
  11. // 绘制半透明蓝色矩形
  12. context.fillStyle = "rgba(0,0,255,0.5)";
  13. context.fillRect(30, 30, 50, 50);
  14. }

矩形擦除

clearRect():擦除画布中的某个矩形的区域

  1. let drawing = document.getElementById("drawing");
  2. // 确保浏览器支持<canvas>
  3. if (drawing.getContext) {
  4. let context = drawing.getContext("2d");
  5. /*
  6. * 引自 MDN 文档
  7. */
  8. // 绘制红色矩形
  9. context.fillStyle = "#ff0000";
  10. context.fillRect(10, 10, 50, 50);
  11. // 绘制半透明蓝色矩形
  12. context.fillStyle = "rgba(0,0,255,0.5)";
  13. context.fillRect(30, 30, 50, 50);
  14. // 在前两个矩形重叠的区域擦除一个矩形区域
  15. context.clearRect(40, 40, 10, 10);
  16. }

image.png

绘制路径 / 圆

2D 绘图上下文支持很多在画布上绘制路径的方法。

通过路径可以创建复杂的形状和线条。

1、要绘制 路径,必须首先调用 beginPath()方法以表示要开始绘制新路径。

2、然后,再调用下列方法来绘制路径。

arc(x, y, radius, startAngle, endAngle, counterclockwise):以坐标(x, y)为圆 心,以 radius 为半径绘制一条弧线,起始角度为 startAngle,结束角度为 endAngle(都是 弧度)。最后一个参数 counterclockwise 表示是否逆时针计算起始角度和结束角度(默认为 顺时针)。

arcTo(x1, y1, x2, y2, radius):以给定半径 radius,经由(x1, y1)绘制一条从上一点 到(x2, y2)的弧线。

bezierCurveTo(c1x, c1y, c2x, c2y, x, y):以(c1x, c1y)和(c2x, c2y)为控制点, 绘制一条从上一点到(x, y)的弧线(三次贝塞尔曲线)。

lineTo(x, y):绘制一条从上一点到(x, y)的直线。

moveTo(x, y):不绘制线条,只把绘制光标移动到(x, y)。

quadraticCurveTo(cx, cy, x, y):以(cx, cy)为控制点,绘制一条从上一点到(x, y) 的弧线(二次贝塞尔曲线)。

rect(x, y, width, height):以给定宽度和高度在坐标点(x, y)绘制一个矩形。这个方法 与 strokeRect()和 fillRect()的区别在于,它创建的是一条路径,而不是独立的图形。

3、最后一步是调用 stroke() 画图

  1. let drawing = document.getElementById("drawing");
  2. // 确保浏览器支持<canvas>
  3. if (drawing.getContext) {
  4. let context = drawing.getContext("2d");
  5. // 1、创建路径
  6. context.beginPath();
  7. // 2、绘制
  8. // 绘制外圆
  9. context.arc(100, 100, 99, 0, 2 * Math.PI, false);
  10. // 绘制内圆
  11. context.moveTo(194, 100); // 而在绘制内圆之前,必须先把路径移动到内圆上的一点,以避免绘制出多余的线条。
  12. context.arc(100, 100, 94, 0, 2 * Math.PI, false);
  13. // 绘制分针
  14. context.moveTo(100, 100);
  15. context.lineTo(100, 15);
  16. // 绘制时针
  17. context.moveTo(100, 100);
  18. context.lineTo(35, 100);
  19. // 3、描画路径
  20. context.stroke();
  21. }

image.png

路径是 2D 上下文的主要绘制机制,为绘制结果提供了很多控制。因为路径经常被使用,所以也有 一个 isPointInPath()方法,接收 x 轴和 y 轴坐标作为参数。

这个方法用于确定指定的点是否在路径 上,可以在关闭路径前随时调用。

  1. if (context.isPointInPath(100, 100)) {
  2. alert("Point (100, 100) is in the path.");
  3. }

2D 上下文的路径 API 非常可靠,可用于创建涉及各种填充样式、描述样式等的复杂图像。

绘制文本

文本和图像混合也是常见的绘制需求,因此2D绘图上下文还提供了绘制文本的方法,即fillText() 和 strokeText()。

这两个方法都接收 4 个参数:要绘制的字符串、x 坐标、y 坐标和可选的最大像素 宽度。

而且,这两个方法最终绘制的结果都取决于以下 3 个属性。

1、font:以 CSS 语法指定的字体样式、大小、字体族等,比如”10px Arial”。

2、textAlign:指定文本的对齐方式,可能的值括”start”、”end”、”left”、”right”和 “center”。
推荐使用”start”和”end”,不使用”left”和”right”,因为前者无论在从左到右 书写的语言还是从右到左书写的语言中含义都更明确。

3、textBaseLine :指定文本的基线,可能的值包括 “top” 、 “hanging” 、 “middle” 、 “alphabetic”、”ideographic”和”bottom”。

这些属性都有相应的默认值,因此没必要每次绘制文本时都设置它们。

  1. // 正常
  2. context.font = "bold 14px Arial";
  3. context.textAlign = "center";
  4. context.textBaseline = "middle";
  5. context.fillText("12", 100, 20); // 模拟了在网页中渲染文本,用得最多
  6. // 与开头对齐
  7. context.textAlign = "start";
  8. context.fillText("12", 100, 40);
  9. // 与末尾对齐
  10. context.textAlign = "end";
  11. context.fillText("12", 100, 60);

image.png

由于绘制文本很复杂,特别是想把文本绘制到特定区域的时候,因此 2D 上下文提供了用于辅助确 定文本大小的 measureText()方法。

这个方法接收一个参数,即要绘制的文本,然后返回一个 TextMetrics 对象。

这个返回的对象目前只有一个属性 width。

measureText()方法使用 font、textAlign 和 textBaseline 属性当前的值计算绘制指定文本 后的大小。

  1. // 例如,假设要把文本"Hello world!"放到一个 140 像素宽的矩形中
  2. let fontSize = 100;
  3. context.font = fontSize + "px Arial";
  4. while(context.measureText("Hello world!").width > 140) {
  5. fontSize--;
  6. context.font = fontSize + "px Arial";
  7. }
  8. context.fillText("Hello world!", 10, 10);
  9. context.fillText("Font size is " + fontSize + "px", 10, 50);

fillText()和 strokeText()方法还有第四个参数,即文本的最大宽度。

如果调用 fillText()和 strokeText()时提供了此参数,但要 绘制的字符串超出了最大宽度限制,则文本会以正确的字符高度绘制,这时字符会被水平压缩

变换

上下文变换可以操作绘制在画布上的图像。2D 绘图上下文支持所有常见的绘制变换。
 rotate(angle):围绕原点把图像旋转 angle 弧度。

 scale(scaleX, scaleY):通过在 x 轴乘以 scaleX、在 y 轴乘以 scaleY 来缩放图像。scaleX 和 scaleY 的默认值都是 1.0。

 translate(x, y):把原点移动到(x, y)。执行这个操作后,坐标(0, 0)就会变成(x, y)。

  1. // 移动原点到表盘中心
  2. context.translate(100, 100);
  3. // 绘制分针
  4. context.moveTo(0, 0);
  5. context.lineTo(0, -85);
  6. // 绘制时针
  7. context.moveTo(0, 0);
  8. context.lineTo(-65, 0);

 transform(m1_1, m1_2, m2_1, m2_2, dx, dy):像下面这样通过矩阵乘法直接修改矩阵。
m1_1 m1_2 dx
m2_1 m2_2 dy
0 0 1

 setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy):把矩阵重置为默认值,再以传入的 参数调用 transform()。

可以使用 rotate()方法来转动

  1. // 旋转表针
  2. context.rotate(1); // 1是角度,相当于1/π * 360°,也可以用45deg角度

恢复变换前 save & restore

所有这些变换,包括 fillStyle 和 strokeStyle 属性,会一直保留在上下文中,直到再次修改 它们。

虽然没有办法明确地将所有值都重置为默认值,但有两个方法可以帮我们跟踪变化。

如果想着什 么时候再回到当前的属性和变换状态,可以调用 save()方法。

调用这个方法后,所有这一时刻的设置 会被放到一个暂存栈中。保存之后,可以继续修改上下文。

而在需要恢复之前的上下文时,可以调用 restore()方法。

这个方法会从暂存栈中取出并恢复之前保存的设置。

多次调用 save()方法可以在暂 存栈中存储多套设置,然后通过 restore()可以系统地恢复。

  1. context.fillStyle = "#ff0000"; // 红色
  2. context.save();
  3. context.fillStyle = "#00ff00"; // 绿色
  4. context.translate(100, 100);
  5. context.save();
  6. context.fillStyle = "#0000ff"; // 蓝色
  7. context.fillRect(0, 0, 100, 200); // 在(100, 100)绘制蓝色矩形
  8. context.restore();
  9. context.fillRect(10, 10, 100, 200); // 在(100, 100)绘制绿色矩形
  10. context.restore();
  11. context.fillRect(0, 0, 100, 200); // 在(0, 0)绘制红色矩形

注意,save()方法只保存应用到绘图上下文的设置和变换,不保存绘图上下文的内容。

绘制图像 drawImage

2D 绘图上下文内置支持操作图像。如果想把现有图像绘制到画布上,可以使用 drawImage()方法。

这个方法可以接收 3 组不同的参数,并产生不同的结果。

最简单的调用是传入一个 HTML 的JS - 动画与Canvas 图形 - 图4元素, 以及表示绘制目标的 x 和 y 坐标,结果是把图像绘制到指定位置。

  1. let image = document.images[0]; // 获取了第一个图像
  2. context.drawImage(image, 10, 10); // 在画布上的坐标(10, 10)处将它绘制了出来,绘制出来的图像与原来的图像一样大。
  3. context.drawImage(image, 50, 10, 20, 30);// 图像会缩放到 20 像素宽、30 像素高
  4. // 还可以只把图像绘制到上下文中的一个区域。此时,需要给 drawImage()提供 9 个参数:
  5. // 要绘制的图像、源图像 x 坐标、源图像 y 坐标、源图像宽度、源图像高度、目标区域 x 坐标、目标区域 y 坐标、目标区域宽度和目标区域高度。
  6. context.drawImage(image, 0, 10, 50, 50, 0, 100, 40, 60);
  7. // 最终,原始图像中只有一部分会绘制到画布上。
  8. // 这一部分从(0, 10)开始,50 像素宽、50 像素高。而绘制到画布上时,会从(0, 100)开始,变成 40 像素宽、60 像素高。

image.png
第一个参数除了可以是 HTML 的JS - 动画与Canvas 图形 - 图6元素,还可以是另一个元素,这样就会把另一个 画布的内容绘制到当前画布上。

结合其他一些方法,drawImage()方法可以方便地实现常见的图像操作。

操作的结果可以使用 toDataURL()方法获取。

不过有一种情况例外:如果绘制的图像来自其他域而非当前页面,则不能获取 其数据。

此时,调用 toDataURL()将抛出错误。

比如,如果来自 www.example.com 的页面上绘制的是 来自 www.wrox.com 的图像,则上下文就是“脏的”,获取数据时会抛出错误。

阴影

2D 上下文可以根据以下属性的值自动为已有形状或路径生成阴影。

 shadowColor:CSS 颜色值,表示要绘制的阴影颜色,默认为黑色。

 shadowOffsetX:阴影相对于形状或路径的 x 坐标的偏移量,默认为 0。

 shadowOffsetY:阴影相对于形状或路径的 y 坐标的偏移量,默认为 0。

 shadowBlur:像素,表示阴影的模糊量。默认值为 0,表示不模糊。

这些属性都可以通过 context 对象读写。只要在绘制图形或路径前给这些属性设置好适当的值, 阴影就会自动生成。

  1. let context = drawing.getContext("2d");
  2. // 设置阴影
  3. context.shadowOffsetX = 5;
  4. context.shadowOffsetY = 5;
  5. context.shadowBlur = 4;
  6. context.shadowColor = "rgba(0, 0, 0, 0.5)";
  7. // 绘制红色矩形
  8. context.fillStyle = "#ff0000";
  9. context.fillRect(10, 10, 50, 50);
  10. // 绘制蓝色矩形
  11. context.fillStyle = "rgba(0,0,255,1)";
  12. context.fillRect(30, 30, 50, 50);

image.png

渐变

渐变通过 CanvasGradient 的实例表示,在 2D 上下文中创建和修改都非常简单。

线性渐变

要创建一个新的 线性渐变,可以调用上下文的 createLinearGradient()方法。

这个方法接收 4 个参数:起点 x 坐标、 起点 y 坐标、终点 x 坐标和终点 y 坐标。

调用之后,该方法会以指定大小创建一个新的 CanvasGradient 对象并返回实例。

有了 gradient 对象后,接下来要使用 addColorStop()方法为渐变指定色标。

这个方法接收两 个参数:色标位置和 CSS 颜色字符串。

色标位置通过 0~1 范围内的值表示,0 是第一种颜色,1 是最后 一种颜色。

  1. // 1、创建渐变方向
  2. let gradient = context.createLinearGradient(30, 30, 70, 70);
  3. // 2、为头尾指定颜色
  4. gradient.addColorStop(0, "white");
  5. gradient.addColorStop(1, "black");
  6. // 3、可以把这个对象赋给 fillStyle 或 strokeStyle 属性,从而以渐变填充或描画绘制的图形
  7. // 绘制红色矩形
  8. context.fillStyle = "#ff0000";
  9. context.fillRect(10, 10, 50, 50);
  10. // 绘制渐变矩形
  11. context.fillStyle = gradient;
  12. context.fillRect(30, 30, 50, 50);
  13. // 有时候可能需要写个函数计算相应的坐标,避免和形状不一致
  14. function createRectLinearGradient(context, x, y, width, height) {
  15. return context.createLinearGradient(x, y, x+width, y+height);
  16. }
  17. let gradient = createRectLinearGradient(context, 30, 30, 50, 50);
  18. gradient.addColorStop(0, "white");
  19. gradient.addColorStop(1, "black");
  20. // 绘制渐变矩形
  21. context.fillStyle = gradient;
  22. context.fillRect(30, 30, 50, 50);

image.png

径向渐变(反射渐变)

这个方法接收 6 个参 数,分别对应两个圆形圆心的坐标和半径。

前 3 个参数指定起点圆形中心的 x、y 坐标和半径,
后 3 个参 数指定终点圆形中心的 x、y 坐标和半径。

  1. // 1、创建渐变方向
  2. let gradient = context.createRadialGradient(55, 55, 10, 55, 55, 30);
  3. // 2、为头尾指定颜色
  4. gradient.addColorStop(0, "white");
  5. gradient.addColorStop(1, "black");
  6. // 3、可以把这个对象赋给 fillStyle 或 strokeStyle 属性,从而以渐变填充或描画绘制的图形
  7. // 绘制红色矩形
  8. context.fillStyle = "#ff0000";
  9. context.fillRect(10, 10, 50, 50);
  10. // 绘制渐变矩形
  11. context.fillStyle = gradient;
  12. context.fillRect(30, 30, 50, 50);

image.png

图案

图案是用于填充和描画图形的重复图像。

要创建新图案,可以调用 createPattern()方法并传入 两个参数:

第一个 HTML JS - 动画与Canvas 图形 - 图10元素和一个表示该如何重复图像的字符串,也可以是

元素或者另一个元素。第二个参数的值与 CSS 的 background-repeat 属性是一样的,包括”repeat”(重复、平铺)、”repeat-x”(横向重复)、”repeat-y”(纵向重复)和”no-repeat”(不重复)。

  1. let image = document.images[0],
  2. pattern = context.createPattern(image, "repeat");
  3. // 绘制矩形
  4. context.fillStyle = pattern;
  5. context.fillRect(10, 10, 150, 150);

image.png

图像数据

2D 上下文中比较强大的一种能力是可以使用 getImageData()方法获取原始图像数据。

这个方法 接收 4 个参数:要取得数据中第一个像素的左上角坐标和要取得的像素宽度及高度。

  1. // 要从(10, 5)开始取得 50 像素宽、50 像素高的区域对应的数据
  2. let imageData = context.getImageData(10, 5, 50, 50);

返回的对象是一个 ImageData 的实例。

每个 ImageData 对象都包含 3 个属性:width、height 和 data,其中,data 属性是包含图像的原始像素信息的数组。

每个像素在 data 数组中都由 4 个值表 示,分别代表红、绿、蓝和透明度值。

这个数组中的每个值都在 0~255 范围内(包括 0 和 255)。

只有在画布没有加载跨域内容时才可以获取图像数据。如果画布上绘制的是跨域内 容,则尝试获取图像数据会导致 JavaScript 报错。

合成

2D上下文中绘制的所有内容都会应用两个属性:globalAlpha 和 globalComposition Operation, 其中,globalAlpha 属性是一个范围在 0~1 的值(包括 0 和 1),用于指定所有绘制内容的透明度,默 认值为 0。

如果所有后来的绘制都需要使用同样的透明度,那么可以将 globalAlpha 设置为适当的值, 执行绘制,然后再把 globalAlpha 设置为 0。

  1. // 绘制红色矩形
  2. context.fillStyle = "#ff0000";
  3. context.fillRect(10, 10, 50, 50);
  4. // 修改全局透明度
  5. context.globalAlpha = 0.5;
  6. // 绘制蓝色矩形
  7. context.fillStyle = "rgba(0,0,255,1)";
  8. context.fillRect(30, 30, 50, 50);
  9. // 重置
  10. context.globalAlpha = 0;

image.png

globalCompositionOperation 属性表示新绘制的形状如何与上下文中已有的形状融合。

这个属 性是一个字符串,可以取下列值。

 source-over:默认值,新图形绘制在原有图形上面。
 source-in:新图形只绘制出与原有图形重叠的部分,画布上其余部分全部透明。
 source-out:新图形只绘制出不与原有图形重叠的部分,画布上其余部分全部透明。
 source-atop:新图形只绘制出与原有图形重叠的部分,原有图形不受影响。
 destination-over:新图形绘制在原有图形下面,重叠部分只有原图形透明像素下的部分可见。
 destination-in:新图形绘制在原有图形下面,画布上只剩下二者重叠的部分,其余部分完全 透明。
 destination-out:新图形与原有图形重叠的部分完全透明,原图形其余部分不受影响。
 destination-atop:新图形绘制在原有图形下面,原有图形与新图形不重叠的部分完全透明。
 lighter:新图形与原有图形重叠部分的像素值相加,使该部分变亮。
 copy:新图形将擦除并完全取代原有图形。
 xor:新图形与原有图形重叠部分的像素执行“异或”计算。

以上合成选项的含义很难用语言来表达清楚,只用黑白图像也体现不出所有合成的效果。

  1. // 绘制红色矩形
  2. context.fillStyle = "#ff0000";
  3. context.fillRect(10, 10, 50, 50);
  4. // 设置合成方式
  5. context.globalCompositeOperation = "destination-over"; // 新图形绘制在原有图形下面,重叠部分只有原图形透明像素下的部分可见。
  6. // 绘制蓝色矩形
  7. context.fillStyle = "rgba(0,0,255,1)";
  8. context.fillRect(30, 30, 50, 50);

image.png

WebGL (3D)

WebGL 是画布的 3D 上下文。

与其他 Web 技术不同,WebGL 不是 W3C 制定的标准,而是 Khronos Group 的标准。

Khronos Group 也制定了其他图形 API,包括作为浏 览器中 WebGL 基础的 OpenGL ES 2.0。

WebGL 支持比 2D 上下文更强大的绘图能力,包括:
 用 OpenGL 着色器语言(GLSL)编写顶点和片段着色器;
 支持定型数组,限定数组中包含数值的类型;
 创建和操作纹理。