假设我有一个 100 x 100 的矩形,我有一个 1000 x 1000 的画布。
只要矩形的 x 坐标不大于 999 且不小于 -100,就可以说在画布上可以看到矩形的某些部分。矩形的 y 坐标也是如此。
我想知道的是,如果矩形的 x 或 y 坐标设置为使矩形在画布上不可见,画布 api 的内部工作是否仍然绘制矩形或自动优化和实现就其本身而言,将不会看到将在画布上绘制的位图,因此它不会尝试绘制它。
假设我有一个 100 x 100 的矩形,我有一个 1000 x 1000 的画布。
只要矩形的 x 坐标不大于 999 且不小于 -100,就可以说在画布上可以看到矩形的某些部分。矩形的 y 坐标也是如此。
我想知道的是,如果矩形的 x 或 y 坐标设置为使矩形在画布上不可见,画布 api 的内部工作是否仍然绘制矩形或自动优化和实现就其本身而言,将不会看到将在画布上绘制的位图,因此它不会尝试绘制它。
绘制到画布时,每次绘制都会检查边界。如果一个像素最终在画布之外,它会被剪裁(丢弃)。
如果不是,您将遇到内存损坏并很快崩溃。
Canvas 的设计非常安全,因此您不会让编写不佳的 Javascript(有意或无意)使您的浏览器崩溃。这同样适用于颜色值(例如直接使用位图数组)被限制在有效范围内的颜色。
优化取决于实现,但可以合理地假设如果该区域完全超出画布边界,则完全拒绝绘制操作。如果它部分在内部,它可以通过移动开始和结束光标来启动内部块复制,以表示将呈现可见的有效区域。
另一种选择是在渲染时检查每个像素,看它是在可见边界之内还是之外。然而,这不是最优的。
为了可视化,只考虑灰色区域,忽略浅蓝色:
(我没有展示所有可能性,但应该很容易想象底部等)
这里的光标是内部例程开始和停止循环像素的地方。在这种情况下,如果要绘制的区域是 100x100 像素并且在 -50, -50 (x,y) 处绘制,则内部光标设置为 +50, +50 相对于正在绘制的区域,宽度和高度为同样减少。
通过移动光标并调整宽度和高度,它不必遍历所有像素并因此优化副本(尽管说“所有像素”并不十分准确,因为数据不是按像素复制而是主要基于与内存对齐相关的块。有单独的算法处理优化的内存复制并考虑偏移字节(不在“干净”内存边界上开始或结束的字节)等等,即 4 或 8字节是一次性复制的,而不是一个和一个字节与掩码(与位)相结合)。
边界也适用于线和圆等。它们的有效绘图区域被处理为一个正方形区域,但是有不同的方法来绘制线条、圆形而不是正方形像素,以进一步优化。
参见 f.ex。Bresenham用于直线的算法或用于圆的中点圆算法或用于椭圆的各种算法- 我没有在每个浏览器中具体实现,但对于这些,您可以平方开始和结束坐标,并且在某些情况下(如圆形和椭圆) )您可能必须边走边检查(也许将圆圈分成四个部分并检查与逐个像素重叠边界的部分 - 虽然这是特定于实现的)。
当涉及到平移时,这仅仅是坐标的重新计算(平移、使用旋转矩阵的旋转和类似的东西)。然后根据边界检查新坐标。
话虽如此,但不确定浏览器是否有自己的特定实现。他们可能会尽可能使用系统的本机位图和剪辑功能。然而,上述相同也适用于这种情况。
FWIW,在 IE、Chrome 和 FF 上,对于 100,000 个矩形,完全离屏绘制(非绘制?)比在屏幕上绘制花费了大约 100 毫秒。
根据画布规范:
“当目标矩形在目标图像(暂存位图)之外时,落在暂存位图之外的像素将被丢弃,就好像目标是一个无限的画布,其渲染被裁剪到暂存位图的尺寸。”
这不是绝对特定于您的问题,但很可能所有“画布外视图”操作都是以这种方式处理的。因此,基于此,我会说是的,它们是“优化的”。