setPixel: function(x, y, color){ var pxW, pxH; pxW = this.options.pixelWidth; pxH = this.options.pixelHeight; this.canvas.fillStyle = color.toString(); this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH); },
出于此原因,高性能图形(如光线跟踪器)作为 Canvas 方案落在谱表的最左端,如下图所示。
注意生成上述光线跟踪器的作者 注意 因为该方案将产生静态图像,所以桌面软件经过了很好的调整以适合光线跟踪器所需的大量浮动操作。
下至金属像素操作的有趣实现是图像的过滤器应用。过滤器已存在于 Web 上,且需要显著的处理速度(受益于其对图形管道中更深层的硬件加速图形的应用),因此开发人员可以试用边缘检测或其他数学表达式等算法。
实时数据对于更常见的方案,Canvas 非常适合输出实时数据。请注意如何简便地确定这些方案,因为已经表明使用 Canvas 难以进行用户交互。因此,下面将讨论非交互的实时数据可视化。
今天的天气数据可以通过特定间隔内服务器上生成的图像非常静态地呈现,也可以尽可能快地通过客户端第三方插件呈现。尽管 ECWMF 已经研究过使用 SVG 而不使用服务器生成的图像如何节省成本,但是 Canvas 在天气模式(以及其他快速的实时数据)的大多数图形表示形式方面,明显是赢家。下图显示以图形方式显示在地图上的天气模式。
如你可以从上图中看到的,没有必要存在大的绘图图面,而且屏幕上的对象数量是相当高的。通过使用 Canvas API,可以在不影响 DOM 的情况下快速绘制(和擦除)这些对象。尽管可以使用 SVG Ellipse 完成此操作,但是将它们加载到 DOM 中以及通过动画修改它们的成本是非常高的。事实上,无论你是在图像中还是在数据动画中看到大量的形状(尤其是不相似的形状)要进行分析,通常都会指出 Canvas 是要使用的技术。这里的实际限制是受 CPU 速度和 JavaScript 引擎速度的控制,能多快可视化显示数据。但除了占用 CPU 的光线跟踪方案之外,仍然可以实现合理的动画。Reasonable描述客户端可以使用 JavaScript 执行的操作与服务器可以通过电线计算和封送的操作之间的相对动画。
此方案似乎是
<canvas>
的关键用例。
另一个使用 Canvas 的可能情况是,在视频上进行颜色检测以便用其他场景或图像替换背景色。像光线跟踪器或过滤器一样,因 JavaScript 中当前性能速度限制的缘故,很可能会使用桌面软件预处理任何需要高的最终产品质量的现实方案。但是,由于 <canvas> 是为低级别像素读取和写入设计的,因此诸如greenscreen替换之类的方案甚至无法使用 SVG 完成。
从两个视频中读写像素到另一个视频中所需的代码要求使用两个视频、两个画布和一个最终画布。一次捕捉视频上的一帧,然后绘制到两个单独的画布上。这样允许读回数据。
JavaScript
ctxSource1.drawImage(video1, 0, 0, videoWidth, videoHeight); ctxSource2.drawImage(video2, 0, 0, videoWidth, videoHeight);
因此,下一步是检索每个绘制图像的句柄,以便你可以检查每个单独的像素。
JavaScript
currentFrameSource1 = ctxSource1.getImageData(0, 0, videoWidth, videoHeight); currentFrameSource2 = ctxSource2.getImageData(0, 0, videoWidth, videoHeight);
获取后,代码将浏览绿屏的像素数组,搜索绿色像素,如果找到,代码将用背景场景中的像素替换所有绿色像素。
JavaScript
for (var i = 0; i < n; i++) { // Grab the RBG for each pixel: r = currentFrameSource1.data[i * 4 + 0]; g = currentFrameSource1.data[i * 4 + 1]; b = currentFrameSource1.data[i * 4 + 2]; // If this seems like a green pixel replace it: if ( (r >= 0 && r <= 59) && (g >= 74 && g <= 144) && (b >= 0 && b <= 56) ) // Target green is (24, 109, 21), so look around those values. { pixelIndex = i * 4; currentFrameSource1.data[pixelIndex] = currentFrameSource2.data[pixelIndex]; currentFrameSource1.data[pixelIndex + 1] = currentFrameSource2.data[pixelIndex + 1]; currentFrameSource1.data[pixelIndex + 2] = currentFrameSource2.data[pixelIndex + 2]; currentFrameSource1.data[pixelIndex + 3] = currentFrameSource2.data[pixelIndex + 3]; } }
最后,像素数组将写入到目标画布中。
JavaScript
ctxDest.putImageData(currentFrameSource1, 0, 0);
(若要完整地查看 greenscreen 代码,请查看该页的源代码。)
以下方案可以在 SVG 或 Canvas 中完成,都可以获得适当的结果,但你可能会更喜欢一项技术胜过另一项技术。
图表和图形需要矢量图形的图表和图形的谱表很宽广。大部分这些图形最好使用 SVG 进行创建,因为它们具有下列三个特征之一:
我们使用可显著增加方案范围的交互功能来扩展高保真文档方案。 其中包括:
已经确定快速的实时数据处理已针对 Canvas 进行了更好地优化(主要取决于速度)。
二维游戏制作休闲游戏(此处定义为 Web 上的简单二维游戏)时,开发人员需要在 canvas 和 svg 之间做出选择。因为历史上游戏库一直利用较低级别的图形 API,所以将倾向于选择
<canvas>
。
当库的其他组成部分(如受欢迎的物理引擎)比图形层要明显深时,图形将变成实现细节。边框、速度、大小和位置等图形几何将传递给引擎,而引擎随后将用速度、碰撞和位置进行响应。图形位于堆栈中的最高层。
通过由同一作者开发的两个游戏来演示独立于游戏逻辑的图形概念,旨在说明
<svg>
和
<canvas>
:SVG-oids和canvas-pinball。一个出色的、独立于游戏引擎的图形层示例是将canvas-pinball与SVG-Dice进行比较(当两者都使用相同的物理引擎时)。
尽管游戏和演示逻辑是不同的,但是这两个游戏的物理引擎都会跟踪位置、碰撞、速度以及游戏组成部分的其他物理方面。
对于 canvas-pinball,自定义的更高级别的动画管理器通过使用一系列 Canvas API 重新绘制场景。
JavaScript