Canvas 调试
自2004年问世以来,Canvas 元素及其关联的 API 一直是网页上生成特定视觉效果的绝佳工具。随着 WebGL 等更多技术的出现,Canvas 的复杂性日益增加,对开发人员的要求也越来越高。多年来,调试 Canvas 问题需要添加 console.log
语句,甚至覆盖 Canvas 上下文的原型,以便更好地理解函数何时被调用。今天,我们很高兴地告诉您,我们在 Canvas 调试流程方面取得了改进,特别是在深入洞察每个操作的原因和效果,以及暴露先前不可见的内部信息方面。
Canvas 标签页
Web Inspector 现在有一个专用的 Canvas 标签页,用于调试 Canvas 上下文。这个新工具使得诊断 canvas 绘图代码中的性能和正确性问题变得更加容易,而无需手动对代码进行插桩。本文的其余部分将解释这些新功能。
可视化 Canvas
Canvas 标签页概览显示所有活动的 canvas 上下文,列出了每个 canvas 的绘图上下文类型、预览图像、尺寸和当前内存使用情况。

在任何时候,点击“卡片”或 Canvas 标签页右上角的刷新按钮,都可以刷新预览图像,以便您随时了解页面上的内容。
点击任何 Canvas 将“向下钻取”到一个更具体的视图,在那里可以查看和编辑任何附加对象,例如着色器程序。

录制和重放 Canvas
Canvas 调试计划的一个重要部分是提供一种接近原生的方式来探索 Canvas 究竟发生了什么。调试绘图代码通常很困难,因为它大部分发生在幕后,只有少数操作会真正引起(如果发生)绘图变化。现在,2D 和 WebGL canvas 可以根据需要逐个动作地进行录制和可视化,以调试任何问题。点击 canvas 预览旁边(概览)或左侧边栏(特定 canvas)的红色圆圈即可开始录制。当您重现了想要调试的行为时,再次点击该按钮即可停止录制。也可以通过按住 Shift 键点击来录制单帧。经过一些处理后,录制内容将可供检查。

录制视图显示所有命令的列表(左侧边栏)、当前状态和回溯信息(右侧边栏),以及截至所选命令的当前输出(中心)。点击任何动作将应用该动作及其之前的所有内容到预览中,生成与实际页面中查看的结果相同。移动滑块可以快速跳转到“视觉”动作之间(在左侧边栏高亮显示),这些动作是可以导致生成内容发生可见变化的。
调试 2D 路径
在 2D Canvas 世界中,存在一个名为“路径”的概念。打个比方,想象一下画家在实际绘画之前用铅笔勾勒出笔触。对于 2D Canvas,这个“路径”就是这根铅笔线条,可以用来一次性绘制更富有表现力的形状。通常,就像铅笔一样,这条路径在实际绘制/描画之前是不可见的。如果开发人员不小心输入了错误的值,这可能会导致意想不到的结果。

虚线表示任何“移动”命令。最新的路径动作以红色绘制。
导出和导入
我们在构建 Canvas 录制时预见到的一个问题是,录制的质量取决于它能捕捉到的内容。如果开发人员在他们的电脑上遇到 bug,但他们的同事没有这个问题,那么录制有 bug 的 Canvas 就没有实际好处,特别是如果他们不知道代码是如何工作的。我们的解决方案是通过允许将任何录制导出到 JSON 文件并导入到任何其他电脑,使 Canvas 录制完全可移植。
所有录制信息都编码到 JSON 文件中,因此将其加载到任何其他电脑都会提供与源电脑完全相同的重放精度。然而,为了最小化 Canvas 录制的大小,值被去重,重复的键被移除,取而代之的是更紧凑的数组。根据我们的粗略估计,这使得平均 JSON 大小减少了约 30%。
着色器程序编辑器
对于更高级的 Canvas 用法,例如 WebGL,大部分工作通常是在着色器中完成的。在这种情况下,录制 Canvas 可能不足以确定潜在问题的原因,因为它可能是由于 Canvas 使用的某个着色器中存在错误。为了方便这一点,我们已经暴露了所选 Canvas 的所有有效着色器程序。
着色器程序的原始源代码在分割视图中显示顶点和片段着色器。每个着色器都可以编辑,并且会对检查的页面产生立竿见影的效果。
这样,无需编辑页面源代码或进行额外的录制即可解决 bug。
演练场
作为使用 Canvas 录制进行调试的简单演示,此页面是上面截图中显示的页面。它大量使用了 canvas 2D 路径,通常超出 canvas 的边界。这是一个很好的优化时机示例,因为没有理由在可见空间之外绘制任何东西。借助 Canvas 录制,这个问题非常明显,并且提供了足够的信息来采取行动进行修复。
反馈
Canvas 标签页在 macOS High Sierra 10.13.4 和 macOS Mojave 中可用。您是否经常调试本文未涵盖的 Canvas API?请告诉我们!欢迎通过 Twitter(@dcrousso 或 @jonathandavis)向我们发送反馈,或提交 bug。