如何在画布JS上优化绘制很多元素?

art*_*zub 1 javascript canvas html5-canvas

我有很多元素和mousemove方法,当选择一个项目时会重绘画布.

function redraw(ctx) { // ctx - canvas context
    if (!needRedraw) 
        return;
    ctx.save();
    ctx.clearRect(0, 0, w, h);
    drawItems(ctx);
    ctx.restore();
}

function drawItems(ctx) {
    var l = nodes.length(); // array of elements for drawing (from 100 to 100000)
    for(var i = 0; i < l; i++) {
        var item = nodes[i];
        ctx.beginPath();
        ctx.strokeStyle = colors(item.type);
        ctx.fillStyle = fill(item);
        ctx.arc(item.x, item.y, item.r, 0, Math.PI * 2, true);
        ctx.fill();
        ctx.stroke();
        ctx.closePath();
    }
}
Run Code Online (Sandbox Code Playgroud)

如何优化这个过程,因为它贯穿了这个非常昂贵的所有元素?可能是使用异步方法,但我不明白如何应用他?

Sim*_*ris 6

您对来电save,restoreclosePath什么也不做,因为他们写的.删除它们.

saverestore复制画布状态的alllll,如果使用的话应该很少.在一个完美的高性能世界中,您需要使用它们的唯一原因是重置剪切区域.

绘制一条且只有一条路径,最后填充(并描边)一次.

像这样:

function redraw(ctx) { // ctx - canvas context
    if (!needRedraw) 
        return;
    ctx.clearRect(0, 0, w, h);
    drawItems(ctx);
}

function drawItems(ctx) {
    var l = nodes.length(); // array of elements for drawing (from 100 to 100000)
    ctx.beginPath(); //outside of loop!
    for(var i = 0; i < l; i++) {
        var item = nodes[i];
        ctx.moveTo(item.x+item.r,item.y); // set up subpath to be at the right point
        ctx.arc(item.x, item.y, item.r, 0, Math.PI * 2, true);
    }
    ctx.fill();     //outside of loop!
    ctx.stroke();   //outside of loop!
}
Run Code Online (Sandbox Code Playgroud)

根据你正在做的事情,它有可能有更多的优化,但这应该有所帮助!

希望你的项目顺利进行.