在画布中反向剪裁

Raj*_*tel 5 html html5-canvas

我想剪辑 html5 画布,以便我可以按照下图实现绘图结果。

我想实现剪辑路径,以便所有绘图仅在黑色区域执行。

在此处输入图片说明

小智 9

方法一

假设白色区域是透明的,黑色是不透明的,那么您可以使用复合模式:

ctx.globalCompositeOperation = 'source-in';
... draw graphics on top - only solid color will be affected ...
ctx.globalCompositeOperation = 'source-over';      // reset to default mode
Run Code Online (Sandbox Code Playgroud)

这里有一个演示小提琴

方法二

另一种更简单的方法是简单地用您需要的图形填充画布,然后将其clearRect()用于您想要透明的区域。

此操作相当快,因此不应有任何闪烁(以防您可以通过一次requestAnimationFrame调用触发此操作)。

使用 clearRect
的演示小提琴 使用 clearRect + requestAnimationFrame 的演示小提琴

请注意,调用 rAF 会使代码异步,但使用它的目的是您的绘制操作在帧更新内同步,因此将消除闪烁(如果您因某种原因遇到问题)。

方法三

通过对 的一系列调用,在要保留的区域周围创建矩形区域rect()。使用 将其设置为剪贴蒙版clip()

如果非剪裁区域按特定顺序排列,则此技术效果最佳,否则您必须定义大量区域。

请记住首先将画布转换为 0.5 像素,并且仅对矩形使用整数值。

方法四

手动解析像素缓冲区以填充满足要求的区域中的像素,例如仅非透明像素。

请注意,这可能是最慢的方法,它受 CORS 限制的影响(如果您首先将外部图像绘制到画布上),并且如果您想填充形状、图像、渐变等,则更加繁琐。如果您可能更喜欢从屏幕外的画布进行复制。

还有其他方法可以使用不同的复合模式和绘制顺序来实现相同的结果,但我保留它,因为它应该涵盖大多数场景。


mar*_*rkE 1

您可以使用分层来满足您的需求:

  • 复制您的图像,将全黑设为透明
  • 在画布上绘制原始图像
  • 画出你想要的形状
  • 在上面绘制透明图像

演示: http: //jsfiddle.net/m1erickson/dFRUf/

在此输入图像描述

此函数创建一个临时画布,其中您指定的颜色范围变得透明:

function makeImageTransparentByColor(image,r1,r2,g1,g2,b1,b2){
    // create a temporary canvas and draw the image on the canvas 
    var bk=document.createElement("canvas");
    var bkCtx=bk.getContext("2d");
    bk.width=image.width;
    bk.height=image.height
    bkCtx.drawImage(image,0,0);
    // get the pixel array from the canvas
    var imgData=bkCtx.getImageData(0,0,bk.width,bk.height);
    var data=imgData.data;
    // loop through each pixel and make every pixel transparent
    // that is between r1-r2, g1-g2 and b1-b2
    for(var i=0;i<data.length;i+=4){
        var r=data[i];
        var g=data[i+1];
        var b=data[i+2]
        if(r>=r1 && r<=r2 && g>=g1 && g<=g2 && b>=b1 && b<=b2){
            data[i]=0;
            data[i+1]=0;
            data[i+2]=0;
            data[i+3]=0;
        }
    }
    // put the modified pixels back on the canvas
    bkCtx.putImageData(imgData,0,0);
    // return the canvas with transparent image
    return(bk);
}
Run Code Online (Sandbox Code Playgroud)