在HTML5画布中,如何使用我选择的背景来遮罩图像?

11

我尝试使用canvas的globalCompositeOperation来实现这个功能,但没有成功,所以我在这里询问。这里有类似的问题,但我没有找到我的情况。

我的画布区域有几层,按绘制顺序从下到上:

  • 画布底部填充纯白色(#fff,使用fillRect)
  • 第一张图片house是一张房子的图片。背景透明。(见下文)
  • 第二张图片roofOverlay是一个“遮罩”图像,屋顶区域为红色(可以是任何颜色,但为了清晰起见选用红色,见下文)

两张图片占据整个画布,并完全重合,使红色屋顶区域与房子匹配。

然后,我有一个重复的背景repeatPattern,我想仅在红色区域内使用它:用repeatPattern填充红色区域。 (可以是任何东西,但假设为六边形或其他形状)

在伪代码中,理想情况下应该是以下内容:

roofOverlay.maskBackground(repeatPattern)

(顺便说一句,我也想能够调整背景图案的HSL值,但是一旦我能够让图案显示出来,那就相当简单了)

期望结果:

期望的结果是房屋的屋顶使用repeatPattern图像进行纹理处理。

注意:我知道有剪切路径和蒙版,但我不能在这里使用它们。这个例子很简化,为多个不同房屋绘制所有路径会花费太多工作量。我只有用于屋顶的叠加png文件。

参考图片

房屋house


房屋屋顶叠加roofOverlay

1个回答

19

以下是如何使用“roofOverlay”将“屋顶图案”叠加在“房屋”上的步骤:

图片描述

这是一个多部分的过程:

  1. 在Canvas#1上绘制房子。
  2. 在Canvas#2上绘制红色的roofOverlay。
  3. 将Canvas#2的context.globalCompositeOperation设置为'source-in'
  4. 在Canvas#2上绘制所需的图案。
  5. 合成将导致所需的图案替换红色覆盖区域内的图案。

这是一个Fiddle示例,可以在您的屋顶上加载草图案:http://jsfiddle.net/m1erickson/SWP6v/

下面是使用格栅图案填充你的屋顶的代码:

注意:我假设您想要将房屋和屋顶放在不同的画布上,这样您就可以翻阅各种屋顶选择。如果您需要一切都在一个画布上,您只需将屋顶画布绘制到房屋画布上即可。

<!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;}
    #container{position:relative;}
    #house{position:absolute; top:0; left:0;}
    #canvas{position:absolute; top:0; left:0;}
</style>

<script>
$(function(){

    var house=document.getElementById("house");
    var ctxHouse=house.getContext("2d");
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var red=new Image();
    red.onload=function(){
       canvas.width=red.width;
       canvas.height=red.height;

       var houseImage=new Image();
       houseImage.onload=function(){
           house.width=houseImage.width;
           house.height=houseImage.height;
           ctxHouse.drawImage(houseImage,0,0);
       }
       houseImage.src="https://dl.dropbox.com/u/1122582/stackoverflow/house.png";

       ctx.drawImage(red,0,0);

        var imageObj = new Image();
        imageObj.onload = function() {
          var pattern = ctx.createPattern(imageObj, 'repeat');
          ctx.globalCompositeOperation = 'source-in';
          ctx.rect(0, 0, canvas.width, canvas.height);
          ctx.fillStyle = pattern;
          ctx.fill();
        };
        imageObj.src = "http://dl.dropbox.com/u/139992952/stackoverflow/lattice.jpg";
    }
    red.src="https://dl.dropbox.com/u/1122582/stackoverflow/roof-overlay.png";

}); // end $(function(){});
</script>

</head>

<body>
<div id="container">
        <canvas id="house" width=300 height=300></canvas>
        <canvas id="canvas" width=300 height=300></canvas>
</div>
</body>
</html>

这个答案让我感到困惑,但它通过指引我正确的方向来帮助我,即去谷歌搜索ctx.globalCompositeOperation。 - shieldgenerator7
小提琴似乎现在没有结果显示。 Dropbox 图像全部为 404 - Rahil Wazir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接