{"id":976,"date":"2017-11-29T15:15:00","date_gmt":"2017-11-29T20:15:00","guid":{"rendered":"http:\/\/bluegalaxy.info\/codewalk\/?p=976"},"modified":"2021-01-17T21:12:50","modified_gmt":"2021-01-18T02:12:50","slug":"p5-js-how-to-build-a-clock","status":"publish","type":"post","link":"https:\/\/bluegalaxy.info\/codewalk\/2017\/11\/29\/p5-js-how-to-build-a-clock\/","title":{"rendered":"p5.js: How to build a clock"},"content":{"rendered":"<p>In this article, I will show how to build a clock using p5.js, step by step. Here is what the final result looks like:<\/p>\n\n<!-- iframe plugin v.5.2 wordpress.org\/plugins\/iframe\/ -->\n<iframe loading=\"lazy\" src=\"https:\/\/www.bluegalaxy.info\/processing\/p5\/clock\/\" width=\"450\" height=\"450\" frameborder=\"1\" scrolling=\"no\" class=\"iframe-class\"><\/iframe>\n\n<p><strong>Step 1: Create a square canvas with an origin point<br \/>\n<\/strong><\/p>\n<p>When you create a new p5.js sketch in the Processing IDE, you start with empty setup() and draw() functions. For example:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">function setup() {\n\n}\n\nfunction draw() {\n  \n}<\/pre>\n<p>So the first thing we want to do is create a square canvas with a white background and draw an origin point at (0,0):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">function setup() {\n  createCanvas(200, 200);\n  background(255);\n}\n\nfunction draw() {\n  strokeWeight(10);\n  point(0,0);\n}<\/pre>\n<p>By default, the origin point of the Processing Cartesian coordinate system is in the upper left corner of the screen:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" id=\"img_ds\" class=\"alignnone size-full wp-image-981\" src=\"http:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/origin_point.png\" alt=\"\" width=\"201\" height=\"202\" srcset=\"https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/origin_point.png 201w, https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/origin_point-150x150.png 150w\" sizes=\"auto, (max-width: 201px) 100vw, 201px\" \/><\/p>\n<p><strong>Step 2: Move the origin point to the center of the screen<br \/>\n<\/strong><\/p>\n<p>In order to have a circular clock in the middle of the screen, we need to move the origin point to the center. This can be done using the <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/translate\">translate()<\/a> function. For example:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">translate(width\/2, height\/2);<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" id=\"img_ds\" class=\"alignnone size-full wp-image-983\" src=\"http:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/origin_point2.png\" alt=\"\" width=\"201\" height=\"201\" srcset=\"https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/origin_point2.png 201w, https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/origin_point2-150x150.png 150w\" sizes=\"auto, (max-width: 201px) 100vw, 201px\" \/><\/p>\n<p><strong>Step 3: Display tick marks<br \/>\n<\/strong><\/p>\n<p>Since a clock is made up of 60 minutes, and each minute contains 60 seconds, we need to create a circle and divide it into 60 sections. Each section will be denoted as a point or &#8220;tick mark&#8221;.<\/p>\n<p>We will need to set up some variables to describe this circle, including the radius of the circle and the number of tick marks we want to divide the circle into. The angles are calculated by taking the whole circle &#8220;TWO_PI&#8221;, and dividing it by the number of tick marks.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var radius = 75.0;\nvar numPoints = 60;\nvar angle = TWO_PI\/numPoints;<\/pre>\n<p>Then we want to change the strokeWeight again so the points are smaller and then use a feature called <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/beginShape\">beginShape()<\/a>, where point vertices are added together to form a unified shape. A while loop can be used to create the tick marks in the shape. For example, inside the draw() function:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/Draw the minute\/second ticks\n\/\/ beginShape() will build the points into a single custom shape  \nstrokeWeight(2);\nstroke(255);\nbeginShape(POINTS);\nvar i = 0;\nwhile (i &lt; numPoints ) {\n  x = cos(angle*i) * secondsRadius; \n  y = sin(angle*i) * secondsRadius;\n  vertex(x, y);\n  i++;\n}\nendShape();<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" id=\"img_ds\" class=\"alignnone size-full wp-image-987\" src=\"http:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/tick_marks.png\" alt=\"\" width=\"200\" height=\"200\" srcset=\"https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/tick_marks.png 200w, https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/tick_marks-150x150.png 150w\" sizes=\"auto, (max-width: 200px) 100vw, 200px\" \/><\/p>\n<p><strong>Step 4: Create a second hand<br \/>\n<\/strong><\/p>\n<p>To create the second hand, we need to set up a new variable and we want the line to be shorter than the radius.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var secondsRadius = radius * 0.9;<\/pre>\n<p>To keep track of seconds, we need a new variable (called &#8216;s&#8217; in this case) that uses the built in functions <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/second\">second()<\/a> and <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/map\">map()<\/a>. We also want to subtract HALF_PI so that the seconds start at the top of the clock (12 o&#8217;clock position):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/ subtract HALF_PI to make them start at the top\nvar s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;<\/pre>\n<p>Next, we need to add the actual line that represents the seconds hand. In this code, I gave it a line weight of 1 and made it red. Notice that this uses the <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/sin\">sin()<\/a> and <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/cos\">cos()<\/a> functions.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">strokeWeight(1);\nstroke('red');\nline(0, 0, cos(s) * secondsRadius, sin(s) * secondsRadius);<\/pre>\n<p>At this point, the seconds hand will appear as a red line that moves around the clock face.<\/p>\n<p>Important: In order to &#8220;clear&#8221; the background every time the second hand moves, we must set the background to white inside the draw function loop:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/ Drawing the background inside the draw function is necessary \n\/\/ to refresh the background so that the hands appear to move \n\/\/ on the clock and the previous hands disappear. \nbackground(255);<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" id=\"img_ds\" class=\"alignnone size-full wp-image-991\" src=\"http:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/second_hand.png\" alt=\"\" width=\"201\" height=\"201\" srcset=\"https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/second_hand.png 201w, https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/second_hand-150x150.png 150w\" sizes=\"auto, (max-width: 201px) 100vw, 201px\" \/><\/p>\n<p><strong>Step 5: Create minute and hour hands<br \/>\n<\/strong><\/p>\n<p>The minute and hour hands are created in much the same way as the second hand. For example, add the following lines to the draw() function:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI;\nvar h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;\n\nstrokeWeight(1);\nstroke('red');\nline(0, 0, cos(s) * secondsRadius, sin(s) * secondsRadius);\nstroke(0);   \/\/ change line color to black\nline(0, 0, cos(m) * minutesRadius, sin(m) * minutesRadius);\nstrokeWeight(2);  \/\/ hour hand should be thicker\nline(0, 0, cos(h) * hoursRadius, sin(h) * hoursRadius);<\/pre>\n<p>For minutes and hours, we are also using the functions <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/minute\">minute()<\/a>, <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/hour\">hour()<\/a>, and <a href=\"https:\/\/p5js.org\/reference\/#\/p5\/norm\">norm()<\/a>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" id=\"img_ds\" class=\"alignnone size-full wp-image-994\" src=\"http:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/sm_clock.png\" alt=\"\" width=\"200\" height=\"200\" srcset=\"https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/sm_clock.png 200w, https:\/\/bluegalaxy.info\/codewalk\/wp-content\/uploads\/2017\/11\/sm_clock-150x150.png 150w\" sizes=\"auto, (max-width: 200px) 100vw, 200px\" \/><\/p>\n<p><strong>Step 6: Add numerals and colors<br \/>\n<\/strong><\/p>\n<p>The final step is to change the size, add colors, add numerals, and complete the overall look of the clock. Lots of experimentation can occur in this stage to get the clock to look just the way you want.<\/p>\n<p>Change the size of the clock to 450 x 450.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">createCanvas(450, 450);<\/pre>\n<p>Set the radius to be the size of the window.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var radius = int(min(width, height) \/ 2);<\/pre>\n<p>Adjust the length of the hands and add a clockDiameter variable.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var secondsRadius = radius * 0.72;\nvar minutesRadius = radius * 0.60;\nvar hoursRadius = radius * 0.50;\nvar clockDiameter = radius * 1.8;<\/pre>\n<p>Draw the clock background and fill with gray.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/ Draw the clock background\nfill(80);\nnoStroke();\nellipse(0, 0, clockDiameter, clockDiameter);<\/pre>\n<p>Add the numerals. Use offsets to visually adjust the positions of the text.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/ Write the numerals\nfill(255);\ntextSize(16);\nstrokeWeight(0.1);\n\nx = cos(PI + HALF_PI) * secondsRadius - 10;\ny = sin(PI + HALF_PI) * secondsRadius - 10;\ntext(\"XII\", x, y);\n\nx = cos(TWO_PI) * secondsRadius + 10;\ny = sin(TWO_PI) * secondsRadius + 5;\ntext(\"III\", x, y)\n\nx = cos(HALF_PI) * secondsRadius - 7;\ny = sin(HALF_PI) * secondsRadius + 20;\ntext(\"VI\", x, y)\n\nx = cos(PI) * secondsRadius - 25;\ny = sin(PI) * secondsRadius + 5;\ntext(\"IX\", x, y)<\/pre>\n<p><strong>Here is the complete p5.js code:<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">function setup() {\n  createCanvas(450, 450);\n  background(255);\n}\n\nfunction draw() {\n  strokeWeight(2);\n  translate(width\/2, height\/2);\n  \n  \/\/ Drawing the background inside the draw function is necessary \n  \/\/ to refresh the background so that the hands appear to move \n  \/\/ on the clock and the previous hands disappear.\n  background(255);\n  \n  var radius = int(min(width, height) \/ 2);\n  var numPoints = 60;\n  var angle = TWO_PI\/numPoints;\n  \n  var secondsRadius = radius * 0.72;\n  var minutesRadius = radius * 0.60;\n  var hoursRadius = radius * 0.50;\n  var clockDiameter = radius * 1.8;\n  \n  \/\/ Draw the clock background\n  fill(80);\n  noStroke();\n  ellipse(0, 0, clockDiameter, clockDiameter);\n\n  \/\/ subtract HALF_PI to make them start at the top\n  var s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;\n  var m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI;\n  var h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;\n\n  \/\/Draw the minute\/second ticks\n  \/\/ beginShape() will build the points into a single custom shape  \n  strokeWeight(2);\n  stroke(255);\n  beginShape(POINTS);\n  var i = 0;\n  while (i &lt; numPoints ) {\n      x = cos(angle*i) * secondsRadius; \n      y = sin(angle*i) * secondsRadius;\n      vertex(x, y);\n      i++;\n  }\n  endShape(); \n  \n  strokeWeight(1);\n  line(0, 0, cos(s) * secondsRadius, sin(s) * secondsRadius);\n  strokeWeight(2);\n  line(0, 0, cos(m) * minutesRadius, sin(m) * minutesRadius);\n  strokeWeight(4);  \/\/ hour hand should be thicker\n  line(0, 0, cos(h) * hoursRadius, sin(h) * hoursRadius);\n  \n  \/\/ Write the numerals\n  fill(255);\n  textSize(16);\n  strokeWeight(0.1);\n\n  x = cos(PI + HALF_PI) * secondsRadius - 10;\n  y = sin(PI + HALF_PI) * secondsRadius - 10;\n  text(\"XII\", x, y);\n  \n  x = cos(TWO_PI) * secondsRadius + 10;\n  y = sin(TWO_PI) * secondsRadius + 5;\n  text(\"III\", x, y);\n\n  x = cos(HALF_PI) * secondsRadius - 7;\n  y = sin(HALF_PI) * secondsRadius + 20;\n  text(\"VI\", x, y);\n\n  x = cos(PI) * secondsRadius - 25;\n  y = sin(PI) * secondsRadius + 5;\n  text(\"IX\", x, y);\n}<\/pre>\n<p>The code in this article is based on this Processing clock example:<br \/>\n<a href=\"https:\/\/processing.org\/examples\/clock.html\">https:\/\/processing.org\/examples\/clock.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, I will show how to build a clock using p5.js, step by step. Here is what the final result looks like: Step 1: Create a square canvas with an origin point When you create a new p5.js sketch in the Processing IDE, you start with empty setup() and draw() functions. For example: &hellip; <a href=\"https:\/\/bluegalaxy.info\/codewalk\/2017\/11\/29\/p5-js-how-to-build-a-clock\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">p5.js: How to build a clock<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[47,35],"tags":[45,48,36],"class_list":["post-976","post","type-post","status-publish","format-standard","hentry","category-p5-js","category-processing-language","tag-javascript","tag-p5-js","tag-processing-py"],"_links":{"self":[{"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/posts\/976","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/comments?post=976"}],"version-history":[{"count":26,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/posts\/976\/revisions"}],"predecessor-version":[{"id":3355,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/posts\/976\/revisions\/3355"}],"wp:attachment":[{"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/media?parent=976"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/categories?post=976"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bluegalaxy.info\/codewalk\/wp-json\/wp\/v2\/tags?post=976"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}