【问题标题】:globalCompositeOperation drawing white over backgroundglobalCompositeOperation 在背景上绘制白色
【发布时间】:2015-08-07 12:55:30
【问题描述】:

我在 html5 画布的 javascript 中使用 globalCompositeOperation 时遇到问题。

https://jsfiddle.net/6j51kxeh/

我正在使用“destination-in”在心的精灵中画一个黑色方块,所以当玩家错过那颗心时,它会显示出来。它可以很好地绘制黑色的心,但它会在其他所有内容之上绘制白色。如果您注释掉 globalCompositeOperation 行,您将看到它被绘制在其他事物之上(只是来自同一个精灵表的一组随机精灵)。感谢您的帮助。

我在链接到 jsfiddle 时也遇到了问题,我已经玩完了。

var canvas = document.createElement("canvas");    

canvas.height = window.innerHeight;
canvas.width  = window.innerWidth;

var scale = 4;

document.body.appendChild(canvas);

var draw = canvas.getContext("2d");

draw.imageSmoothingEnabled = false;
draw.mozImageSmoothingEnabled = false;
draw.oImageSmoothingEnabled = false;
draw.webkitImageSmoothingEnabled = false;

var assetsToLoad = [];
var assetsLoaded = 0;

var sprites = new Image();
sprites.onload = loadHandler;
sprites.src = "https://dl.dropboxusercontent.com/u/38825680/Site/images/sprites.png";
assetsToLoad.push(sprites);


function loadHandler() {
    assetsLoaded++;
    if(assetsLoaded === assetsToLoad.length) {
        console.log(assetsLoaded + " asset[s] loaded");

        Draw();
    }
};

function Draw() {
    draw.save();
    draw.scale(scale,scale);

    draw.drawImage(sprites,0,64,64,64,0,0,64,64);
    // draw.drawImage(sprites,112,80,16,16,0,0,16,16);
    draw.fillStyle = "black";
    draw.fillRect(0,0,16,16);

    //draw.globalCompositeOperation = "destination-in";

    draw.drawImage(sprites,96,48,16,16,0,0,16,16);


    draw.restore();
}

【问题讨论】:

    标签: javascript html canvas alpha masking


    【解决方案1】:

    destination-in 合成具有破坏性,因为它将擦除画布上的所有内容,除非新(心脏)与任何现有的非透明像素重叠。所以这种合成形式可能不是你需要的。

    澄清一下:您想在另一个精灵图像上绘制心脏精灵,然后从添加了心脏的另一个精灵图像中清除该精灵?

    如果是,那么:

    • 要添加心形,请将心形精灵绘制在另一个精灵上。
    • 要清除心脏,只需重新绘制另一个精灵。

    示例代码和演示:

    var canvas = document.createElement("canvas");    
    
    canvas.height = 640;//window.innerHeight;
    canvas.width  = 960;//window.innerWidth;
    
    var scale = 4;
    
    document.body.appendChild(canvas);
    
    var draw = canvas.getContext("2d");
    
    draw.imageSmoothingEnabled = false;
    draw.mozImageSmoothingEnabled = false;
    draw.oImageSmoothingEnabled = false;
    draw.webkitImageSmoothingEnabled = false;
    
    var assetsToLoad = [];
    var assetsLoaded = 0;
    
    var sprites = new Image();
    sprites.onload = loadHandler;
    
    sprites.src = "https://dl.dropboxusercontent.com/u/38825680/Site/images/sprites.png";
    assetsToLoad.push(sprites);
    
    
    function loadHandler() {
      assetsLoaded++;
      if(assetsLoaded === assetsToLoad.length) {
        console.log(assetsLoaded + " asset[s] loaded");
    
        draw.scale(scale,scale);
        Draw();
      }
    };
    
    function Draw() {
      draw.drawImage(sprites,0,64,64,64,0,0,64,64);
    }
    
    
    
    function addHeart(x,y){
      draw.fillStyle = "black";
      draw.fillRect(x,y,16,16);
      draw.drawImage(sprites,96,48,16,16,x,y,16,16);
    }
    
    function removeHeart(x,y,spriteX,spriteY){
      draw.clearRect(x,y,16,16);
      draw.drawImage(sprites,spriteX,spriteY+64,16,16,x,y,16,16)
    }
    
    $('#add').click(function(){
      addHeart(0,0);
    });
    
    $('#remove').click(function(){
      removeHeart(0,0,0,0);
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <button id=add>Add heart</button>
    <button id=remove>Remove heart</button>

    【讨论】:

    • 这不是我想要的。首先,我在这里看到的心是黑色方块上的心。心脏应该掩盖黑色方块,所以只出现黑色心脏。其次,这是在游戏的背景下发生的,其中许多不同的精灵以特定的顺序绘制。我把它拉出来,只是画了一些,看看我是否可以让它自己工作,但无济于事。但是我的游戏每秒更新很多次。我只需要能够在不清除画布的其余部分的情况下绘制黑色的心。感谢您的快速回复。
    • (1) 创建第二个内存画布,大小为 1 个图块,(2) 在该画布上绘制红心,(3) 设置 source-in 合成,(4) 填充整个画布带有一个黑色矩形 - 心脏将变成黑色,其他一切都透明,(5)使用该画布作为图像源在您的主画布上绘制:ctx.drawImage(memCanvas,x,y)
    • 第 4 步,其他一切都保持透明,我想我希望在我的主画布上绘图时不会把所有东西都变成白色。对不起,我还在研究这个网站。输入按钮在我准备好之前发布了第一条评论,然后我花了太长时间尝试编辑。我不是故意要简洁或粗鲁。
    • 这里没问题。欢迎来到 Stackoverflow :-) 我仍然不清楚你想要什么——一颗黑心,还有什么......?
    • 那行得通。我不确定我是否应该将此标记为已回答。我想要的只是能够使用精灵作为面具。很明显,要做到这一点,需要缓冲区。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 2022-10-04
    • 2012-04-23
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    相关资源
    最近更新 更多