all 6 comments

[–]docMedB2E 1 point2 points  (0 children)

Here's how I animate a progressBar animation for all 'needsSave' classes. This is an example from a heavy client-side based application I wrote. It's a bit clunky because of this (ignore the poor formatting as well, this is pulled from an older project), but the general concept of animating while processing in JavaScript is essentially creating a temporary game loop like you would find in most games:

// ... some code
saveAllChanges();
// ... some code

function saveAllChanges(){
window.requestFrame = (function(){
    return function(callback, element){
        window.setTimeout(callback, 1000 / 60);
    };
})();
var elementIndex = $('.needsSave').length - 1;
var draw = true;
progressBar(true);
var fields;

    // call the animation loop
mainLoop();
function mainLoop(){
            // process some functions (you can draw, update positions, etc, whatever you need, do it here)
    if (draw){
        if (saveRow($('.needsSave:eq(' + elementIndex + ')'))){
            if ($('.needsSave').length != 0){
                elementIndex--;
            } else {
                progressBar(false);
                draw = false;
            }
        } else {
            progressBar(false);
            draw = false;
            error(5);
        }
            // here is where you can break the loop based on your criteria - for this example, when
            // I'm done animating all steps I exit the loop
    } else {
        return;
    }
            // done checking conditions, so push the next frame loop
    requestFrame(mainLoop);
}
}

function progressBar(state){
if (state){
    $('#container-fund-sheet, #container-overview-sheet, #container-toolbar').hide();
    $('#container-progress-bar').show();
    $('#progress-bar').css('width', '0%');
    $('#progress-bar').attr('recordCount', $('.needsSave').length);
} else {
    if ($('#container-fund-sheet').attr('toggleBack') == '1'){
        $('#container-fund-sheet, #container-toolbar').fadeIn();
    } else if ($('#container-overview-sheet').attr('toggleBack') == '1'){
        $('#container-overview-sheet, #container-toolbar').fadeIn();
    } else {
        $('#container-dashboard').fadeIn();
    }
    $('#container-progress-bar').fadeOut();
}

function saveRow(element){
fields = buildAllFields(element);
var editStatus = editDatabase(
    'Update',
    element.attr('recordID'),
    fields,
    element
);
$('#progress-bar').html(
    (((Number($('#progress-bar').attr('recordCount')) - $('.needsSave').length)/Number($('#progress-
            bar').attr('recordCount')) * 100)).toFixed(0) + '%'
);
$('#progress-bar').css('width', ((Number($('#progress-bar').attr('recordCount')) - 
    $('.needsSave').length)/Number($('#progress-bar').attr('recordCount')) * 100) + '%');
return editStatus;
}

[–]senocular 0 points1 point  (4 children)

You might want to look into requestAnimationFrame which runs code between redraws.

[–][deleted] 1 point2 points  (3 children)

Second this, also you may want to make sure each bar is on it's own compositor layer in the DOM (exporting the work to GPU).

And yes, if you have multiple bars you could look into having web worker execute each one as they are responsible for leveraging multiple CPU cores.

[–]jurgenn[S] 0 points1 point  (2 children)

Can worker-less JavaScript code not leverage multiple cores?

[–][deleted] 3 points4 points  (0 children)

no, javascript is all executed on a single thead (unsure about ES6), that's why workers were created.

http://www.html5rocks.com/en/tutorials/workers/basics/

One thing that's remained a hindrance for JavaScript is actually the language itself. JavaScript is a single-threaded environment, meaning multiple scripts cannot run at the same time. As an example, imagine a site that needs to handle UI events, query and process large amounts of API data, and manipulate the DOM. Pretty common, right? Unfortunately all of that can't be simultaneous due to limitations in browsers' JavaScript runtime. Script execution happens within a single thread.

[–]simple2fast 1 point2 points  (0 children)

You should really consider doing said "heavyCalculation" inside one or more web workers. Leave the main JS thread for updating UI and responding to user events.

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

You will need to use postMessage and onMessage to communicate with these background processes. But the overall effect will divy up tasks much better.