简体   繁体   中英

How to reduce lag in fabric.js recursion-based function

I am animating boxes using fabric.js to appear (canvas.add) onscreen as though they are being stitched on (see image).

刺绣之字形

Due to the nature of the thing, I've implemented a recurring function with a timer. As it runs, the more it starts to lag. I'd like to know if there's a way to reduce the lag. It's especially bad at wide screen sizes (I'm able to get ~1880px) but unfortunately the design I'm working with has this element full-width (not just content).

I've included the recurring function below, but it's not much good without the rest, so check out the Fiddle. Please forgive the implementation - I got a stack overflow (hah) error from nesting groups too many times, hence the kludge-y group/item/counter traversal with a single array.

-- Fiddle HERE --

I suspect it may be the sheer capacity of the objects rendering onscreen, as the lag is noticeably reduced by running just one line at a time (instead of all 3), but I just want to wipe across once and move on with the animation from there (sliding in stock images, text, CTA, etc.). Can anybody suggest a better solution? Most noticeable at larger screen sizes - I've left instructions in the Fiddle to test.

function embroider(obj,i){

    var iOffset = Math.floor(i/perLine);

    for(whichZigzag=0;whichZigzag<numZigzags;whichZigzag++){
        var whichGroup = (iOffset+(whichZigzag*numLines));
        var whichStitch = (i-(iOffset*perLine));
        for(four=0;four<4;four++, whichStitch++){
            canvas.add(obj[whichGroup].item(whichStitch));
        }
    }

    i+=4;

    if(i<perZigzag){
        setTimeout(function(){ // dont trigger immediately
            embroider(obj,i);
        },100);
    }
}

I'm mostly a lurker, so please let me know if my question and/or Fiddle suck and I'll try to improve.

The current lag is because each time you add an object to the canvas, it is re-rendered to display that object.

There is a property renderOnAddRemove which you can set to false for the Canvas. This will disable the automatic re-rendering that happens after each canvas.add() . You can then call canvas.renderAll() after the for loop, once all your objects are added.

Here is what Documentation says about this property:

Indicates whether fabric.Collection.add, fabric.Collection.insertAt and fabric.Collection.remove should also re-render canvas. Disabling this option could give a great performance boost when adding/removing a lot of objects to/from canvas at once (followed by a manual rendering after addition/deletion)

I have edited your fiddle. You can check it here : http://jsfiddle.net/4srj2sc8/3/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM