2

假设我有一个 100 x 100 的矩形,我有一个 1000 x 1000 的画布。

只要矩形的 x 坐标不大于 999 且不小于 -100,就可以说在画布上可以看到矩形的某些部分。矩形的 y 坐标也是如此。

我想知道的是,如果矩形的 x 或 y 坐标设置为使矩形在画布上不可见,画布 api 的内部工作是否仍然绘制矩形或自动优化和实现就其本身而言,将不会看到将在画布上绘制的位图,因此它不会尝试绘制它。

4

3 回答 3

3

绘制到画布时,每次绘制都会检查边界。如果一个像素最终在画布之外,它会被剪裁(丢弃)。

如果不是,您将遇到内存损坏并很快崩溃。

Canvas 的设计非常安全,因此您不会让编写不佳的 Javascript(有意或无意)使您的浏览器崩溃。这同样适用于颜色值(例如直接使用位图数组)被限制在有效范围内的颜色。

优化取决于实现,但可以合理地假设如果该区域完全超出画布边界,则完全拒绝绘制操作。如果它部分在内部,它可以通过移动开始和结束光标来启动内部块复制,以表示将呈现可见的有效区域。

另一种选择是在渲染时检查每个像素,看它是在可见边界之内还是之外。然而,这不是最优的。

为了可视化,只考虑灰色区域,忽略浅蓝色:

帆布剪裁

(我没有展示所有可能性,但应该很容易想象底部等)

这里的光标是内部例程开始和停止循环像素的地方。在这种情况下,如果要绘制的区域是 100x100 像素并且在 -50, -50 (x,y) 处绘制,则内部光标设置为 +50, +50 相对于正在绘制的区域,宽度和高度为同样减少。

通过移动光标并调整宽度和高度,它不必遍历所有像素并因此优化副本(尽管说“所有像素”并不十分准确,因为数据不是按像素复制而是主要基于与内存对齐相关的块。有单独的算法处理优化的内存复制并考虑偏移字节(不在“干净”内存边界上开始或结束的字节)等等,即 4 或 8字节是一次性复制的,而不是一个和一个字节与掩码(与位)相结合)。

边界也适用于线和圆等。它们的有效绘图区域被处理为一个正方形区域,但是有不同的方法来绘制线条、圆形而不是正方形像素,以进一步优化。

参见 f.ex。Bresenham用于直线的算法或用于圆的中点圆算法或用于椭圆的各种算法- 我没有在每个浏览器中具体实现,但对于这些,您可以平方开始和结束坐标,并且在某些情况下(如圆形和椭圆) )您可能必须边走边检查(也许将圆圈分成四个部分并检查与逐个像素重叠边界的部分 - 虽然这是特定于实现的)。

当涉及到平移时,这仅仅是坐标的重新计算(平移、使用旋转矩阵的旋转和类似的东西)。然后根据边界检查新坐标。

话虽如此,但不确定浏览器是否有自己的特定实现。他们可能会尽可能使用系统的本机位图和剪辑功能。然而,上述相同也适用于这种情况。

于 2013-06-04T06:41:22.773 回答
1

FWIW,在 IE、Chrome 和 FF 上,对于 100,000 个矩形,完全离屏绘制(非绘制?)比在屏幕上绘制花费了大约 100 毫秒。

于 2013-06-01T23:42:26.290 回答
1

根据画布规范

“当目标矩形在目标图像(暂存位图)之外时,落在暂存位图之外的像素将被丢弃,就好像目标是一个无限的画布,其渲染被裁剪到暂存位图的尺寸。”

这不是绝对特定于您的问题,但很可能所有“画布外视图”操作都是以这种方式处理的。因此,基于此,我会说是的,它们是“优化的”

于 2013-06-04T04:21:52.213 回答