仅在循环完成后才显示for循环中的HTML Canvas

时间:2018-01-25 00:22:46

标签: javascript jquery canvas html5-canvas

我在制作进度图时遇到了一些麻烦。这是我第一次使用canvas,所以我对这个概念有点新意。这个页面将成为学校作业的一个小素数基准。我还没有完成算法,所以现在才算数。我希望有一个图表向用户显示基准测试的进度,因此它看起来不像页面刚刚冻结。我已经将基准测试分解为“sprint”,设备将在一段时间内计算数字,然后更新图形。问题是,图表似乎直到“基准”结束才更新。有什么建议吗?

javascript在下面(execBench可能是最相关的函数):

function startBench() {
    // move to benchmark display
    //showPage("bench");
    jQuery.mobile.changePage("#bench");
    setTimeout(
        function () {
            // run benchmark
            var score = execBench(10);
            //set score and move page
            $(".result").text(score);
            setTimeout(function () {
                showPage("result");
            }, 4000);

        }, 2000);
}

function debugmsg(message) {
    console.log(message);
}

function execBench(time) {
    var graphUpdateRate = 2; // horizontal "resolution" of graph/sprint length in s
    var sprintCount = Math.floor(time / graphUpdateRate);
    debugmsg("Running " + sprintCount + " " + graphUpdateRate + "-second sprints");
    var currentTime = new Date();
    var sprintDeadline = currentTime;
    var counter = 0; // "score" for the end, # of primes generated
    var lastPrime = 0;
    var record = []; // datapoints for graph

    for (var i = 0; i < sprintCount; i++) {
        
        // perform calculations
        sprintDeadline = incrementDate(new Date(), graphUpdateRate);
        while (currentTime < sprintDeadline) {
            currentTime = Date.now();
            lastPrime = generatePrime(lastPrime);
            counter++;
        }

        // report progress
        record.push(counter);
        drawGraph(document.getElementById('progGraph'), record, sprintCount);
    }
    return counter;
}

function generatePrime(min) {
    //placeholder for algorithm
    min++;
    return min;
}

function drawGraph(canvas, dataPoints, maxPoints) {
    var context = canvas.getContext('2d');
    var width = canvas.width;
    var height = canvas.height;
    var xIncrement = width / maxPoints;
    var xBegin = 0;
    var prevPoint = 0;
    var yScale = -1 * height / Math.max(...dataPoints);

    //reset canvas
    canvas.width = canvas.width;
    context.clearRect(0, 0, canvas.width, canvas.height);

    //move context to bottom right and set scale
    context.translate(0, height);
    context.scale(1, 1);

    context.strokeStyle = "#ed1e79";

    for (dataPoint in dataPoints) {
        currentPoint = (dataPoints[dataPoint] * yScale);

        context.beginPath();
        context.moveTo(xBegin, prevPoint);
        context.lineTo(xBegin + xIncrement, currentPoint);
        context.lineWidth = 3;
        context.lineCap = 'round';
        context.stroke();

        prevPoint = currentPoint;
        xBegin += xIncrement;
    }

    debugmsg(Math.max(...dataPoints));
    return;
}

function incrementDate(date, seconds) {
    return new Date(date.getTime() + (seconds * 1000));
}

2 个答案:

答案 0 :(得分:0)

作为使用requestAnimationFrame()的示例,您可以尝试这样的事情。

&#13;
&#13;
function execBench(time) {
    var graphUpdateRate = 2; // horizontal "resolution" of graph/sprint length in s
    var sprintCount = Math.floor(time / graphUpdateRate);
    debugmsg("Running " + sprintCount + " " + graphUpdateRate + "-second sprints");
    var currentTime = new Date();
    var sprintDeadline = currentTime;
    var counter = 0; // "score" for the end, # of primes generated
    var lastPrime = 0;
    var record = []; // datapoints for graph

    var i = 0;
    (function drawSprint() {
    
        // perform calculations
        sprintDeadline = incrementDate(new Date(), graphUpdateRate);
        while (currentTime < sprintDeadline) {
            currentTime = Date.now();
            lastPrime = generatePrime(lastPrime);
            counter++;
        }

        // report progress
        record.push(counter);
        drawGraph(document.getElementById('progGraph'), record, sprintCount);
        
        i++;
        if (i < sprintCount) {
          requestAnimationFrame(drawSprint);
        }
    })();
    
    return counter;
}
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

您的while循环是“阻止”。它会占用CPU,不允许使用javascript和计算机上的其他任何东西来做任何事情。

而是使用setTimeout(fn, t)来安排下一次更新。

setTimeout()无阻止。它的fn将在t milliseonds时间内(或之后不久)在一个新的事件线程中执行。

在setTimouts之间,您的计算机处理器将具有指示graphich卡呈现画布的能力。