Categories: FreeCodeCamp
Tags: Sass, Canvas, JavaScript
This pen began as a FreeCodeCamp project to build a Pomodoro Clock, which is a clock based on the Pomodoro Technique. The clock breaks work into intervals, typically 25 minutes long, and in between there are short breaks. My clock does all of that, and you can also adjust the intervals. After each interval, a sound plays to alert the user.
I wrote the HTML markup in three sections: one for the title and start/stop/reset buttons, one for the clock, and one for the clock settings below.
I used Sass for this project and it really helped for nesting selectors so I didn’t have to write a million different classes to get the look I wanted. I did have to fine-tune the CSS properties of each element to get the layout looking the way I wanted. I used CSS Flexbox on the top panel:
I made the “+/-“ buttons on the bottom settings panel be transparent with
background-color: transparent
. Also, cursor: pointer
makes buttons seem more…
buttony (is that even a word?) by making the mouse into a pointer when hovering.
With the CSS and HTML out of the way, I started on coding the actual clock, making it tick, and providing interactivity with all the buttons. I began by initializing a few variables that can also be changed as configuration settings, like the clock radius, colors, and a URL to the sound file to be played:
This is also one of my first projects to work on the HTML5 Canvas API, which lets
us draw some cool things on the <canvas>
element. First, we have
to grab the DOM element with JavaScript, get the context (2D in this case, since we
want to draw a flat object), and set the height and width of the canvas (this defines
the window in which we’ll draw the clock):
Next, I defined two functions which draw a path for the border of the clock. The command
ctx.beginPath()
initiates a drawing path at the current location. Then
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
creates an arc starting
at the coordinates (x,y) within the canvas rectangle defined above, with a given radius,
starting angle, and ending angle. The “anticlockwise” parameter is an optional boolean which
determines the direction of the arc.
Note how in the drawArc function, the ending angle is given as an expression with
the variable frac
, allowing the length of the arc to change with the
variable. This will be important later. Also note how an if statement allows alternating
between different colors, depending on whether the clock is on a session or a break.
Another function called “refresh” takes the time displayed on the clock and decreases the timer by one second. The time in seconds displayed is stored in the variable “start” and unless the timer is done, the time is decreased by a second, and the variable “frac” is recalculated. This will adjust the length of the arc on the clock.
In the above code, two functions, convertTime
and convertToTime
, were invoked
to convert the time on the clock in the form “MM:SS” to an integer representing
the total seconds remaining (and vice versa). In the convertTime
function,
the variable is split into an array by the “:” separator and the minutes and seconds
are stored in separate variables, so that the total number of seconds can be returned.
In the convertToTime
function, the minutes left is found by dividing the total
number of seconds by 60, and rounding down. The remaining seconds are then prepended
with a 0 if it is less than 10; then, a string in the form “MM:SS” is returned and
displayed in the refresh
function above.
There are several other functions, like startClock
, stopClock
, and resetClock
that are fairly straightforward and are triggered by clicking on the start, stop,
and reset buttons.
I really learned how to work comfortably with Canvas to do simple things like drawing shapes and curves, and also how to integrate it with the rest of my code so that functions like ticking the clock can affect animations on the screen (the arc going around the clock that shows the amount of time passed/remaining).
See the Pen [Color Palette Generator](https://codepen.io/acrenwelge/pen/dOqPrY/) by Andrew ([@acrenwelge](https://codepen.io/acrenwelge)) on [CodePen](https://codepen.io).