Win an Ipad
  Developer   Tutorials   Advanced tutorials   Working with timers: ...
Lesson 1

Working with timers: Creating analog clock and a countdown

Both, the analog clock and digital countdown are created in a separate layers which can be easily reused in your projects. Also, some properties for the most important settings have been added to the layers to customize control to the requirements.

Because you should understand the very basics at this point, we will talk mostly about the timers.

Analog clock

The analog clock indicates the actual time using two or three hands moving on the dial. The most common clock face is divided into twelve parts representing the hours. Each of these parts is divided into five smaller sections for representing the minutes or seconds. The hands are moving round the clock face to indicate the number of hours, minutes and seconds.

Clock face

The clock face is a circle divided into 12 sections for hours and 60 sections for minutes. The whole circle has 360 degrees meaning that the angle of one section is six degrees (360°/60). Every smaller section (for minutes / seconds) is bounded by two shorter lines. The longer interval for hours has thirty degrees (360/12) meaning that it consists from five shorter intervals. The longer interval is bounded by two longer lines.

Example: the clock's face theory

Only few lines of code are need to draw the whole clock face that are in the drawClockFace method which is called from the layer's draw method. The drawClockFace method moves the canvas base point (0, 0) to the point of the clock centre. Then it rotates the canvas 60times and draws the desired line. Normally it draws short line for minute intervals, but on every fifth step it draws longer line for the hour interval.  When whole clock face is drawn, the canvas is restored into its default state.

function drawClockFace(canvas)
{
   // save the default canvas state
   canvas.save();
   // move canvas to the centre of the clock's face
   canvas.translate(this._clockX, this._clockY);
   for (var i = 1; i < 61; i++) {
       // rotate canvas by 6 degrees
       canvas.rotate(6);
       if (i%5 == 0)
           canvas.drawLine(this._clockWidth / 2, 0, this._clockWidth / 2 - this._clockWidth / 10, 0, this._longLine);
       else
           canvas.drawLine(this._clockWidth / 2, 0, this._clockWidth / 2 - this._clockWidth / 20, 0, this._shortLine);
   }
   // restor the canvas' default position
   canvas.restore();
}

Actual time

To get the actual time the Date class is used that works with the system date and time.  When a new instance of the Date class is created it holds information about the actual time (the moment when the instance was created). According to this information we can easily calculate the angle of clock' hands.

In order to achieve better FPS (frames per seconds) thus better performance, the hands angle is not being calculated in the draw method. Instead, the process method was created which calculates the angle every 25ms.

Example: calculating clock hands angle

function process()
{
   // get current date (hour, minute, second)
   var t = new Date();
   // second angle
   this._secondAngle = t.second*1.0 / 60 * 360;
   this._minuteAngle = t.minute*1.0 / 60 * 360 /* whole part*/ + (t.second * 1.0 / 60)*6/*second part for smooth run*/;
   this._hourAngle = (t.hour%12)*1.0 / 12 * 360 /* whole part*/ + (t.minute * 1.0 / 60)*30/*minute part for smooth run*/;
}

Clock hands

To redraw the layer to show the actual time, a draw method is called. In this method is firstly called the drawClockFace method to draw clock face and then according to pre calculated values of angle for every hand are drawn also three hands (for hour, minute and seconds).

Example: drawing the clock

function draw(canvas)
{
   super.draw(canvas);    this.drawClockFace(canvas);    canvas.save();
   canvas.translate(this._clockX, this._clockY);
   canvas.rotate(this._secondAngle);
   canvas.drawLine(0, 0, 0, this._clockWidth / -2 + this._clockWidth / 20, this._secondLine);
   canvas.restore();    canvas.save();
   canvas.translate(this._clockX, this._clockY);
   canvas.rotate(this._minuteAngle);
   canvas.drawLine(0, 0, 0, this._clockWidth / -2 + this._clockWidth / 10, this._minuteLine);
   canvas.restore();    canvas.save();
   canvas.translate(this._clockX, this._clockY);
   canvas.rotate(this._hourAngle);
   canvas.drawLine(0, 0, 0, this._clockWidth / -2 + this._clockWidth / 4, this._hourLine);
   canvas.restore();
}

Digital countdown

A digital countdown can be used as a timer for many various purposes. In comparison with the analog clock the digital countdown does not need to calculate any angles between the hands. It just changes the digital numbers according to the remaining time.

Digits

On digital clocks digits are used which can be easily created. Of course, in our implementation the number of pixels is not a limitation but for the realistic appearance we used the same number as on the digital clocks. The digits have been made in a graphic editor. You can download them from this tutorial.

In the init method all images are loaded into one array (from zero to nine).

Example: creating the array of digits

this._digits = new Array(GFX.zero, GFX.one, GFX.two, GFX.three, GFX.four, GFX.five, GFX.six, GFX.seven, GFX.eight, GFX.nine);

Timing

The remaining time in seconds is stored in a member variable called time. When a countdown starts the time value is set to the required time which decreases its value every second.  The countdown supports the methods for starting, pausing and resuming the timer, which are mapped directly to the equal timers methods.

Example: starting the countdown

function start(time)
{
   if (this._timer !== 0)
       this._timer.dispose();    this.time = time;    this._timer = new Timer(1000, true);
   this._timer.onTick = function()
   {
       this super.time -= 1;
       if (this super.time < 1) {
           this super._timer.dispose();
           this super._timer = 0;
           if (typeof this super._finish == #function)
               this super._finish();
       }
  
   }
   this._timer.start(1000);
}

Drawing

In the drawing method all the digit of actual time are being drawn.

Example: displaying the time

function draw(canvas)
{
   super.draw(canvas);    var minute = this.time / 60;
   canvas.drawBitmap(this._digits[minute / 10], this._timerX - gap - 2*GFX.one.width - GFX.one.width / 2, this._timerY - GFX.one.height / 2);
   canvas.drawBitmap(this._digits[minute % 10], this._timerX - GFX.one.width - GFX.one.width / 2, this._timerY - GFX.one.height / 2);
   canvas.drawBitmap(GFX.dot, this._timerX - GFX.one.width / 2, this._timerY - GFX.one.height / 2);    var seconds = this.time % 60;
   canvas.drawBitmap(this._digits[seconds / 10], this._timerX + GFX.one.width / 2, this._timerY - GFX.one.height / 2);
   canvas.drawBitmap(this._digits[seconds % 10], this._timerX + gap + GFX.one.width + GFX.one.width / 2, this._timerY - GFX.one.height / 2);
}

 Working with timers: ...   Designing for optima ... 
Tutorial details and chapters
Technology:
iOS, Android
Difficulty:
Advanced
Completion:
90 min
Advanced tutorials chapters