J26*_*261 17 javascript performance html5 canvas drawimage
我需要在画布上绘制超过10,000张图像(32x32像素),但超过2000画的表现非常糟糕.
这是一个小例子:
对象结构 {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++;
}
Run Code Online (Sandbox Code Playgroud)
使用这段代码我可以对坐标周围的图像进行扫描.
您建议什么来提高性能?
更新:
我尝试分层,但表现恶化
Lok*_*tar 50
我可以给你10,000,但有两个主要的缺点.
您可能会注意到图像完全不尊重透明度,可以修复..但这超出了本答案的范围.
您将不得不使用数学进行任何类型的转换,因为标准画布转换矩阵无法应用于ImageData
因此,要使用canvas和大量对象获得最快的性能,您需要使用ImageData.这基本上是在每像素级别访问canvas元素,并允许你做各种很酷的东西.我使用了两种主要方法.
这里还有一个很好的教程,有助于更好地理解它.
所以我做的是首先我为图像创建了一个临时画布
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();
};
Run Code Online (Sandbox Code Playgroud)
Next是渲染功能中的主要部分
我只是张贴相关部分.
// 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);
Run Code Online (Sandbox Code Playgroud)
主要的是,如果您需要在画布上绘制一些无法使用的荒谬物体drawImage,像素操作就是您的朋友.
| 归档时间: |
|
| 查看次数: |
7954 次 |
| 最近记录: |