This
tutorial is split in three steps:
- Step 1: Create the clock's background.
 - Step 2: Initialize the current clock time.
 - Step 3: Animate the clock.
 
Hint: This
tutorial assumes that you have a certain knowledge of HTML5 and JavaScript.
We begin
this tutorial by creating the background of this clock.
<!DOCTYPE
  html> 
<head> 
<meta
  content="text/html; charset=utf-8"
  http-equiv="Content-Type" /> 
<title>Simple
  Clock Animation</title> 
<script type="application/javascript"> 
var canvas; // the clock
  canvas 
var ctx; // canvas’s
  context 
// clock settings 
var centerX = 0; 
var centerY = 0; 
var radius = 150; 
function init() { 
canvas
= document.getElementById("clock"); 
ctx = canvas.getContext("2d"); 
centerX =
  canvas.width / 2; 
centerY = canvas.height / 2; 
drawClock(); 
} 
</script> 
</head> 
<body
  onload="init()"> 
<canvas
  id="clock" height="500" width="500"> 
Your browser does not support HTML5</canvas> 
</body> 
</html> 
 | 
 
Step 1: will consist of drawing the clock. This is given by the function drawClock().
function drawClock()
  { 
                drawClockBackground(); 
} 
 | 
The function drawClockBackground() inside the drawClock() function will draw the background of the clock. It will create small lines around the center (centerX, centerY) of the clock which is also the center of the canvas.
We start creating the lines from the right to the left, and using the function drawArcAtPosition() located below. Also, we will highlight the main lines.
At final, a small circle is added at the center of the clock (see function drawLittleCircle()).
Hint: You can
also use a predefined image (if you like) instead of drawing the background of
the clock yourself.
function
  drawClockBackground() { 
var correction = 1/300; 
var shift_unit = 1/170; 
var shift_factor = 1/30; 
var
  angle_initial_position = 2; 
var
  angle_current_position_begin = 0; 
var
  angle_current_position_end = 0; 
var repeat = 60; 
var lineWidth = 10; 
for (var i=0; i <
  repeat; i+=1) { 
angle_current_position_begin
  = angle_initial_position - (i * shift_factor) - correction; 
angle_current_position_end
  = angle_current_position_begin + shift_unit; 
if (i % 5 == 0)
  lineWidth = 20; 
else lineWidth = 10; 
drawArcAtPosition(centerX,
  centerY, radius,  
angle_current_position_begin*Math.PI, angle_current_position_end*Math.PI, false, lineWidth); 
} 
drawLittleCircle(centerX, centerY); 
} 
function
  drawArcAtPosition(centerX, centerY, radius,  
start_angle, end_angle, counterclockwise, lineWidth) { 
ctx.beginPath(); 
ctx.arc(centerX, centerY, radius, start_angle, end_angle, counterclockwise); 
ctx.lineWidth =
  lineWidth; 
ctx.strokeStyle =
  "black"; 
ctx.stroke(); 
ctx.closePath(); 
} 
function
  drawLittleCircle(centerX, centerY) { 
drawArcAtPosition(centerX, centerY, 4, 0*Math.PI, 2*Math.PI, false, 4); 
} 
 | 
 
Afterward,
we create the Hands for seconds, minutes, and hours.
The below figure show the hand for the seconds.
// draw Hand for
  seconds 
endX = centerX + radius*Math.sin(seconds*Math.PI / 30); 
endY = centerY -
  radius*Math.cos(seconds*Math.PI / 30); 
drawHand(centerX, centerY, endX, endY); 
} 
function
  drawHand(beginX, beginY, endX, endY) { 
ctx.beginPath(); 
ctx.moveTo(beginX,
  beginY); 
ctx.lineTo(endX,
  endY); 
ctx.stroke(); 
ctx.closePath(); 
} 
 | 
The same principle is applied for minutes and hours. The hands will be a little bit smaller than that of the seconds-Hand. The minutes-Hand will move depending on the seconds-Hand, and the hours-Hand will move depending on the minutes-Hand. The moving of the Hands will be constant and smooth.
// draw Hand for
  minutes 
