如何让javascript画布画得更快?

时间:2015-12-05 06:43:45

标签: javascript canvas

我有以下代码来显示心电图。我使用画布绘制图形背景(每个2.5毫米尺寸的网格)。稍后我将从数组 array_1 中获取y坐标(x坐标在程序中计算)。这种方法的问题是绘制整个图表需要大约40秒,因为数组 array_1 中有1250个值。我能做的是我可以在一个循环内完成绘图部分,在这种情况下,一旦页面加载就会绘制整个图形。但是,我需要在5秒的时间内完成绘图。不多。不低于。我如何改变代码来做到这一点?请帮忙。

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <canvas id="canvas" width="1350" height="1300" style="background-color: white;"></canvas>
    <script type='text/javascript'>

    var canvas = document.getElementById("canvas");
    var ctxt = canvas.getContext("2d");
    var n1 = 1;
    var n1_x=49; //Graph x coordinate starting pixel.
    var n1_y=72;//Graph y coordinate starting pixel.
    var array_1 = []// array from which y coordinates are taken. Has 1250 elements
     var ctx = canvas.getContext("2d");
    var x=0;
    var y=0;
    var Line_position=-1;
    while(x<=1350)//graph width
    {
        ctxt.lineWidth = "0.5";
        Line_position=Line_position+1;
        if(Line_position%5==0)
        {
            ctxt.lineWidth = "1.5";
        }

        ctxt.strokeStyle = "black";
        ctxt.beginPath();
        ctxt.moveTo(x, 0);
        ctxt.lineTo(x, 1300);
        ctxt.stroke();
        x=x+9.43;

    }

    Line_position=-1;
    while(y<=1300)//graph height
    {
        ctxt.lineWidth = "0.5";
        Line_position=Line_position+1;
        if(Line_position%5==0)
        {
            ctxt.lineWidth = "1.5";
        }

        ctxt.strokeStyle = "black";
        ctxt.beginPath();
        ctxt.moveTo(0, y);
        ctxt.lineTo(1350,y);
        ctxt.stroke();
        y=y+9.43;
    }
   drawWave();
        function drawWave()
        {
          requestAnimationFrame(drawWave);
                ctx.lineWidth = "1";
                ctx.strokeStyle = 'blue';
               ctx.beginPath();
                ctx.moveTo(n1_x- 1, n1_y+array_1[n1-1]);//move to the pixel position
                ctx.lineTo(n1_x, n1_y+array_1[n1]);//Draw to the pixel position
                ctx.stroke();
                n1_x=n1_x+0.374;//Incrementing pixel so as to traverse x axis.
                n1++;
 }

    </script>
</body>
</html>

