HTML5, rendering pixels to image on load for faster draw times

旧时模样 提交于 2019-12-13 05:19:50

问题


I have a map that is a per pixel terrain. If you draw these pixels individually, it takes a lot of render time.

So my idea is to draw them in blocks of 100x100 images when the pixels are changed, and render those images.

The pixels in "chunk" is stored in a 1D array in the form index = x+y*width.

var img = game.c.createImageData(CHUNK_SIZE,CHUNK_SIZE);
for (var i=0;i<chunk.map.length;i++){
    var p = chunk.map[i];

    if (p){
        img.data[i*4] = 255;
        img.data[i*4+1] = 0;
        img.data[i*4+2] = 0;
        img.data[i*4+3] = 255;
    }else{
        img.data[i*4] = 0;
        img.data[i*4+1] = 0;
        img.data[i*4+2] = 0;
        img.data[i*4+3] = 0;
    }
}
this.render.push({x:chunk.x,y:chunk.y,img:img});

Draw:

for (var i=0;i<this.map.render.length;i++){
        var img = this.map.render[i];
        if (img.x*CHUNK_SIZE > this.player.x - (this.ce.width/2)){
            if (img.y*CHUNK_SIZE > this.player.y -(this.ce.height/2)){
                if ((img.x*CHUNK_SIZE)+CHUNK_SIZE < this.player.x + (this.ce.width/2)){
                    if ((img.y*CHUNK_SIZE)+CHUNK_SIZE < this.player.y + (this.ce.height/2)){
                        console.log("Rendering chunk...");
                        this.c.putImageData(img.img,(img.x*CHUNK_SIZE)-this.player.x,(img.y*CHUNK_SIZE)-this.player.y); 
                    }
                }   
            }                   
        }
    }

It is, however, not rendering correctly: The box has some transparent pixels, which makes the canvas transparent when there should be a sky gradient.

I want to write the image so transparent shows what was there (the sky gradient), and not make a hole in the canvas


回答1:


When you are using putImageDatayou are simply replacing all pixels for that area (including the alpha channel), no mixing takes place.

The better approach would be to store your chunks as off-screen canvases (or images/sprites) and use drawImage to draw them onto your main canvas.

Not only will this preserve existing pixels (depending on composite mode if that is changed) but it will also be faster than using putImageData.

If you should still insist on using putImageData you would need to first do a getImageData for the existing content, then iterate through all pixels and mix the pixels from you chunk with the data you got from main canvas according to their alpha value and finally put the result of that back on canvas. This is a very costly operation.



来源:https://stackoverflow.com/questions/18964775/html5-rendering-pixels-to-image-on-load-for-faster-draw-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!