我在画布上使用clip()函数。
结果:
正如你可以看到,铬版本有可怕的锯齿/边缘的锯齿。我该如何解决?
重现代码:
<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,2*Math.PI,true); ctx.clip(); ctx.drawImage(im,0); } im.src = "http://placekitten.com/300/300"; </script>
解决方法
如果你做复杂的,分层的绘图,你可以使用globalCompositeOperation在第二个,scratch画布中模拟剪辑。然后可以使用drawImage将scratch 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,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,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,...);
我们在临时画布中执行此操作的原因是destination-in是一个非常具有破坏性的操作。如果你已经在主画布中绘制了一些东西(也许你在背景中放下一个漂亮的渐变),然后想要绘制一个剪切的图像,剪切圆也会剪辑你已经绘制的一切。当然,如果你的特殊情况更简单(也许所有你想画的是一个剪辑的图像),然后你可以放弃划痕画布。
你可以在my demo page上使用不同的剪辑模式。底行(带渐变)对你来说不太有用,但是顶行(带圆圈和正方形)更为相关。
编辑
糟糕,我不小心forked your JSFiddle演示的技术。