Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw arc with increasing radius?

I am drawing an arc which increases gradually and turns in to a circle.On completion of animation(arc turning in to a circle) i want to draw another circle with increased radius with the previous circle persisting and the second animation continuing.

Arc to circle fiddle

After the circle is drawn,it gets washed out which is something that I dont want and continue the second animation. Some unnecessary animation appears after the completion.

What should I do?

MyCode:

    setInterval(function(){
        context.save();
        context.clearRect(0,0,500,400);
        context.beginPath();
        increase_end_angle=increase_end_angle+11/500;
        dynamic_end_angle=end_angle+increase_end_angle;
        context.arc(x,y,radius,start_angle,dynamic_end_angle,false);
        context.lineWidth=6;
        context.lineCap = "round";
        context.stroke();
        context.restore();
           if(dynamic_end_angle>3.5*Math.PI){  //condition for if circle completion
                draw(radius+10);//draw from same origin and increasd radius
           }
    },66);

window.onload=draw(30);

UPDATE:when should i clear the interval to save some cpu cycles and why does the animation slows down on third circle ??

like image 654
user2617915 Avatar asked Mar 23 '23 23:03

user2617915


2 Answers

First of all, about the flicker: you are using setInterval and not clearing it for the next draw(). So there’s that.

But I’d use a completely different approach; just check the time elapsed since the start, and draw an appropriate number of circles using a loop.

var start = new Date().getTime();

var timePerCircle = 2;
var x = 190, y = 140;

function draw() {
    requestAnimationFrame(draw);
    g.clearRect(0, 0, canvas.width, canvas.height);

    var t = (new Date().getTime() - start) / 1000;
    var circles = t / timePerCircle;
    var r = 30;

    do {
        g.beginPath();
        g.arc(x, y, r, 0, Math.PI * 2 * Math.min(circles, 1));
        g.stroke();
        r += 10;
        circles--;
    } while(circles > 0);
}

draw();
like image 72
Ry- Avatar answered Apr 05 '23 12:04

Ry-


This snippet from your code has some flaw.

if(dynamic_end_angle>3.5*Math.PI){  //condition for if circle completion
    draw(radius+10);//draw from same origin and increased radius
}

The recursive call to draw() will continue to run after the first circle was drawn completely. This is why the performance will be slow down immediately. You need to somehow block it.

I did a simple fix, you can polish it if you like. FIDDLE DEMO

My fix is to remove context.clearRect(0, 0, 500, 400); and change the new circle drawing logic to:

if (dynamic_end_angle > 3.5 * Math.PI) { //condition for if circle completion
    increase_end_angle = 0; // this will prevent the draw() from triggering multiple times.
    draw(radius + 10); //draw from same origin.
}

In this stackoverflow thread, it mentions how to make it more smooth. You'd better use some drawing framework since the optimization needs a lot of work.

like image 44
zs2020 Avatar answered Apr 05 '23 13:04

zs2020