Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 画布剪裁区域和画布堆栈_Javascript_Html_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 画布剪裁区域和画布堆栈

Javascript 画布剪裁区域和画布堆栈,javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,我已经开始阅读O'Reilly的书《HTML5画布》。我在第二章中,其中一个例子给出了没有很好解释的代码。例2-5: 画一个黑盒子 推送状态 在左上角设置小剪裁区域 画圈 流行状态 设置大剪裁区域 再画一个圈 但我在理解一些事情上有困难: context.fillStyle = 'black'; context.fillRect(10, 10, 200, 200); context.save(); context.beginPath(); context.rect(0, 0, 50, 50)

我已经开始阅读O'Reilly的书《HTML5画布》。我在第二章中,其中一个例子给出了没有很好解释的代码。例2-5:

  • 画一个黑盒子
  • 推送状态
  • 在左上角设置小剪裁区域
  • 画圈
  • 流行状态
  • 设置大剪裁区域
  • 再画一个圈
  • 但我在理解一些事情上有困难:

    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();
    
    第二,为什么需要推送上下文状态?为什么我不能更改剪辑区域?这似乎是必要的,因为如果不推动政府,它是行不通的。如果我不推动状态,然后恢复它,蓝色的大圆圈就不会出现,我不明白为什么

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

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

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

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

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

    虽然已经提出并讨论过剪辑区域,但无法重置剪辑区域(标准中有一个选项,但尚未得到广泛支持)。好几次-

    clip()方法必须通过计算当前剪裁区域的交点[…]来创建新的剪裁区域

    换句话说,如果我们说为整个绘制曲面定义了剪辑区域,则不会替换它


    因此,我们删除剪辑的唯一方法是保存状态,设置剪辑,然后还原以删除它。

    beginPath开始一个全新的路径并转储旧路径。closePath与beginPath不相关。ClosePath只需创建从当前位置到最后一个moveTo位置的lineTo。您可以有任意多个ClosePath,每个渲染输出只能有一个beginPath(stroke(),fill())。剪辑是累积的,每次添加剪辑时,它都会被上一个剪辑剪辑,每个剪辑区域都会变得越来越小。要还原,您必须使用“保存和还原”。很好的解释!这只是适用于边缘情况的一个小插件:调整画布元素的大小时也会清除剪裁。这是因为在调整画布元素的大小时,所有上下文状态都会重置。