这是数组: array_1 = [69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69 ,69,69,69,69,69,69,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20 ,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20 ,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20 ,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20 ,20,20,20,20,20,20,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69 ,69,72,72,72,72,72,72,72,73,73,74,74,74,74,74,74,74,73,73,73,73,74,74,74,74 ,73,73,73,73,73,73,73,73,73,73,73,73,73,74,74,74,73,73,73,72,73,73,73,73,73 ,73,73,73,73,73,73,73,73,73,73,72,72,72,71,72,72,72,73,73,73,72,72,72,73,73 ,73,74,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,73,73,73,72,72,72,71,101 ,71,70,70,70,69,68,68,67,67,66,66,67,67,69,70,72,72,72,73,73,74,73,73,73,73 ,73,73,73,73,73,74,76,77,76,70,57,40,22,11,11,22,40,57,69,73,73,71,71,71,72 ,72,73,73,74,74,74,73,72,72,72,72,72,72,72,72,72,72,72,72,71,71,70,70,71,71 ,71,71,70,70,6 9,69,69,69,69,69,69,68,68,68,67,67,66,66,65,65,64,63,63,62,62,62,62,62,62, 62,62,63,63,64,65,66,67,68,68,69,70,71,72,72,72,73,73,73,73,72,72,72,73,73, 73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,73,73,73,73,72,73,73,73,73, 73,73,73,73,73,73,72,72,72,72,72,72,73,73,74,74,74,74,74,74,73,73,72,73,73, 73,74,73,73,72,72,72,73,73,73,72,72,73,73,74,74,73,73,73,73,73,73,73,73,73, 73,73,73,73,73,73,73,73,73,72,72,71,70,70,70,70,70,69,69,68,67,67,67,67,68, 69,71,72,72,73,73,73,73,74,74,74,74,74,73,73,73,73,75,77,78,76,67,53,35,18, 8,10,23,41,58,69,73,72,71,70,71,72,73,73,73,73,73,73,73,73,72,72,73,73,73, 73,72,71,71,70,70,71,71,71,71,71,71,71,71,70,70,69,69,69,69,68,68,67,67,67, 67,67,66,65,65,65,64,63,62,61,61,61,60,60,60,59,60,60,60,61,62,63,65,66,66, 67,68,69,70,71,72,72,72,72,73,73,73,72,72,72,72,72,72,72,73,73,73,73,73,73, 72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,71,71,72,72,73,73,73,72, 72,72,72,72,72,73,73,73,73,73,73,73,73,73,72,73,73,73,73,73,73,72,73,73,73, 73,73,73,73,72,72,72,73,73, 73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,71,71,70,70,69,69, 69,68,67,67,66,65,66,66,68,69,70,71,72,72,73,73,73,73,73,73,74,74,74,74,74, 74,76,78,78,74,64,48,29,13,5,10,26,45,62,71,73,72,71,71,72,73,73,73,73,73, 74,74,74,73,72,72,72,73,73,73,73,73,73,73,72,72,72,72,71,71,71,71,71,71,71, 71,71,70,70,69,69,69,69,68,67,66,66,66,66,65,65,64,63,62,62,61,61,60,60,60, 60,61,62,62,63,64,65,66,67,68,70,71,72,72,72,72,72,72,73,73,73,73,73,73,73, 74,74,75,75,74,74,74,73,73,73,74,73,73,73,73,73,74,74,74,74,74,73,73,73,73, 73,73,73,73,73,73,73,73,73,73,72,72,73,73,74,74,74,73,73,73,73,73,73,73,73, 73,73,72,72,72,72,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, 73,73,73,73,73,73,72,72,73,73,72,72,71,70,70,70,69,69,68,68,67,67,66,67,67, 68,69,70,71,72,73,73,74,74,73,73,73,74,75,75,74,73,73,74,76,78,75,67,52,32, 15,5,8,22,41,59,69,73,72,71,70,71,72,72,73,73,73,73,73,73,73,73,73,72,72, 72,72,72,72,72,72,72,72,71,71,71,70,70,70,70,70,70,70,69,69,69,69,68,68,68, 68,67,67,66,65,65,64,64,64,6 3,62,61,60,60,60,60,60,61,61,62,62,63,64,65,65,66,67,68,69,70,71,71,71,71, 71,71,72,72,73,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72, 72,72,72,72,71,71,71,71,71,71,71,72,72,72,72,72,72,72,72,72,71,71,71,72,72, 73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72, 73,73,74,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,71,71,71,70,70,70, 70,69,69,68,67,67,68,69,71,72,73,73,73,73,73,73,73,73,74,75,75,75,74,74,74, 75,77,77,75,67,52,34,18,10,12,26,45,62,71,74,73,72,72,72,73,74,74,74,75,75, 74,74,74,74,74,74,74,74,74,73,73,73,73,74,74,73,73,73,73,73,73,73,72,72,71, 71,71,71,71,70,70,70,69,69,69,68,68,68,68,67,66,65,64,63,63,62,62,62,63,63, 63,63,64,65,66,67,69,69,70,71,72,72,73,73,74,74,74,74,75,75,76,76,74,72,70, 70,69,69];

3 个答案:

答案 0 :(得分:1)

<强>更新

现在我看到你提供了更多信息,我得到了你想要的东西。

问题是您需要在时间t内绘制固定数量的线段。

由于您不知道每个帧可以花多长时间,因此无法依赖固定的帧速率。另一种方法是只使用当前时间并节省结束时间。

获取开始时间然后每帧绘制所有应该被绘制直到当前时间。由于正在绘制的线段在下一个屏幕刷新之前不会显示,因此您将获得大约16毫秒的时间,因此需要进行调整。

我所做的是跟踪平均帧时间,并用一半的时间来估计何时显示新的画布更新。

