Js Canvas circular clock tutorial, jscanvas circular clock

Source: Internet
Author: User

Js Canvas circular clock tutorial, jscanvas circular clock

Reading this article requires some basic information about the basic usage of canvas. This article provides an example of a simple tutorial on implementing circular clock in HTML5 Canvas.

Step 1:Create a simple html file and define the element canvas in the <body> label.

Canvas.html

After this step, open canvas.html with a browser, and you will find that nothing is visible, because we didn't draw anything on the canvas, nor define boundaries for it.

Add css style attributes for <canvas> in canvas. html:

In this way, we can see the outline of <canvas>.

When the width and height are not set, the canvas will initialize the width to 300 pixels and the height to 150 pixels. CSS can be used to define the size of the element, but the image will be scaled to fit its frame size during painting: If the CSS size is different from the initial canvas size, it will be distorted.

Note:If the image you have drawn is distorted, specify the width and height in the <canvas> attribute, instead of using CSS.

Step 2: Create a draw. js file that implements the circular clock logic for initialization.

There is no doubt that to implement the clock, you need to obtain the system time.

In js syntax, Date () can be used to obtain the time in real time.
Var currentTime = new Date ();

Next, you should master the function of drawing a circle on canvas:
Arc (x, y, radius, startAngle, endAngle, anticlockwise) This method is used to draw an arc (circle) with the radius as the center of (x, y ), from startAngle to endAngle, it is generated in the direction specified by anticlockwise (true by default.
The unit of stratAngle and endAngle is not the angle unit we are familiar with, but the unit of radian. A complete circle spans 2 π radians.

In the canvas coordinate system, the orientation is 0 radian in the positive direction of the X axis. The clock pointer turns clockwise and takes 2 π as a cycle. As shown in, the clock pointer starts from the (-1/2) * π position.

The radians of the current time are calculated as follows:

// Divide a clock cycle by 12. The remainder of 12 is calculated because Date (). getHours returns the hour in the 24-hour format. Hour = (currentTime. getHours () % 12) * (2 * Math. PI/12); // MINUTE 60 = (currentTIme. getMinutes) * (2 * Math. PI/60); // a circle of 60 equals SECOND = (currentTime. getSeconds) * (2 * Math. PI/60 );

Since the clock circles in the canvas start from (-1/2) * π, we also need to add the starting offset of (-1/2) * π to them.

We can see that draw. js:
 

Function draw () {// prerequisite for canvas painting var canvas = document. getElementById ('clock '); var currentTime = new Date (); var hour = (currentTime. getHours () % 12) * Math. PI/6; var minute = currentTime. getMinutes () * Math. PI/30; var second = currentTime. getSeconds () * Math. PI/30; hour = hour-Math. PI * (1/2); minute = minute-Math. PI * (1/2); second = second-Math. PI * (1/2); if (canvas. getContext) {var ctx = canvas. getContext ('2d '); ctx. beginPath (); ctx. arc( 200,200, 50, Math. PI * (-1/2), hour, false); ctx. moveTo (200,100); ctx. arc( 200,200,100, Math. PI * (-1/2), minute, false); ctx. moveTo (200,50); ctx. arc( 200,200,150, Math. PI * (-1/2), second, false); ctx. stroke ();}}

Add draw. js references to canvas.html at the same time.

After completing step 2, we can see the circular clock contour of the current time. Next, let it work!

Step 3:Use the requestAnimationFrame () method to change the clock.

The execution frequency of requestAnimationFrame () is 60 frames per second. You can define an event in requestAnimationFrame so that the event can be repeated and iterated in each frame to complete the corresponding event.

In this case, the requestAnimationFrame in each frame is easy to do. Add increments for the three parameters of the current time (hour hands, minute hands, second hands) and re-draw the clock.

Based on the frequency of 60 frames per second, the increment of second in one frame is: 2*π/60/60 = π/1800;

The increment of minute in a frame is one of the 60 points of the second increment; the increment of hour in a frame is one of the 12 points of minute.
 

In addition, when any of the hour, minute, and second variables reaches 3/2 * π, it means that after a cycle is completed, it will be re-initialized to (-1/2) * π, otherwise, it will overwrite and be drawn into a circle.

The update process of hour, minute, and second in the requestAnimationFrame () function is as follows:

   var s = Math.PI / 1800;   var m = s / 60;   var h = m / 12;   second = second + s;   minute = minute + m;   hour = hour + h;   if(second >= Math.PI * (3/2)){    second = Math.PI * (-1/2);   }   if(minute >= Math.PI * (3/2)){    minute = Math.PI * (-1/2);   }   if(second >= Math.PI * (3/2)){    second = Math.PI * (-1/2);   }</span>

The complete code for updating draw. js is as follows:

function draw() { var canvas = document.getElementById('clock'); var currentTime = new Date(); var hour = (currentTime.getHours()%12) * Math.PI/6; var minute = currentTime.getMinutes() * Math.PI/30; var second = currentTime.getSeconds() * Math.PI/30; hour = hour - Math.PI * (1/2); minute = minute - Math.PI * (1/2); second = second - Math.PI * (1/2); if (canvas.getContext){  var ctx = canvas.getContext('2d');  var s = Math.PI / 1800;  var m = s / 60;  var h = m / 12;  var rotate = requestAnimationFrame(step);  function step(){   second = second + s;   minute = minute + m;   hour = hour + h;   if(second >= Math.PI * (3/2)){    second = Math.PI * (-1/2);   }   if(minute >= Math.PI * (3/2)){    minute = Math.PI * (-1/2);   }   if(second >= Math.PI * (3/2)){    second = Math.PI * (-1/2);   }   ctx.clearRect(0, 0, 400 , 400);   ctx.beginPath();   ctx.arc(200,200,50,Math.PI*(-1/2),hour,false);   ctx.moveTo(200,100);   ctx.arc(200,200,100,Math.PI*(-1/2),minute,false);   ctx.moveTo(200,50);   ctx.arc(200,200,150,Math.PI*(-1/2),second,false);   ctx.stroke();   requestAnimationFrame(step);  } }}

So far, we have obtained an interactive circular clock. Next, we will add a pointer to it.

Step 4 *:Add the hour, minute, and second hands.

JS provides us with Math. cos () and Math. sin () to calculate the pointer arrival location. The units of the parameters they receive are also radians.

Function draw () {var canvas = document. getElementById ('clock '); var currentTime = new Date (); var hour = (currentTime. getHours () % 12) * Math. PI/6; var minute = currentTime. getMinutes () * Math. PI/30; var second = currentTime. getSeconds () * Math. PI/30; hour = hour-Math. PI * (1/2); minute = minute-Math. PI * (1/2); second = second-Math. PI * (1/2); if (canvas. getContext) {var ctx = canvas. getContext ('2d '); var s = Math. PI/1800; var m = s/60; var h = m/12; var rotate = requestAnimationFrame (step); function step () {second = second + s; minute = minute + m; hour = hour + h; if (second> = Math. PI * (3/2) {second = Math. PI * (-1/2);} if (minute> = Math. PI * (3/2) {minute = Math. PI * (-1/2);} if (second> = Math. PI * (3/2) {second = Math. PI * (-1/2);} // second-hand end xs = 150 * Math. cos (second) + 200; ys = 150 * Math. sin (second) + 200; // The End Of The Sub-needle xm = 100 * Math. cos (minute) + 200; ym = 100 * Math. sin (minute) + 200; // the end point of the hour hand xh = 50 * Math. cos (hour) + 200; yh = 50 * Math. sin (hour) + 200; ctx. clearRect (0, 0,400,400); ctx. beginPath (); // draw the pointer ctx. moveTo (200,200); ctx. lineTo (xs, ys); ctx. moveTo (200,200); ctx. lineTo (xm, ym); ctx. moveTo (200,200); ctx. lineTo (xh, yh); // draw the circular contour ctx. moveTo (200,150); ctx. arc( 200,200, 50, Math. PI * (-1/2), hour, false); ctx. moveTo (200,100); ctx. arc( 200,200,100, Math. PI * (-1/2), minute, false); ctx. moveTo (200,50); ctx. arc( 200,200,150, Math. PI * (-1/2), second, false); ctx. stroke (); requestAnimationFrame (step );}}}

Well, although the pointer is drawn, I regret it because it is too ugly. From the aesthetic point of view, a clock with a pointer should be a fully circular contour. I don't know if the readers share the same feelings. I decided to roll back step 4 in step 5.

Step 5:Personalize, beautify, and customize your clock.

The canvas of html5 provides multiple style attributes, such as line color and line width.

To improve code reusability, we abstract the circular code into a function.

Function draw () {var canvas = document. getElementById ('clock '); var currentTime = new Date (); var hour = (currentTime. getHours () % 12) * Math. PI/6; var minute = currentTime. getMinutes () * Math. PI/30; var second = currentTime. getSeconds () * Math. PI/30; hour = hour-Math. PI * (1/2); minute = minute-Math. PI * (1/2); second = second-Math. PI * (1/2); if (canvas. getContext) {var ctx = canvas. getContext ('2d '); var s = Math. PI/1800; var m = s/60; var h = m/12; var rotate = requestAnimationFrame (step); function step () {second = second + s; minute = minute + m; hour = hour + h; if (second> = Math. PI * (3/2) {second = Math. PI * (-1/2);} if (minute> = Math. PI * (3/2) {minute = Math. PI * (-1/2);} if (second> = Math. PI * (3/2) {second = Math. PI * (-1/2);} ctx. clearRect (0, 0,400,400); ctx. beginPath (); // draw the circular contour drawCircle (ctx, 100, hour, '# 99ff00'); drawCircle (ctx, 120, minute,' #99ff66 '); drawCircle (ctx, 140, second, '#66cc66'); requestAnimationFrame (step) ;}} function drawCircle (ctx, radius, endAngle, color) {ctx. beginPath (); ctx. moveTo (200,200-radius); ctx. strokeStyle = color; ctx. lineWidth = 20; ctx. arc( 200,200, radius, Math. PI * (-1/2), endAngle, false); ctx. stroke ();}

Step 6 (add later ):Add a digital index for the clock.

Add a canvas element. Since we can get the time from Date (), it is not a problem to display the value source. The only thing readers need to know is to use the setInterval (thingstodo (), interval) method to update the index every second.

Canvas.html

Modified draw. js

Function draw () {var canvas = document. getElementById ('clock '); var displayCanvas = document. getElementById ('display'); var currentTime = new Date (); var hour = (currentTime. getHours () % 12) * Math. PI/6; var minute = currentTime. getMinutes () * Math. PI/30; var second = currentTime. getSeconds () * Math. PI/30; hour = hour-Math. PI * (1/2); minute = minute-Math. PI * (1/2); second = second-Math. PI * (1/2); if (canvas. getContext) {var ctx = canvas. getContext ('2d '); var ctxD = displayCanvas. getContext ('2d '); showDisplay (ctxD, currentTime); var s = Math. PI/1800; var m = s/60; var h = m/12; var rotate = requestAnimationFrame (step); function step () {second = second + s; minute = minute + m; hour = hour + h; if (second> = Math. PI * (3/2) {second = Math. PI * (-1/2);} if (minute> = Math. PI * (3/2) {minute = Math. PI * (-1/2);} if (second> = Math. PI * (3/2) {second = Math. PI * (-1/2);} ctx. clearRect (0, 0,400,400); ctx. beginPath (); // draw the circular contour drawCircle (ctx, 100, hour, '# 99ff00'); drawCircle (ctx, 120, minute,' #99ff66 '); drawCircle (ctx, 140, second, '#66cc66'); requestAnimationFrame (step) ;}} function drawCircle (ctx, radius, endAngle, color) {ctx. beginPath (); ctx. moveTo (200,200-radius); ctx. strokeStyle = color; ctx. lineWidth = 20; ctx. arc( 200,200, radius, Math. PI * (-1/2), endAngle, false); ctx. stroke ();} function showDisplay (ctx, date) {var h = date. getHours (), m = date. getMinutes (), s = date. getSeconds (); // time text style ctx. font = "13px Sans-Serif"; ctx. textAlign = "center"; ctx. strokeText (h + ":" + m + ":" + s, 200,200); var timmer = setInterval (function () {s ++; if (s> = 60) {m ++; s = 0 ;}if (m >=60) {h ++; m = 0 ;}if (h >=24) {h = 0 ;} ctx. clearRect (0, 0, 400,400); ctx. strokeText (h + ":" + m + ":" + s, 200,200) ;}, 1000 );}

The final result is shown below:

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.