最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to optimize drawing a lot elements on canvas JS? - Stack Overflow

programmeradmin3浏览0评论

I have a lot of elements and mousemove method which, when selecting an item does redraw canvas.

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();
    }
}

How to optimize this process, since it runs through all the elements of this highly expensive? May be used async method, but i'm not understand how to apply him?

I have a lot of elements and mousemove method which, when selecting an item does redraw canvas.

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();
    }
}

How to optimize this process, since it runs through all the elements of this highly expensive? May be used async method, but i'm not understand how to apply him?

Share Improve this question edited Sep 25, 2012 at 1:59 Artem Zubkov asked Sep 24, 2012 at 13:16 Artem ZubkovArtem Zubkov 5582 gold badges14 silver badges29 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 6

Your calls to save, restore and closePath do nothing as they are written. Remove them.

save and restore copy alllll of the canvas state and should be rarely if ever used. In a perfect performant world the only reason you'll ever need to use them is to reset the clipping region.

Draw one and only one path, and fill (and stroke) it only once, at the end.

Like this:

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!
}

Depending on what you're doing its very possible there are more optimizations to be had, but that should help!

Hope your project goes well.

There's a great article on optimizing canvas operations, many of which might apply to you.

Probably the easiest to start with is moving the beginPath() and closePath() calls out of your loop, and instead use moveTo() in between the segments, as well as drawing your canvas off screen and then copying it over to the display canvas.

You could also reverse your loop, assuming it's ok to draw everything in reverse order, as jsperf shows this to be quicker. A while loop is even quicker still.

example

var i = nodes.length();
while (i--) {
    // ...do stuff...
}

Another performance tip: cache your Math.PI * 2 result.

As it is, javascript is getting PI from an object, then multiplying it. The value is always going to be the same so just add a constant

example

const PI_TIMES_TWO = 6.28; //or whatever degree of accuracy you want.

...

ctx.arc(item.x, item.y, item.r, 0, PI_TIMES_TWO, true);
发布评论

评论列表(0)

  1. 暂无评论