它有点迂腐,但也可以展示如何尽可能接近所需的时间。如果你不关心它几毫秒,那么只需删除平均帧时间的东西。在慢速机器上你最多可以休息30ms。

var canvas; // canvas
var ctx; 

function getCanvas () {
    // to do 
    // get canvas and context
}
function drawGrid () {
    // to do
    // draw the grid
}
function drawTimedLine(){
    if(canvas === undefined){ // if the canvas not available get it
       getCanvas();
    }
    // clear the canvas is repeating animation
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawGrid();

    var array_1 = ; // your data


    // All stuff needed for timed animation.
    // The frame you render will not be displayed untill the next
    // vertical refresh which is unknown, Assume it is one frame.
    var startDelay = 1000;      // if Needed time in milliseconds to delay start
    var endTime;                // hold the time that the animation has to end
    var lastDataPoint;          // holds the last point drawn to
    var timeToDraw = 5 * 1000;  // how long the animation should last
    var repeatAfter = 1 *1000;  // if you want to repeat the animatoin
    var frameCount = 0;         // count the frames to get average frame time
    var startTime;              //the start time;
    var numberPoints = array_1.length; // number of points;
    var startX = 49;            // line starts at
    var yOffset = 72;           // line Y offset
    var endX = 512;             // line ends at. 
    var width = endX - startX;  // width  
    var xStep = width / numberPoints;   // X step per point
    var pointsPerMS = numberPoints / timeToDraw; // get how many points per ms should be drawn

    // function to draw
    function drawWave() {
        // variable needed
        var averageframeTime, timeLeft, i, currentTime;
        currentTime = new Date().valueOf();     // gets the time in millisecond;
        if (startTime === undefined) {          // Is this the first frame      
            startTime = currentTime;            // save the start time;
            endTime = currentTime + timeToDraw; // workout when the end time is;
            lastDataPoint = 0;                  // set the data position to the start;
            averageframeTime = 0;               // no frames counted so frame time is zero          
        } else {
            frameCount += 1;                    // count the frames
            // get the average frame time
            averageframeTime = (currentTime - startTime) / frameCount; 
        }
        // get the time this frame
        // will most likely be displayed
        // then calculate how long
        // till the end
        timeLeft = endTime - Math.min(endTime, currentTime + averageframeTime / 2); 

        // now get where we should
        // be when the frame is presented
        pointPos = Math.floor(pointsPerMS * (timeToDraw - timeLeft)); 


        // now draw the points from where we last left of
        // till the new pos;
        ctx.lineWidth = 4;
        ctx.strokeStyle = 'blue';

        ctx.beginPath();
        ctx.moveTo(  // move to first point
            lastDataPoint * xStep + startX,
            array_1[lastDataPoint] + yOffset 
        ); 
        // draw each line from the last drawn to the new position 
        for (i = lastDataPoint + 1; i <= pointPos && i < numberPoints; i++) { 
            // Add the line segment
            ctx.lineTo(
                i * xStep + startX, 
                array_1[i] + yOffset
            );
        }
        ctx.stroke();                   // execute the render commands
        lastDataPoint = pointPos;       // update the last point
        if (pointPos < numberPoints) {  // are we there yet???
            requestAnimationFrame(drawWave); // no so request another frame
        }else{
            // if you want to repeat the animation
            setTimeout(drawTimedLine , repeatAfter ); 
        } 
    }
    // start the line animation with delay if needed
    setTimeout(drawWave,startDelay);
}    

// use this if you want it to start as soon as page is ready.    
document.addEventListener("DOMContentLoaded",drawTimedLine);
// or use if you want it to start when page has images loaded and is ready
// document.addEventListener("load",drawTimedLine);

我还添加了重复动画的功能。如果不需要,只需删除该代码

我的原始回答

不知道速度有什么问题,因为它在我的机器上运行得很好。

设置更好的开始使用

function startFunction(){
   // your code
}
document.addEventListener("DOMContentLoaded",startFunction);

这将等到页面加载并解析页面。图像和其他媒体可能尚未加载,但页面已准备好进行操作。

5秒钟不确定你的意思。假设您可能希望在5秒内完成这项任务。

以下将会这样做。

