【发布时间】:2026-02-11 12:35:01
【问题描述】:
我一直在开发一款游戏,它需要每帧渲染和旋转数千个非常小的图像(20^20 像素)。提供了一个示例 sn-p。
我已经使用了我知道的所有技巧来加速它以提高帧速率,但我怀疑我还可以做其他事情来优化它。
目前的优化包括:
- 用显式转换替换保存/恢复
- 避免缩放/尺寸转换
- 明确目标大小而不是让浏览器猜测
- requestAnimationFrame 而不是 set-interval
已尝试但未出现在示例中:
- 将对象批量渲染到其他屏幕外画布,然后再编译(降低性能)
- 避免浮点位置(由于放置精度而需要)
- 不在主画布上使用 alpha(由于 SO sn-p 渲染,未在 sn-p 中显示)
//initial canvas and context
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
//create an image (I) to render
let myImage = new OffscreenCanvas(10,10);
let myImageCtx = myImage.getContext('2d');
myImageCtx.fillRect(0,2.5,10,5);
myImageCtx.fillRect(0,0,2.5,10);
myImageCtx.fillRect(7.5,0,2.5,10);
//animation
let animation = requestAnimationFrame(frame);
//fill an initial array of [n] object positions and angles
let myObjects = [];
for (let i = 0; i <1500; i++){
myObjects.push({
x : Math.floor(Math.random() * 800),
y : Math.floor(Math.random() * 800),
angle : Math.floor(Math.random() * 360),
});
}
//render a specific frame
function frame(){
ctx.clearRect(0,0,canvas.width, canvas.height);
//draw each object and update its position
for (let i = 0, l = myObjects.length; i<l;i++){
drawImageNoReset(ctx, myImage, myObjects[i].x, myObjects[i].y, myObjects[i].angle);
myObjects[i].x += 1; if (myObjects[i].x > 800) {myObjects[i].x = 0}
myObjects[i].y += .5; if (myObjects[i].y > 800) {myObjects[i].y = 0}
myObjects[i].angle += .01; if (myObjects[i].angle > 360) {myObjects[i].angle = 0}
}
//reset the transform and call next frame
ctx.setTransform(1, 0, 0, 1, 0, 0);
requestAnimationFrame(frame);
}
//fastest transform draw method - no transform reset
function drawImageNoReset(myCtx, image, x, y, rotation) {
myCtx.setTransform(1, 0, 0, 1, x, y);
myCtx.rotate(rotation);
myCtx.drawImage(image, 0,0,image.width, image.height,-image.width / 2, -image.height / 2, image.width, image.height);
}
<canvas name = "canvas" id = "canvas"></canvas>
【问题讨论】:
标签: javascript canvas optimization drawimage