假设我有一个 100 x 100 的矩形和一个 1000 x 1000 的 Canvas 。
只要矩形的 x 坐标不大于 999 且不小于 -100,就可以确实在 Canvas 上看到矩形的某些部分。矩形的 y 坐标也是如此。
我想知道的是,如果设置了矩形的 x 或 y 坐标,使得矩形在 Canvas 上不可见,canvas api 的内部工作是否仍然绘制矩形或自动绘制矩形优化并自行实现,将在 Canvas 上绘制的位图将不会被看到,因此它不会尝试绘制它。
最佳答案
绘制到 Canvas 时,每次绘制都会检查边界。如果像素最终位于 Canvas 之外,则会被剪裁(丢弃)。
如果不这样做,你会出现内存损坏,并且很快就会崩溃。
Canvas 的设计非常安全,因此编写糟糕的 Javascript(有意或无意)不会导致浏览器崩溃。这同样适用于颜色值(例如直接使用位图数组)被限制在有效范围内的颜色。
优化取决于实现,但可以合理地假设,如果该区域完全超出 Canvas 的边界,则绘制操作将被完全拒绝。如果它部分位于内部,则可以通过移动开始和结束光标来表示将呈现可见的有效区域来启动内部 block 复制。
另一个选项是在渲染时检查每个像素是否位于可见边界之内或之外。但这并不是最佳选择。
为了可视化,仅考虑灰色区域,而忽略浅蓝色:
(我没有展示所有可能性,但应该很容易想象底部等。)
这里的光标是内部例程开始和停止循环像素的地方。在这种情况下,如果要绘制的区域为 100x100 像素并在 -50、-50 (x,y) 处绘制,则内部光标相对于正在绘制的区域设置为 +50、+50,宽度和高度为同样减少。
通过移动光标并调整宽度和高度,它不必遍历所有像素,从而优化复制(尽管,说“所有像素”不太准确,因为数据没有复制每个像素但主要基于与内存对齐相关的 block 。有单独的算法来处理优化的内存复制并考虑偏移字节(不在“干净”内存边界上开始或结束的字节)等等,即一次性复制 4 或 8 个字节,而不是结合屏蔽(与位)合并一个和一个字节。
边界也适用于直线和圆等。它们的有效绘图区域被处理为正方形区域,但有不同的方法来绘制线条、圆形而不是像素正方形,以进一步优化。
参见 f.ex。 Bresenham algorithm对于线路或 mid-point circle algorithm对于圆圈或 various algorithms对于省略号 - 我不知道每个浏览器中的具体实现,但是对于这些,您可以对起始坐标和结束坐标进行平方,在某些情况下(如圆形和椭圆形),您可能必须随时检查(可能在中绘制圆)四个部分,并检查在单个像素的基础上与边界重叠的部分 - 但这是特定于实现的)。
当涉及到平移时,这仅仅是重新计算坐标(使用 rotation matrixes 进行平移、旋转以及类似的东西)。然后根据边界检查新坐标。
话虽这么说,但不确定浏览器是否有自己的特定实现。在可能的情况下,他们可能会使用系统的 native 位图和剪辑功能。然而,上述内容也适用于这种情况。
关于Javascript Canvas 和内部功能的优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16875115/