在画布上绘制10,000个对象javascript [英] draw 10,000 objects on canvas javascript

查看:127
本文介绍了在画布上绘制10,000个对象javascript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在画布上绘制超过10,000张图片(32x32像素),但超过2000张图片的效果非常糟糕。

I need draw over 10,000 images (32x32 px) on canvas but over 2000 draws the performances is very bad.

这是一个例子:

对象结构 {position:0}

for(var nObject = 0; nObject < objects.length; nObject++){
    ctx.save();
    ctx.translate(coords.x,coords.y);
    ctx.rotate(objects[nObject].position/100);
    ctx.translate(radio,0);
    ctx.drawImage(img,0,0);
    ctx.restore();
    objects[nObject].position++;
}

使用此代码我可以遍历坐标的图像。

with this code I traslate the images around of a coordinates.

您建议如何改善效能?

更新

我尝试分层,但表演恶化

i try layering but the performances worsens

http ://jsfiddle.net/72nCX/3/

推荐答案

我可以得到你10,000,但有两个主要缺点。

I can get you 10,000 but there are two main drawbacks.


  1. 您可能会注意到图片不完全尊重透明度,可能修复..但超出了此范围

  1. You may notice the images don't respect transparency entirely, its possible to fix.. but that's beyond the scope of this answer.

您必须使用math来执行任何类型的转换,因为标准画布转换矩阵不能应用于ImageData

You will have to use math to do any sort of transformations because the standard canvas transformation matrix can not be applied to ImageData



即时演示



代码和方法的说明



为了获得最快的性能,可以使用canvas和需要使用 ImageData 的大量对象。这是基本上访问每个像素级别的画布元素,并允许你做各种酷的东西。我使用了两种主要方法。

Live Demo

Explanation of the code and methods

So to get the fastest performance possible with canvas and a large number of objects you need to use ImageData. This is accessing the canvas element on a per pixel level basically, and allows you to do all sorts of cool stuff. I used two primary methods.

  • putImageData
  • createImageData

这里还有一个很好的教程,它有点帮助更好地了解。

Also here is a nice tutorial that goes into it a bit to help get a better understanding.

所以我做的是首先为图像创建一个临时画布

So what I did is first I created a temporary canvas for the image

imgToDraw.onload = function () {
    // In memory canvas
    imageCanvas = document.createElement("canvas"),
    iCtx = imageCanvas.getContext("2d");

    // set the canvas to the size of the image
    imageCanvas.width = this.width;
    imageCanvas.height = this.height;

    // draw the image onto the canvas
    iCtx.drawImage(this, 0, 0);

    // get the ImageData for the image.
    imageData = iCtx.getImageData(0, 0, this.width, this.height);
    // get the pixel component data from the image Data.
    imagePixData = imageData.data;

    // store our width and height so we can reference it faster.
    imgWidth = this.width;
    imgHeight = this.height;

    draw();
};

下一页是渲染函数中的主要部分

Next Is the main piece which is in the rendering function

我只是发布相关部分。

// create new Image data. Doing this everytime gets rid of our 
// need to manually clear the canvas since the data is fresh each time
var canvasData = ctx.createImageData(canvas.width, canvas.height),
    // get the pixel data
    cData = canvasData.data;

// Iterate over the image we stored 
for (var w = 0; w < imgWidth; w++) {
    for (var h = 0; h < imgHeight; h++) {
        // make sure the edges of the image are still inside the canvas
        // This also is VERY important for perf reasons
        // you never want to draw outside of the canvas bounds with this method
        if (entity.x + w < width && entity.x + w > 0 &&
            entity.y + h > 0 && entity.y + h < height) {

            // get the position pixel from the image canvas
            var iData = (h * imgWidth + w) * 4;

            // get the position of the data we will write to on our main canvas
            // the values must be whole numbers ~~ is just Math.floor basically
            var pData = (~~ (entity.x + w) + ~~ (entity.y + h) * width) * 4;

            // copy the r/g/b/ and alpha values to our main canvas from 
            // our image canvas data.

            cData[pData] = imagePixData[iData];
            cData[pData + 1] = imagePixData[iData + 1];
            cData[pData + 2] = imagePixData[iData + 2];
            // this is where alpha blending could be applied
            if(cData[pData + 3] < 100){
                cData[pData + 3] = imagePixData[iData + 3];
            }
        }
    }
}

// now put all of that image data we just wrote onto the actual canvas.
ctx.putImageData(canvasData, 0, 0);

主要取消这是,如果你需要在画布上绘制一个可笑的数量的对象您不能使用 drawImage ,像素操作是您的朋友。

The main Take away from this is, if you need to draw a ridiculous number of objects on the canvas you can't use drawImage, pixel manipulation is your friend.

这篇关于在画布上绘制10,000个对象javascript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