【问题标题】:In HTML5 canvas, how to mask an image with a background of my choice?在 HTML5 画布中,如何用我选择的背景屏蔽图像?
【发布时间】:2013-03-09 17:56:57
【问题描述】:

我试图用画布'globalCompositeOperation 来实现这一点,但没有运气,所以我在这里问。这里有类似的问题,但我没有在其中找到我的案例。

我的画布区域中也有图层(从下到上的绘制顺序):

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

两张图片都占据了整个画布,并完美地排列在一起,使红色屋顶区域与房子相匹配。

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

在伪代码中,理想的情况是:

roofOverlay.maskBackground(repeatPattern)

(在旁注中,我还希望能够弄乱背景图案 HSL 值,但我认为一旦我得到图案甚至显示,这将非常简单)

预期结果:

预期的结果将是屋顶带有 repeatPattern 图像纹理的房子。

注意:我知道带有蒙版的剪切路径,但我不能在这里使用它们。这个例子被简化了,绘制多个不同房屋的所有路径将是太多的工作。我只有屋顶覆盖的 png 文件。

图片供参考

house


roofOverlay

【问题讨论】:

    标签: javascript html canvas png masking


    【解决方案1】:

    以下是使用“roofOverlay”在“房子”顶部合成“屋顶图案”的方法

    这是一个多部分的过程:

    1. 在画布#1 上画出房子。
    2. 在 canvas#2 上绘制红色的屋顶覆盖层。
    3. 设置 canvas#2 的 context.globalCompositeOperation = 'source-in'
    4. 在画布#2 上绘制您想要的图案
    5. 合成将导致您想要的图案替换红色覆盖 - 仅在红色覆盖区域中。

    这是一个在屋顶上装草的小提琴:http://jsfiddle.net/m1erickson/SWP6v/

    下面是在屋顶上使用格子图案填充的代码:

    注意:我假设您希望房子和屋顶在不同的画布上,这样您就可以翻阅各种屋顶选择。如果您需要 1 个画布上的所有内容,您只需将屋顶画布绘制到房屋画布上即可。

    <!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
    • 小提琴现在似乎没有结果。 Dropbox 图片都是 404
    猜你喜欢
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    相关资源
    最近更新 更多