Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to go about creating a pie-chart like countdown with jQuery?

I'm trying to code something like this -

enter image description here

I'd love to add my coding attempt, only I don't really have a clue. When googling stuff like "jQuery countdown", "pie chart" etc. I find only plugins, where I want to code it myself. I'm not even sure whether this should be done with html5 canvas, jQuery or both..

What should be my first step?

like image 938
Roy Avatar asked Oct 22 '22 19:10

Roy


1 Answers

Drawing a "pie" section of a circle is a fairly trivial task.

For example:

ctx.fillStyle = "#f00";
ctx.beginPath();
ctx.moveTo(50,50);
ctx.arc(50,50,50, sta, sta + 2*Math.PI*pct);
ctx.fill();

The above code will draw an arc with a radius of 50 pixels. the forth and fifth parameters determine where the arc starts and ends. In your case, you want:

var sta = -Math.PI/2; // this is -90 degrees (or "up")

The variable pct is the percentage of the circle to be filled.

The real objective of your question is the Timer. I've created a simple Timer class that is very flexible with its output:

function Timer(duration /* in ms */ , props) {
    this.ontick = props && typeof props.ontick === "function" ? props.ontick : function() {};
    this.onend = props && typeof props.onend === "function" ? props.onend : function() {};
    this.interval = props && typeof props.interval === "number" ? props.interval : 1000 / 10;
    this.elapsed = 0;

    var running = false,
      start, end, self = this;

    this.start = function() {
      if (running) return this;

      start = new Date().getTime();
      end = start + duration;
      tick();
      running = true;

      return this;
    };

    function tick() {
      var now = new Date().getTime();
      self.ontick.call(self);
      self.elapsed = now - start;

      if (now < end) setTimeout(tick, self.interval);
      else self.onend.call(self);
    }
  }

Very basic usage of the Timer class could be something like this:

var timer = new Timer(10 * 1000, {
    ontick:function(){
        console.log(this.elapsed);
    },
    onend:function(){
        console.log('all done');
    }
}).start();

The nice thing about this Timer implementation is that it isn't cluttered with logic unrelated to counting down time, so it is very reusable.

I've created a sample of the output you would like here: http://jsfiddle.net/9jZsb/6/
You can see that I'm creating the animation myself, but it should be trivial to incorporate other libraries into this solution to accomplish a similar effect.

like image 64
Shmiddty Avatar answered Oct 24 '22 12:10

Shmiddty