【问题标题】:Canvas clipping region and the canvas stack画布剪辑区域和画布堆栈
【发布时间】:2016-05-13 14:36:55
【问题描述】:

我已经开始阅读 O'Reilly 的书“HTML5 Canvas”。我在第二章,其中一个示例提供的代码解释得不是很好。示例 2-5:

  1. 画一个黑盒子
  2. 推送状态
  3. 在左上角设置小剪辑区域
  4. 画圆
  5. 弹出状态
  6. 设置大的剪辑区域
  7. 再画一个圆圈

但我无法理解一些事情:

context.fillStyle = 'black';
context.fillRect(10, 10, 200, 200);

context.save();

context.beginPath();
context.rect(0, 0, 50, 50);
context.clip();

context.beginPath();
context.strokeStyle = 'red';
context.lineWidth = 5;
context.arc(100, 100, 100, 0, 2*Math.PI, false);
context.stroke();
context.closePath();

context.restore();

context.beginPath();
context.rect(0, 0, 500, 500);
context.clip();

context.beginPath();
context.strokeStyle = 'blue';
context.lineWidth = 5;
context.arc(100, 100, 50, 0, 2*Math.PI, false);
context.stroke();
context.closePath();

我的问题:

首先,context.clip() 是否隐式关闭上下文路径(“context.closePath()”)?它前面是一个 context.beginPath(),后面是另一个 context.beginPath()。像这样:

context.beginPath();
context.rect(0, 0, 50, 50);
context.clip();
context.beginPath();

第二,为什么要推送上下文状态?为什么我不能只更改剪辑区域?这似乎是必要的,因为不推动状态它是行不通的。如果我不推送状态然后恢复它,蓝色大圆圈不显示,我不明白为什么。

【问题讨论】:

  • beginPath 开始一个全新的路径并转储旧路径。 closePath 与 beginPath 无关。 ClosePath 只需创建一个从当前位置到最后一个 moveTo 位置的 lineTo 您可以拥有任意数量的 closePath,每个渲染输出只能有一个 beginPath(stroke()、fill())。剪辑是累积的,每次添加剪辑都会被前一个剪辑剪辑,每个剪辑区域越来越小。要恢复,您必须使用保存和恢复。

标签: javascript html canvas html5-canvas


【解决方案1】:

context.clip() 是否隐式关闭上下文路径?...
它前面是一个 context.beginPath(),后面是另一个 context.beginPath()。像这样:[...]

是的,这是创建剪切所需的闭合形状的唯一方法,因此如果不调用 closePath(),clip() 将在内部关闭路径。

specification states:

在计算裁剪区域时,必须隐式关闭打开的子路径,而不影响实际的子路径。

beginPath() 将清除当前主路径及其所有子路径。虽然剪辑仍然处于活动状态,但现在您可以执行其他路径操作,这些操作会在光栅化时受到剪辑区域的影响。

为什么需要推送上下文状态?

虽然有人建议和讨论过,但无法重置剪辑区域(标准中有 resetClip(),但尚未得到广泛支持)。 Calling clip() 多次-

clip() 方法必须通过计算当前剪辑区域的交集来创建一个新的剪辑区域 [...]

换句话说,如果我们说为整个绘图表面定义了一个剪辑区域,它将不会被替换。

所以我们可以删除剪辑的唯一方法是保存状态,设置剪辑然后恢复以删除它。

【讨论】:

  • 很好的解释!对于那些适用的边缘情况,只是一个小插件:调整画布元素大小时也会清除剪辑。这是因为在调整画布元素大小时会重置所有上下文状态。
猜你喜欢
  • 1970-01-01
  • 2013-09-09
  • 1970-01-01
  • 2014-10-06
  • 2013-09-29
  • 1970-01-01
  • 2011-11-10
  • 2016-04-06
  • 2014-10-06
相关资源
最近更新 更多