画布渐变表现

Dan*_*eng 3 performance html5 gradient canvas fog

我目前正在使用画布编写一个小游戏.对于游戏,我需要某种雾,它隐藏了地图的大部分区域,并且只能看到玩家周围的一小块区域.我使用第二个画布覆盖游戏发生的那个并用渐变填充(从透明到黑色):

function drawFog(){
fogc.clearRect(0,0,700,600);
// Create gradient
var grd=fogc.createRadialGradient(player.getPosX(),player.getPosY(),0,player.getPosX(),player.getPosY(),100);
grd.addColorStop(0,"rgba(50,50,50,0)");
grd.addColorStop(1,"black");

// Fill with gradient
fogc.fillStyle=grd;
fogc.fillRect(0,0,700,600);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这会导致巨大的性能问题,因为它会在每一帧重绘.

我想问一下是否有更好的解决方案可以达到同样的效果并获得更好的性能.

小智 6

将渐变缓存到离屏画布,然后使用drawImage()在画布中绘制:

  • 创建一个雾大小的离屏画布
  • 绘制渐变
  • 当您需要雾时,请使用离屏画布作为图像.

这样,消除了创建和计算梯度的处理.绘制图像基本上是一个复制操作(有一点点,但性能非常好).

function createFog(player) {

    // Create off-screen canvas and gradient
    var fogCanvas = document.createElement('canvas'),
        ctx = fogCanvas.getContext('2d'),
        grd = fogc.createRadialGradient(player.getPosX(),
                                        player.getPosY(),
                                        0,player.getPosX(),
                                        player.getPosY(),100);

    fogCanvas.width = 700;
    fogCanvas.height = 700;

    grd.addColorStop(0,"rgba(50,50,50,0)");
    grd.addColorStop(1,"black");

    // Fill with gradient
    ctx.fillStyle = grd;
    ctx.fillRect(0,0,700,600);

    return fogCanvas;
}
Run Code Online (Sandbox Code Playgroud)

现在您可以简单地在从上面的函数返回的画布中绘制,而不是每次都创建渐变:

var fog = createFog(player);
ctx.drawImage(fog, x, y);
Run Code Online (Sandbox Code Playgroud)