Javascript 画布中每个上下文有多个剪辑调用

Javascript 画布中每个上下文有多个剪辑调用,javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,我似乎无法在画布上获得第二个剪辑调用。参见小提琴: 请注意第一个径向渐变是如何剪裁的,而第二个不是 我已经看到了,但是save restore似乎仍然不能让下一个clip()正常工作 提前感谢你的帮助。见下面的代码: var x1 = 300, y1 = 100, x2 = 50, y2 = 50, r = 20; var canvas = document.getElementById('myCanvas'); var context = canvas.get

我似乎无法在画布上获得第二个剪辑调用。参见小提琴: 请注意第一个径向渐变是如何剪裁的,而第二个不是

我已经看到了,但是save restore似乎仍然不能让下一个clip()正常工作

提前感谢你的帮助。见下面的代码:

var x1 = 300,
    y1 = 100,
    x2 = 50,
    y2 = 50,
    r = 20;

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
function createRadialGradient (xa, ya, xb, yb, r) {
    var grd = context.createRadialGradient(xa, ya, 0, xb, yb, r);
    grd.addColorStop(0, 'rgba(0,0,0,1)');
    grd.addColorStop(1, 'rgba(0,0,0,0)');
    context.fillStyle = grd;
    context.fill();
}
context.save();
context.rect(x1-r,y1-r,r,r);
context.clip();
context.rect(0, 0, canvas.width, canvas.height);
createRadialGradient(x1, y1, x1, y1, r);

context.restore();

context.save();
context.rect(x2-r,y2,r,r);
context.strokeStyle = 'black';
context.clip();
context.rect(0, 0, canvas.width, canvas.height);
createRadialGradient(x2, y2, x2, y2, r);

context.stroke();
在绘制片段之前和片段()方法之后,应分别使用beginPath()和closePath()

var x1=300,
y1=100,
x2=50,
y2=50,
r=20;
var canvas=document.getElementById('myCanvas');
var context=canvas.getContext('2d');
函数createRadialGradient(xa,ya,xb,yb,r){
var grd=context.createRadialGradient(xa,ya,0,xb,yb,r);
grd.addColorStop(0,'rgba(0,0,0,1');
grd.addColorStop(1,'rgba(0,0,0');
context.fillStyle=grd;
context.fill();
}
context.save();
context.beginPath();
context.rect(x1-r,y1-r,r,r);
closePath();
clip();
rect(0,0,canvas.width,canvas.height);
创建径向梯度(x1,y1,x1,y1,r);
restore();
context.save();
context.beginPath();
rect(x2-r,y2,r,r);
closePath();
clip();
context.strokeStyle='black';
rect(0,0,canvas.width,canvas.height);
创建径向梯度(x2,y2,x2,y2,r);
stroke()
保存()
和还原()不会影响路径对象本身的内容-仅影响上下文的状态(包括剪切状态)

restore()
可以删除剪辑定义,但如果路径仍然包含数据,则下次调用剪辑时将激活该定义,并且会将新数据添加到路径中

要使其工作,您需要确保您使用的是干净的路径。为此,只需在使用
rect()
定义剪辑区域之前调用
beginPath()
<对于
clip()
,code>closePath()确实是不必要的,因为
clip()
(和
fill()
)将隐式关闭,因为无法使用打开的路径进行剪裁

然后在实际绘制之前再次调用
beginPath()
,因为剪裁现在是上下文状态的一部分。最后使用
restore()

var ctx=canvas.getContext('2d');
ctx.save();
ctx.beginPath();
ctx.rect(50,50,50,50);
ctx.clip();
ctx.beginPath();
ctx.rect(0,0,canvas.width,canvas.height);
ctx.fillStyle='#900';
ctx.fill();
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.rect(150,80,80,60);
ctx.clip();
ctx.beginPath();
ctx.rect(0,0,canvas.width,canvas.height);
ctx.fillStyle='#009';
ctx.fill();
ctx.restore()
剪切后新图形形状需要beginPath(),否则剪切矩形将成为填充/笔划等的一部分(因为closePath不会清除路径)。clip()确实不需要closePath,但如果仍要使用它,请确保在调用clip()之前调用了closePath。
context.save();               // store current state to stack

context.beginPath();          // clean path
context.rect(x1-r,y1-r,r,r);
context.clip();               // path is closed; clip is now activated

context.beginPath();          // clean path for your new shape
context.rect(0, 0, canvas.width, canvas.height);
createRadialGradient(x1, y1, x1, y1, r);
...

context.restore();            // removes the clip from state