document.addEventListener("DOMContentLoaded",function() {setTimeout(startFunction,5000);});

我想问为什么一次用requestAnimationFrame 1250绘制一个条目的图表并不是那么多行。如果您添加ctx.beginPath() ctx.moveTo(/*first point*/),则使用ctx.moveTo(/*points*/)循环所有点,然后ctx.stroke()将实时运行,但设备速度最慢。

BTW ctx.lineWidthNumber而不是字符串。你有两个背景吗?将一个上下文用于画布。删除ctxt并使用ctx,最后您不需要将type='text/javascript'添加到脚本代码中,因为Javascript是默认值。

答案 1 :(得分:1)

我可能会做类似这样的任务。正如评论中所提到的,我们需要在每帧中绘制一些数据点。我们绘制的数量取决于浏览器能够提供动画帧的速度。

我已经将值硬编码为4,因为这似乎可以在我的机器上运行,但是由于工作量不多,您可以自己调整代码时间并动态调整此值以便运行动画尽可能接近目标时间。我快速去了,但结果很糟糕,我会将其作为研究或思考的练习留给读者。

通过跟踪我们已经为当前“刷新周期”绘制了多少帧,我们知道为每个帧绘制的第一个点索引数组的距离。

我试图尽可能地参数化代码,但是已经很晚了,我很累,我可能忽略了某些地方。

<!doctype html>
<html>
<head>
<script>
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}

window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
    drawBkg(byId('canvas'), 9.43, 5, "0.5", "1.5", "black");
    drawCurFrame();
}

var dataSamples = [69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,72,72,72,72,72,72,72,73,73,74,74,74,74,74,74,74,73,73,73,73,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,74,74,74,73,73,73,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,71,72,72,72,73,73,73,72,72,72,73,73,73,74,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,73,73,73,72,72,72,71,101,71,70,70,70,69,68,68,67,67,66,66,67,67,69,70,72,72,72,73,73,74,73,73,73,73,73,73,73,73,73,74,76,77,76,70,57,40,22,11,11,22,40,57,69,73,73,71,71,71,72,72,73,73,74,74,74,73,72,72,72,72,72,72,72,72,72,72,72,72,71,71,70,70,71,71,71,71,70,70,69,69,69,69,69,69,69,68,68,68,67,67,66,66,65,65,64,63,63,62,62,62,62,62,62,62,62,63,63,64,65,66,67,68,68,69,70,71,72,72,72,73,73,73,73,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,73,73,73,73,72,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,73,73,74,74,74,74,74,74,73,73,72,73,73,73,74,73,73,72,72,72,73,73,73,72,72,73,73,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,71,70,70,70,70,70,69,69,68,67,67,67,67,68,69,71,72,72,73,73,73,73,74,74,74,74,74,73,73,73,73,75,77,78,76,67,53,35,18,8,10,23,41,58,69,73,72,71,70,71,72,73,73,73,73,73,73,73,73,72,72,73,73,73,73,72,71,71,70,70,71,71,71,71,71,71,71,71,70,70,69,69,69,69,68,68,67,67,67,67,67,66,65,65,65,64,63,62,61,61,61,60,60,60,59,60,60,60,61,62,63,65,66,66,67,68,69,70,71,72,72,72,72,73,73,73,72,72,72,72,72,72,72,73,73,73,73,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,71,71,72,72,73,73,73,72,72,72,72,72,72,73,73,73,73,73,73,73,73,73,72,73,73,73,73,73,73,72,73,73,73,73,73,73,73,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,71,71,70,70,69,69,69,68,67,67,66,65,66,66,68,69,70,71,72,72,73,73,73,73,73,73,74,74,74,74,74,74,76,78,78,74,64,48,29,13,5,10,26,45,62,71,73,72,71,71,72,73,73,73,73,73,74,74,74,73,72,72,72,73,73,73,73,73,73,73,72,72,72,72,71,71,71,71,71,71,71,71,71,70,70,69,69,69,69,68,67,66,66,66,66,65,65,64,63,62,62,61,61,60,60,60,60,61,62,62,63,64,65,66,67,68,70,71,72,72,72,72,72,72,73,73,73,73,73,73,73,74,74,75,75,74,74,74,73,73,73,74,73,73,73,73,73,74,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,73,73,74,74,74,73,73,73,73,73,73,73,73,73,73,72,72,72,72,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,73,73,72,72,71,70,70,70,69,69,68,68,67,67,66,67,67,68,69,70,71,72,73,73,74,74,73,73,73,74,75,75,74,73,73,74,76,78,75,67,52,32,15,5,8,22,41,59,69,73,72,71,70,71,72,72,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,72,72,72,71,71,71,70,70,70,70,70,70,70,69,69,69,69,68,68,68,68,67,67,66,65,65,64,64,64,63,62,61,60,60,60,60,60,61,61,62,62,63,64,65,65,66,67,68,69,70,71,71,71,71,71,71,72,72,73,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,71,71,71,71,71,71,71,72,72,72,72,72,72,72,72,72,71,71,71,72,72,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,73,73,74,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,71,71,71,70,70,70,70,69,69,68,67,67,68,69,71,72,73,73,73,73,73,73,73,73,74,75,75,75,74,74,74,75,77,77,75,67,52,34,18,10,12,26,45,62,71,74,73,72,72,72,73,74,74,74,75,75,74,74,74,74,74,74,74,74,74,73,73,73,73,74,74,73,73,73,73,73,73,73,72,72,71,71,71,71,71,70,70,70,69,69,69,68,68,68,68,67,66,65,64,63,63,62,62,62,63,63,63,63,64,65,66,67,69,69,70,71,72,72,73,73,74,74,74,74,75,75,76,76,74,72,70,70,69,69 ];

