首页 > 解决方案 > 画布 javascript

问题描述

我正在尝试使用 javascript 画布制作“隐藏的问候”。它应该以这种方式工作,当用户单击画布区域时,该区域的不透明度会降低。为了改变这个不透明度,我使用像素数据(getImageData)。然后我在该画布上再次写入该文本,因为如果像素数据位于该区域中,它也会更改文本。

我面临的问题是,当我有时在画布中单击时,文本本身就会变得可见,即使我没有在文本区域中单击。

代码和输出可以在这里找到。

请参阅CodePen 上situ25 ( @situ25 )的 Pen JBdJzZ

当在画布上发生点击时调用函数 fillpos()。

function fillpos(ev){
    var canvas=document.getElementById("canvas1");
    if(canvas.getContext)
    {

        var ctx=canvas.getContext('2d');
        ctx.fillStyle='rgb(0,240,0)';
        ctx.globalAlpha=0.2;
        var pos=getMousePos(canvas,ev);
        var borderWidth=parseInt(getComputedStyle(document.getElementById("canvas1")).borderWidth);

        var imagedata=ctx.getImageData(pos.x,pos.y,40,40);

        for(var i=0;i<imagedata.data.length;i+=4)
        {
            imagedata.data[i+3]=100;
        }
        ctx.putImageData(imagedata,pos.x,pos.y);
        writeText();

    }
}

function writeText(){
    var canvas=document.getElementById("canvas1");
    if(canvas.getContext){

        var ctx=canvas.getContext('2d');

        ctx.font="40px Georgia";

        ctx.fillText("Hi There",100,100);                       //Write text again
    }
}

标签: javascriptcanvas

解决方案


我面临的问题是,当我有时在画布中单击时,文本本身就会变得可见,即使我没有在文本区域中单击。

那是因为你在画布上绘制文本,不管它的哪一部分应该被显示,并且在绘制背景/前景之后这样做,这意味着它最后被绘制在其他所有内容之上。

使用单个画布,您只有一层图像数据,因此您无法在画布中“显示”一开始就不存在的东西。

实现目标的一种方法是拥有一个单独的画布,其中仅包含前景层的图像数据(此处称为revealLayerCanvas):

var revealLayerCanvas = document.createElement('canvas');
revealLayerCanvas.width = canvas.width;
revealLayerCanvas.height = canvas.height;
revealLayerCtx = revealLayerCanvas.getContext('2d');

绘制画布时首先绘制背景,然后是文本,然后是前景层。

function redraw(){
   ctx.fillStyle='rgb(0,240,0)';
   ctx.fillRect(0,0,canvas.width,canvas.height);
   ctx.fillStyle='rgb(0,0,0)';
   ctx.font="40px Georgia";
   ctx.fillText("SECRET",100,100);
   ctx.drawImage(revealLayerCanvas,0,0);
}

拖动图像时,您将显示前景的一部分,就像您在示例中所做的那样。

有关完整的工作示例,请参见 Pen:Canvas Reveal Layer


推荐阅读