[英]How can I clip INSIDE a shape in HTML5 canvas?
我已经找到了许多用于剪切弧的外部区域的示例 (例如: 此示例 )。 我似乎无法弄清楚如何在弧形内部进行剪裁。
这是我当前如何剪切外部区域的示例,这实际上与我想要的相反:
ctx.save();
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
ctx.clip();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.shadowBlur = 10;
ctx.shadowOffsetX = shadowOffset;
ctx.shadowColor = '#000000';
ctx.strokeStyle = '#000000';
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
ctx.stroke();
ctx.restore();
对于不规则形状,您可以使用两种技术:
恕我直言,更好的选择使用实际剪辑模式或复合模式destination-out
。
正如markE在他的回答中所说, xor
也是可用的,但是xor只反转alpha像素并且不会移除RGB像素。 这适用于没有透明度的实体图像,但是如果现有像素具有透明度,则这些像素可能会产生相反的效果(变为可见),或者如果稍后使用xor模式并在顶部绘制其他内容,则“剪切”区域将再次显示。
通过使用剪辑,您只需使用clearRect
清除路径定义的区域。
例:
/// save context for clipping
ctx.save();
/// create path
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.closePath();
/// set clipping mask based on shape
ctx.clip();
/// clear anything inside it
ctx.clearRect(0, 0, offset, offset);
/// remove clipping mask
ctx.restore();
源图像 :具有部分半透明像素且完全透明的图像,其中背景中的白色通过 -
结果:
我们打了一个洞,背景显示:
使用复合模式destination-out
将像剪辑一样清除像素:
ctx.beginPath();
ctx.arc(offset * 0.5, offset * 0.5, offset * 0.3, 0, 2 * Math.PI);
ctx.closePath();
/// set composite mode
ctx.globalCompositeOperation = 'destination-out';
ctx.fill();
/// reset composite mode to default
ctx.globalCompositeOperation = 'source-over';
结果:
与剪切相同, destination-out
删除像素。
在这种情况下使用xor
存在透明像素( 参见此处的在线示例 ):
只有alpha值被反转。 由于我们没有实像素,因此alpha不会从255变为0( 255 - 255
)而是255 - actual value
会导致使用此模式的非清除背景。
(如果您使用相同模式第二次绘制,则“已删除”像素将被恢复,因此可以以其他方式使用)。
您肯定可以使用您的样式的“倒置”剪辑形状进行剪辑:首先绘制屏幕轮廓,然后绘制剪切路径 - 不使用beginPath-,然后关闭路径和剪辑。
这样,您描述的形状就是屏幕内的“洞”。
路径功能必须描述封闭路径。
这里有一个演示: http : //jsfiddle.net/gamealchemist/9DuJL/40/
我们可以看到,即使它们没有相交也可以使用多种形状。
代码如下:
// clips the canvas with the invert of provided path function
// if pathFunction is an array, remove clips defined by all functions
function clipRevert(pathFunction) {
ctx.beginPath();
ctx.rect(0, 0, canvas.width, ctx.canvas.height);
if (Array.isArray(pathFunction)) pathFunction.forEach(execute);
else pathFunction();
ctx.clip();
}
function execute(fn) {
return fn();
}
使用示例:(将使用圆形的反转剪辑绘制图像):
function circlePath(x, y, r) {
ctx.arc(x, y, r, 0, Math.PI * 2, true);
}
window.clipRevertExample = function () {
ctx.save();
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
clipRevert(circlePath.bind(null, 100, 60, 40));
ctx.drawImage(img, 0, 0);
ctx.restore();
}
最后一点:您实际上可以选择任意基础形状来减去。
您可以使用context.globalCompositeOperation =“xor”根据任何路径或绘图从现有图像中删除。
此合成模式将使用您在应用合成后执行的任何绘图“取消”现有像素。
在这种情况下,现有图像将根据您的弧线“未绘制”:
这是代码和小提琴: http : //jsfiddle.net/m1erickson/9DuJL/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=function(){
ctx.save();
ctx.drawImage(img,0,0);
ctx.globalCompositeOperation="xor";
ctx.beginPath();
ctx.arc(106, 77, 74, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
ctx.restore();
}
img.src="http://i.imgur.com/gwlPu.jpg";
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=200 height=158></canvas>
</body>
</html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.