function
  drawMinutesHand() { 
var rotationUnit = minutes + seconds / 60; var rotationFactor = Math.PI / 30; var rotation = rotationUnit*rotationFactor; var handLength = 0.8*radius; endX = centerX + handLength*Math.sin(rotation); endY = centerY - handLength*Math.cos(rotation); drawHand(centerX, centerY, endX, endY); 
} 
// draw Hand for
  hours 
function
  drawHoursHand() { 
var rotationUnit = 5*hours + minutes / 12; var rotationFactor = Math.PI / 30; var rotation = rotationUnit*rotationFactor; var handLength = 0.4*radius; endX = centerX + handLength*Math.sin(rotation); endY = centerY - handLength*Math.cos(rotation); drawHand(centerX, centerY, endX, endY); 
} 
 | 
 
The function drawClock() will be adequately updated as follow, where we add the Hands for the clock.
function drawClock()
  { 
                drawClockBackground(); 
                drawSecondsHand(); 
                drawMinutesHand(); 
                drawHoursHand(); 
} 
 | 
 
Step 2: will consists of animating the Hands. However, before we start we have to get the current time of the system. Thus, we create 4 additional system variables as follows:
// time settings 
var date; 
var hours; 
var minutes; 
var seconds; 
 | 
 
And, we create a function called initTime(), where we initialize the data object and pass to our variables the current time of our system and clock.
// get the system
  time 
function initTime()
  { 
date = new Date(); 
hours =
  date.getHours() % 12; 
minutes = date.getMinutes(); 
seconds = date.getSeconds(); 
} 
 | 
 
Now, add the initTime() function before the drawClock() function in the init() function. This is because the Hands will be drawn according to the system current time.
function init() { 
… 
initTime(); 
drawClock(); 
} 
 | 
 
Step 3: will consist now of animating the Hands(seconds, minutes, and hours) of the clock.
We are
going now to create an animate clock function called animateClock() as
follows:
// animate clock 
function
  animateClock() { 
clearCanvas(); 
refreshTime(); 
drawClock(); 
} 
 | 
 
Inside this
function we have three functions named: clearCanvas(), refreshTime(),
and drawClock().
The first
function will clear the canvas for the animation. The second function is going
to refresh the current elapsed time, and the final function, which we have
already seen, is going to redraw the clock with its Hands according to the refreshed
time.
// clear canvas 
function
  clearCanvas() { 
ctx.clearRect(0, 0, canvas.width, canvas.height); 
} 
// refresh time
  after 1 seconde 
function
  refreshTime() { 
seconds += 1; 
if
  (Math.floor((seconds / 60)) != 0) { minutes += 1; seconds %= 60; } 
if
  (Math.floor((minutes / 60)) != 0) { hours += 1; minutes %= 60; } 
} 
// draw or redraw
  Clock after time refresh 
function drawClock()
  { 
                drawClockBackground(); 
                drawSecondsHand(); 
                drawMinutesHand(); 
                drawHoursHand(); 
} 
 | 
 
In order to animate the clock we are going now to add the setInterval(..) function inside the init() function which will animate the clock every second. Of course, the function that will be called every second is the animateClock() function.
function init() { 
canvas =
  document.getElementById("clock"); 
ctx =
  canvas.getContext("2d"); 
centerX =
  canvas.width / 2; 
centerY =
  canvas.height / 2; 
initTime(); 
drawClock(); 
setInterval("animateClock()",
  1000); 
} 
 | 
 
The full clock's code can be viewed below:
<!DOCTYPE
  html> 
<head> 
<meta
  content="text/html; charset=utf-8"
  http-equiv="Content-Type" /> 
<title>Simple
  Clock Animation</title> 
<script
  type="application/javascript"> 
var canvas; // the
  clock canvas 
var ctx; // canvas's
  context 
// clock settings 
var centerX = 0; 
var centerY = 0; 
var radius = 150; 
// time settings 
var date; 
var hours; 
var minutes; 
var seconds; 
function init() { 
canvas = document.getElementById("clock"); 
ctx = canvas.getContext("2d"); 
centerX =
  canvas.width / 2; 
centerY = canvas.height / 2; 
initTime(); 
drawClock(); 
setInterval("animateClock()",
  1000); 
} 
// get the system
  time 
