6

I am working with canvas. I have draw a set of lines. Here is my sample code

for(var i = 0 ; i< points.length; i++){
var point = points[i];

setInterval(function() {
  ctx.strokeStyle = "black";
  ctx.moveTo(point.startX, point.startY);
  ctx.lineTo(point.startX1, point.startY1); 
  ctx.stroke();
 }, 500);​
}

This code draws line after every 0.5 seconds. But I wish to animate it progressively. So kindly help to draw a line progressively.

This screen shot show the output. I made this possible in SVG. But I need the same in canvas.

enter image description here

Jaya
  • 253
  • 2
  • 3
  • 9
  • The number 500 at the end of your statement represents the interval (in miliseconds) in which the function will repeat. Try putting a smaller number (or even just 1) and that might do the trick. – NDraskovic Aug 25 '14 at 07:05
  • yes @NDraskovic . But the duration of animation is reduced. :( So suggest some other way if possible – Jaya Aug 25 '14 at 07:12
  • you might have to experiment with the parameters of your animation, my suggestion is to reduce the time interval, but also reduce the length of the line that is drawn in that interval. That way you will effectively prolong the animation. From the code you posted, I assume that means adding more points into the points[] array – NDraskovic Aug 25 '14 at 07:15
  • take a look at this http://www.html5canvastutorials.com/advanced/html5-canvas-linear-motion-animation/, it does something similar to what you need (lines 30-51), you just omit the part where it clears the previous state – NDraskovic Aug 25 '14 at 07:23
  • Thanks NDraskovic hope this will help.. – Jaya Aug 25 '14 at 07:43
  • Jeshua has an inventive solution for progressively drawing paths here: http://stackoverflow.com/questions/25442709/draw-html5-javascript-canvas-path-in-time/25451821#comment39717566_25451821 – markE Aug 25 '14 at 16:58
  • This code does the needful --- [link Jsfiddle](http://jsfiddle.net/UtmTh/).. – Jaya Aug 26 '14 at 03:54

2 Answers2

3
<!DOCTYPE html>
<html>
    <head>
        <title>Parent selector</title>
    </head>
<body>
<canvas height="300px" width="500px" id="canva"></canvas>
<script>
    var canva = document.getElementById('canva'),
        ctx = canva.getContext('2d');

    var Point = function (x, y) {
        this.startX = x;
        this.startY = y;
    };
    var points = [new Point(1, 2), 
                  new Point(10, 20), 
                  new Point(30, 30), 
                  new Point(40, 80), 
                  new Point(100, 100), 
                  new Point(120, 100)];

    //goto first point
    ctx.strokeStyle = "black";
    ctx.moveTo(points[0].startX, points[0].startY);

    var counter = 1,
    inter = setInterval(function() {
        //create interval, it will
        //iterate over pointes and when counter > length
        //will destroy itself
        var point = points[counter++];
        ctx.lineTo(point.startX, point.startY); 
        ctx.stroke();
        if (counter >= points.length) {
           clearInterval(inter);
        }
        console.log(counter);
    }, 500);
    ctx.stroke();
</script>
    </body>
</html>
Ivan Ivanov
  • 2,076
  • 16
  • 33
  • Hi Sorry.. :( This is what my code does. Draw a line, after 500ms delay draw another line and so on.. But i need like progressive as like in screen shot. Could you suggest any other way if possible ?? – Jaya Aug 25 '14 at 08:25
  • See upd. There is no background and other features. But it progressively draws diagram. More detailed questions, please. – Ivan Ivanov Aug 25 '14 at 08:33
  • Ya.. As I mentioned, that is generated in SVG using jquery's animate method. I am in need of any other approach which bring this o/p other than setInterval. Its just an reference, background doesn't matters. I just saying about the line. Thanks. – Jaya Aug 25 '14 at 09:02
0
async function aWaitF(ctx, index, ary) {

        if (!ary) return;

        for (let i = 0; i < ary.length; i++) {

            let cur = {};
            cur.x = name_pos[i].x;  // x position
            cur.val = ary[i].Y - 0;
            cur.y = y_h - y_h * ((ary[i].Y - 0) / series_max); // y position
            let prev = {};
            let next = {};
            let font_pos = null;

            if (i === 0) {

            } else {
                prev.val = ary[i - 1].Y - 0;
                prev.x = name_pos[i - 1].x;
                prev.y = t + y_h - y_h * ((ary[i - 1].Y - 0) / series_max);
                next.val = ary[i + 1] ? ary[i + 1].Y - 0 : 0;
                ctx.lineWidth = 0.5;

                **await orderRender();**

                function orderRender() {
                    return new Promise(resolve => {
                        let w = cur.x - prev.x;
                        let h = cur.y - prev.y;
                        **let rad = Math.atan2(h, w);** 

                        let x = cur.x > prev.x ? prev.x : cur.x;
                        let y = cur.y > prev.y ? prev.y : cur.y;
                        **let imgData = ctx.getImageData(x, y, w, h);**


                        let timer = requestAnimFrame(drawLine);
                        let num = 0;

                        function drawLine() {
                            **ctx.putImageData(imgData, x, y);**
                            ctx.beginPath();
                            ctx.moveTo(prev.x, prev.y);
                            let newX = prev.x + num;
                            let newH = Math.tan(rad) * num;
                            let newY = prev.y + newH;
                            // num += (ary.length - i) * 10;
                            num += 5;

                            ctx.lineTo(newX, newY);
                            ctx.stroke();
                            timer = requestAnimFrame(drawLine);
                            if (num >= w) {
                                ctx.beginPath();
                                ctx.moveTo(prev.x, prev.y);
                                ctx.lineTo(cur.x, cur.y);
                                ctx.stroke();
                                window.cancelAnimationFrame(timer);
                                resolve();
                            }
                        }
                    });
                }
            }
        }
    }
lczapski
  • 4,026
  • 3
  • 16
  • 32