function drawBkg(canvasElem, squareSize, numSquaresPerBlock, minorLineWidthStr, majorLineWidthStr, lineColStr)
{
    var nLinesDone = 0;
    var i, curX, curY;
    var ctx = canvasElem.getContext('2d');
    ctx.clearRect(0,0,canvasElem.width,canvasElem.height);

    // draw the vertical lines
    curX=0;
    ctx.strokeStyle = lineColStr;
    while (curX < canvasElem.width)
    {
        if (nLinesDone % numSquaresPerBlock == 0)
            ctx.lineWidth = majorLineWidthStr;
        else
            ctx.lineWidth = minorLineWidthStr;

        ctx.beginPath();
        ctx.moveTo(curX, 0);
        ctx.lineTo(curX, canvasElem.height);
        ctx.stroke();

        curX += squareSize;
        nLinesDone++;
    }

    // draw the horizontal lines
    curY=0;
    nLinesDone = 0;
    while (curY < canvasElem.height)
    {
        if (nLinesDone % numSquaresPerBlock == 0)
            ctx.lineWidth = majorLineWidthStr;
        else
            ctx.lineWidth = minorLineWidthStr;

        ctx.beginPath();
        ctx.moveTo(0, curY);
        ctx.lineTo(canvasElem.width, curY);
        ctx.stroke();

        curY += squareSize;
        nLinesDone++;
    }
}

// position that will be treated as 0,0 when drawing our points.
var originX=49;
var originY=72;

function drawSamples(nSamplesToDraw, firstSample, lineWidthStr, lineColourStr)
{
    var can = byId('canvas');
    var ctx = can.getContext('2d');

    ctx.strokeStyle = lineColourStr;
    ctx.lineWidth = lineWidthStr;
    console.log(firstSample);
    ctx.beginPath();

    ctx.moveTo( originX+firstSample-1, dataSamples[firstSample-1]+originY );
    for (var i=0; i<nSamplesToDraw; i++)
    {
        var curSample = dataSamples[i + firstSample];
        ctx.lineTo( originX+firstSample+i, curSample+originY );
    }
    ctx.stroke();
}

var curFrame=0;
var nPointsPerFrame = 4;
function drawCurFrame()
{
    if ((dataSamples.length - (nPointsPerFrame * curFrame)) < nPointsPerFrame)      // will we over-run the end of the array of datapoints?
    {
        curFrame = 0;                                                               // if so, reset
        drawBkg(byId('canvas'), 9.43, 5, "0.5", "1.5", "black");
    }
    drawSamples(nPointsPerFrame, nPointsPerFrame*curFrame, "1", "blue");
    curFrame++;
    requestAnimationFrame( drawCurFrame );
}
</script>

