我似乎无法在画布上进行第二次剪辑调用。见小提琴:http://jsfiddle.net/m2hL17nu/ 请注意第一个径向渐变是如何被剪裁但第二个渐变渐变是
。我看过Can you have multiple clipping regions in an HTML Canvas?但是保存还原似乎还没有让下一个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();
答案 0 :(得分:3)
在绘制剪辑之前和剪辑()方法之后,你应该使用beginPath()和closePath():
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.beginPath();
context.rect(x1-r,y1-r,r,r);
context.closePath();
context.clip();
context.rect(0, 0, canvas.width, canvas.height);
createRadialGradient(x1, y1, x1, y1, r);
context.restore();
context.save();
context.beginPath();
context.rect(x2-r,y2,r,r);
context.closePath();
context.clip();
context.strokeStyle = 'black';
context.rect(0, 0, canvas.width, canvas.height);
createRadialGradient(x2, y2, x2, y2, r);
context.stroke();
<canvas id="myCanvas" width="500" height="500"></canvas>
答案 1 :(得分:2)
save()
和restore()
不会影响路径对象本身的内容 - 只影响上下文的状态(包括裁剪状态)。
restore()
可以删除剪辑定义,但如果路径仍然包含数据,则无论何时调用剪辑都会激活它,并且新数据会添加到路径中。
要使其正常工作,您需要确保自己正在使用干净的路径。为此,只需在使用beginPath()
定义剪辑区域之前调用rect()
。 closePath()
clip()
实际上没有必要clip()
因为fill()
(和beginPath()
)会因为无法使用开放路径进行剪辑而隐式关闭。
然后再进行实际绘制之前再次调用restore()
,因为剪切现在是上下文状态的一部分。最后使用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
删除剪辑定义(将状态恢复为上一个)。
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();
<canvas id=canvas width=500 height=180></canvas>
{{1}}