【问题标题】:Reverse Clipping in Canvas画布中的反向剪辑
【发布时间】:2014-04-05 18:59:25
【问题描述】:

我想裁剪html5画布,这样我就可以达到如下图的绘图效果。

我想实现剪辑路径,使所有的绘图都只在黑色区域进行。

【问题讨论】:

  • 这与core-graphics(这是一个关于 iOS 和 OSX 上的图形框架的标签)有何关系?
  • 对不起,我不知道什么是核心图形。刚刚从建议列表中选择。
  • 您可以将鼠标悬停在标签上查看它们的简短描述,看看它们是否真的符合您的问题。

标签: html html5-canvas


【解决方案1】:

方法一

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

ctx.globalCompositeOperation = 'source-in';
... draw graphics on top - only solid color will be affected ...
ctx.globalCompositeOperation = 'source-over';      // reset to default mode

A demo fiddle for this here

方法二

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

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

A demo fiddle with clearRect
A demo fiddle with clearRect + requestAnimationFrame

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

方法3

通过对rect() 的一系列调用,围绕您要保留的区域创建矩形区域。使用clip()作为剪贴蒙版的集合。

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

记得先将画布平移 0.5 像素,矩形只使用整数值。

方法四

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

请注意,这可能是最慢的方法,它受 CORS 限制的影响(如果你先在画布上绘制外部图像),如果你想填充形状、图像、渐变等,它会更加乏味第四,如果您可能更喜欢屏幕外的画布来复制。

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

【讨论】:

  • 方法 2 正是我所需要的,谢谢。当我读到它时,它是如此明显,以至于我一开始就为自己错过它而生气。
【解决方案2】:

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

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

演示: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);
}

【讨论】:

    猜你喜欢
    • 2011-06-16
    • 2014-10-06
    • 1970-01-01
    • 2023-03-03
    • 2010-12-09
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多