我在 Canvas 上使用clip()函数。
结果:
如您所见,Chrome版本的边缘有锯齿状的锯齿/锯齿。我该如何解决?
复制代码:
http://jsfiddle.net/ZRA76/:
<canvas id="test" width="300" height="300"></canvas>
<script type="text/javascript">
cv = document.getElementById("test");
ctx = cv.getContext("2d");
var im = new Image();
im.onload = function () {
ctx.beginPath();
ctx.arc(110, 110, 100, 0, 2*Math.PI, true);
ctx.clip();
ctx.drawImage(im, 0, 0);
}
im.src = "http://placekitten.com/300/300";
</script>
最佳答案
如果要进行复杂的分层绘图,则可以使用globalCompositeOperation在第二个暂存 Canvas 中模拟裁剪。然后,您可以使用drawImage将草稿 Canvas 复制回原始 Canvas 。我不能保证这种方法的性能,但这是我知道获得所需东西的唯一方法。
//set-up - probably only needs to be done once
var scratchCanvas = document.createElement('canvas');
scratchCanvas.width = 100;
scratchCanvas.height = 100;
var scratchCtx = scratchCanvas.getContext('2d');
//drawing code
scratchCtx.clearRect(0, 0, scratchCanvas.width, scratchCanvas.height);
scratchCtx.globalCompositeOperation = 'source-over'; //default
//Do whatever drawing you want. In your case, draw your image.
scratchCtx.drawImage(imageToCrop, ...);
//As long as we can represent our clipping region as a single path,
//we can perform our clipping by using a non-default composite operation.
//You can think of destination-in as "write alpha". It will not touch
//the color channel of the canvas, but will replace the alpha channel.
//(Actually, it will multiply the already drawn alpha with the alpha
//currently being drawn - meaning that things look good where two anti-
//aliased pixels overlap.)
//
//If you can't represent the clipping region as a single path, you can
//always draw your clip shape into yet another scratch canvas.
scratchCtx.fillStyle = '#fff'; //color doesn't matter, but we want full opacity
scratchCtx.globalCompositeOperation = 'destination-in';
scratchCtx.beginPath();
scratchCtx.arc(50, 50, 50, 0, 2 * Math.PI, true);
scratchCtx.closePath();
scratchCtx.fill();
//Now that we have a nice, cropped image, we can draw it in our
//actual canvas. We can even draw it over top existing pixels, and
//everything will look great!
ctx.drawImage(scratchCanvas, ...);
之所以在暂存 Canvas 中执行此操作,是因为目标进入是一个非常有害的操作。如果您已经在主 Canvas 中绘制了一些东西(也许您在背景中放了一个漂亮的渐变),然后想要绘制一个剪切的图像,则剪切圆还将剪切出您已经绘制的所有内容。当然,如果您的情况比较简单(也许您要绘制的只是剪切的图像),则可以放弃暂存 Canvas 。
您可以在my demo page上使用不同的剪切模式。最下面一行(带有渐变)对您不太有用,但是最上面一行(带有圆形和正方形)更相关。
编辑
糟糕,我不小心forked your JSFiddle演示了该技术。