<style>
#canvas
{
    border: solid 1px black;
    background-color: #FFFFFF;
}
</style>

</head>
<body>
    <div id='txt'></div>
    <canvas id="canvas" width="1350" height="1300"></canvas>

</body>
</html>

答案 2 :(得分:0)

1)绘制1000行不能花那么长时间,即使是100000行也不会超过10毫秒。看看时间丢失的地方 2)您的代码的核心问题是它缺乏模块性。将代码拆分为几个清晰的函数,将参数分组为几个对象,正确命名和缩进。

下面一个(不完整但有效的)示例,看看它的外观。

var cv, ctx;
var data = null;
var debug = true;

// ---------------------------------------

// define here all graphic related parameters
var gfxParams = {
  canvasWidth: 600,
  canvasHeight: 600,
  gridColor: '#A66',
  gridSpacing: 10,
  gridLineWidth: 0.5,
  gridStrongLinesEvery: 5,
  lineColor: '#AEB',
  lastLineColor: '#8A9' // , ...
};

// define here all animation related parameters
var animationParams = {
  duration: 5,
  startTime: -1
}


// ---------------------------------------
//              main
// ---------------------------------------

window.onload = function() {
  data = getData();
  setupCanvas(data);
  launchAnimation();
}

// ---------------------------------------

// 
function setupCanvas(data) {
  cv = document.getElementById('cv');
  cv.width = gfxParams.canvasWidth;
  cv.height = gfxParams.canvasHeight;
  ctx = cv.getContext('2d');
  // here you should translate and scale the context
  // so that it shows your data.
}

function drawGrid(ctx) {
  var i = 0,
    pos = 0,
    lw = gfxParams.gridLineWidth;
  ctx.fillStyle = gfxParams.gridColor;
  var vLineCount = gfxParams.canvasWidth / gfxParams.gridSpacing;
  for (i = 0; i < vLineCount; i++) {
    pos = i * gfxParams.gridSpacing;
    ctx.fillRect(pos, 0, lw, gfxParams.canvasHeight);
  }
  var hLineCount = gfxParams.canvasHeight / gfxParams.gridSpacing;
  for (i = 0; i < hLineCount; i++) {
    pos = i * gfxParams.gridSpacing;
    ctx.fillRect(0, pos, gfxParams.canvasWidth, lw);
  }
}

function animate() {
  requestAnimationFrame(animate);
  var now = Date.now();
  // erase screen
  ctx.clearRect(0, 0, gfxParams.canvasWidth, gfxParams.canvasHeight);
  // draw grid
  drawGrid(ctx);
  // draw lines 
  var lastIndex = getLastDrawnIndex(data, now - animationParams.startTime);
  drawLines(ctx, data, lastIndex);
  if (debug) {
    ctx.save();
    ctx.fillStyle = '#000';
    ctx.fillText(lastIndex + ' lines drawn. Time elapsed : ' + (now - animationParams.startTime), 10, 10);
    ctx.restore();
  }
}

// comment
function launchAnimation() {
  requestAnimationFrame(animate);
  animationParams.startTime = Date.now();
}

// comment
function getData() {
  var newData = [];
  for (var i = 0; i < 500; i++) {
    newData.push([Math.random() * 600, Math.random() * 600]);
  }
  return newData;
}

// comment
function getLastDrawnIndex(data, timeElapsed_ms) {
  var timeElapsed = timeElapsed_ms / 1000;
  if (timeElapsed >= animationParams.duration) return data.length - 1;
  return Math.floor(data.length * timeElapsed / animationParams.duration);
}

function drawLines(ctx, data, lastIndex) {
  ctx.strokeStyle = gfxParams.lineColor;
  // other ctx setup here.
  for (var i = 0; i < lastIndex - 1; i++) {
    drawLine(ctx, data[i], data[i + 1]);
  }
  ctx.strokeStyle = gfxParams.lastLineColor;
  drawLine(ctx, data[lastIndex - 1], data[lastIndex]);
}

function drawLine(ctx, p1, p2) {
  ctx.beginPath();
  ctx.moveTo(p1[0], p1[1]);
  ctx.lineTo(p2[0], p2[1]);
  ctx.stroke();
}
<canvas id='cv'></canvas>