function initTime()
  { 
date = new Date(); 
hours
= date.getHours() % 12; 
minutes
= date.getMinutes(); 
seconds
= date.getSeconds(); 
} 
// animate clock 
function
  animateClock() { 
clearCanvas(); 
refreshTime(); 
drawClock(); 
} 
// clear canvas 
function
  clearCanvas() { 
ctx.clearRect(0, 0,
  canvas.width, canvas.height); 
} 
// refresh time
  after 1 seconde 
function
  refreshTime() { 
seconds += 1; 
if
  (Math.floor((seconds / 60)) != 0) { minutes += 1; seconds %= 60; } 
if
  (Math.floor((minutes / 60)) != 0) { hours += 1; minutes %= 60; } 
} 
// draw or redraw
  Clock after time refresh 
function drawClock()
  { 
                drawClockBackground(); 
                drawSecondsHand(); 
                drawMinutesHand(); 
                drawHoursHand(); 
} 
function
  drawHand(beginX, beginY, endX, endY) { 
ctx.beginPath(); 
ctx.moveTo(beginX,
  beginY); 
ctx.lineTo(endX, endY); 
ctx.stroke(); 
ctx.closePath(); 
} 
// draw Hand for
  seconds 
function
  drawSecondsHand() { 
endX = centerX +
  radius*Math.sin(seconds*Math.PI / 30); 
endY = centerY -
  radius*Math.cos(seconds*Math.PI / 30); 
drawHand(centerX, centerY, endX, endY); 
} 
// draw Hand for minutes function drawMinutesHand() { var rotationUnit = minutes + seconds / 60; var rotationFactor = Math.PI / 30; var rotation = rotationUnit*rotationFactor; var handLength = 0.8*radius; endX = centerX + handLength*Math.sin(rotation); endY = centerY - handLength*Math.cos(rotation); drawHand(centerX, centerY, endX, endY); } // draw Hand for hours function drawHoursHand() { var rotationUnit = 5 * hours + minutes / 12; var rotationFactor = Math.PI / 30; var rotation = rotationUnit*rotationFactor; var handLength = 0.4*radius; endX = centerX + handLength*Math.sin(rotation); endY = centerY - handLength*Math.cos(rotation); drawHand(centerX, centerY, endX, endY); } 
function
  drawClockBackground() { 
var correction =
  1/300; 
var shift_unit =
  1/170; 
var shift_factor =
  1/30; 
var angle_initial_position = 2; 
var angle_current_position_begin = 0; 
var angle_current_position_end = 0; 
var repeat = 60; 
var lineWidth = 10; 
for (var i=0; i <
  repeat; i+=1) { 
angle_current_position_begin
  = angle_initial_position - (i * shift_factor) - correction; 
angle_current_position_end = angle_current_position_begin + shift_unit; 
if (i % 5 == 0)
  lineWidth = 20; 
else lineWidth = 10; 
drawArcAtPosition(centerX,
  centerY, radius,  
angle_current_position_begin*Math.PI, angle_current_position_end*Math.PI, false, lineWidth); 
} 
drawLittleCircle(centerX,
  centerY); 
} 
function
  drawArcAtPosition(centerX, centerY, radius, start_angle,  
end_angle, counterclockwise, lineWidth) { 
ctx.beginPath(); 
ctx.arc(centerX, centerY, radius, start_angle, end_angle, counterclockwise); 
ctx.lineWidth =
  lineWidth; 
ctx.strokeStyle =
  "black"; 
ctx.stroke(); 
ctx.closePath(); 
} 
function
  drawLittleCircle(centerX, centerY) { 
drawArcAtPosition(centerX, centerY, 4, 0*Math.PI, 2*Math.PI, false, 4); 
} 
</script> 
</head> 
<body
  onload="init()"> 
<canvas
  id="clock" height="500" width="500"> 
Your browser does not support HTML5</canvas> 
</body> 
</html> 
 | 

+5!
ReplyDeletecreate animation rotate view
ReplyDelete