Pomodoro clock project

Last we spoke, I was just finishing up the third of four projects required by the Free Code Camp curriculum in the Basic Front End Development section.  The JavaScript calculator I built was by far the most complicated programming I’d done as part of Free Code Camp.  Project #4, the Pomodoro Clock, seemed like a step back, complexity-wise, but was an interesting challenge as I’d not done much with time-based callbacks.

That was almost two weeks ago, about twice the time it took me to build the calculator.  Conceptually, I still don’t think the project was as complicated as the calculator, but there were things with this project that stumped me for days.

FCC Pomodoro Clock - bigger

The first challenge, obviously, was getting the timers to increment…OK, maybe that wasn’t what you’d attack first, but I wanted to make sure my JQuery click event skills were still sharp.  I created a control of sorts,

Rest Time
5
</div>

I had two of these, each with an increment and decrement control, and a value displayed in the middle.  I wanted them side by side, so a <span> tag seemed appropriate, and worked wonderfully.  Of course, I had the usual challenge with vertical centering, which I solved with the <div class=”vert-center”>.   Here’s the CSS, with the “display: table-cell;” being the key bit:

.vert-center {
  display: table-cell;
  vertical-align: middle; 
  ...
}

The clicks were handled with JQuery event handlers, which directly modified the text in the middle span.  The tricky part was that I wanted to use the same event handlers for both “controls” (or sets of elements).  This was solved by adding the class “value” to both middle spans, which had the ids “focus-length” and “rest-length” (this is the one shown above) , which allowed me to target the increment or decrement change to that element.  Here’s the code:

$(".increment-value").click( function () {
  var value = parseInt($(this).siblings(".value").text());
  if (value < 99)
    value++;
  $(this).siblings(".value").text(value.toString());
});

The key bit I had never used before was the “.siblings()” selector, which selects all the siblings, or HTML elements that are contained in the same parent element.  Looking at the HTML snipit above, this would be the <br> tag and the three <span> tags enclosed by the <div class=”vert-center”> tag.  The passed in filter – “.value” – allowed me to select only the element with the “.value” class, and store the freshly modified value inside.

Another minor but new (to me) concept used in these controls were the CSS selectors “:before” and “:after”.  You’ll notice that the HTML above has no text for the up or down arrows used in the increment/decrement controls.  I used font-awesome gliphs for the actual arrows, but instead of adding font-awesome classes to the spans, I applied the characters using the following CSS:

.ui-button {
  font-family: FontAwesome;
  ...
}

.increment-value:before {
  content: "\f0d8";
}

.decrement-value:before {
  content: "\f0d7";
}

I used the ui-button class to apply the FontAwesome font (loaded in a <link> tag in the <head> section of the HTML file) and then applied a specific character  using the “content” property.

The other problem I needed to solve was how to add a “min” suffix to each number without having to parse it out each time I needed to use the value (such as in the above click() handler.)  This was solved similarly, using the “:after” selector:

.value:after {
  content: " min";
}

Of course, the critical bit of logic for any clock is the timer.  I was a bit worried about this, not having any experience with JavaScript timers, but in the end I was able to implement a super-simple timer using setTimer().  I stored the number of seconds, calculated from the value stored in the appropriate HTML element (e.g., the HTML above shows the “rest-length” element, and the default value of the rest timer,) multiplied by 60 so get seconds, in a variable.  Then, I call a function – updateTimeRemaining() – which decrements the time, and then, assuming we’re not paused, schedules another updateTimeRemaining() call with setTimer():

function updateTimeRemaining() {
  if (currentTime >= 0) {
      drawTimer(...);
      currentTime -= intervalInSeconds;
    if (!paused) {
      currentTimeout = setTimeout(updateTimeRemaining, intervalInSeconds * 1000);
    }
  } 
  else {
    playAlarmSound();
    ...
  }
}

Once the timing code was in place and the clock was working, I needed to make some audio and visual enhancements.  Playing audio in JavaScript was pretty simple:

function playAlarmSound() {
var audio = new Audio(focusSound);
audio.play();
}

The variable “focusSound” is just a text string containing a URL to an audio file, but that was by far the biggest challenge of this part of the project – finding  appropriate hosted audio files.  I spent a huge chunk of time looking for usable audio files, finding many I could download and host myself, but none that were available to link to as-is.

Eventually, I gave up and broke “Rule #1: Don’t look at the example project’s code.”  I knew the person creating the example project had found something, as their clock played a sound.  I figured a quick glance at their source would tell me if they had a personal server they were using, or if they’d found a  side hosting audio.

Fortunately for me, it turned out to be the latter.  They were linking to a file from oringz.com, a site which hosts all sorts of free sound files.  I did a quick search, and found a couple of audio clips that I felt were appropriate (I think you’ll wake up and want to get back to work after hearing my rest sound…)

That left me with the minor task of adding a look and feel.

I’ll admit it, I’m not a UI designer.  Fortunately, there are plenty of great UI designers out there to copy from, and that’s what I did with my clock UI.  In this case, I turned to the Apple iPad countdown timer.  I took a screen shot, and used paint.NET to capture the background color, and the red for the clock.  I also decided to copy the basic circular design of the timer.

The critical challenge of this design was getting the timer animation to look good – in my case, a red or green circular line getting shorter as the timer runs down.  In looking for a way to draw that circular line, I was led (via some stackoverflow answers) to the JQuery knob control by Anthony Terrien.

If you click on that link, you’ll see a bunch of circular controls that look almost exactly like my final clock.  What you won’t see, however, is multiple lines of text in any of those controls.  As you can see in my final clock, I wanted to show both the active clock (Focus or Rest), the current clock time, and the next-up clock time.  I looked around for some examples using multiple lines, and while I found some suggestions, nothing really workable turned up.

I resumed my search, eventually finding some code that used the HTML <canvas> element, and the arc() function, to draw a smooth circular line.  I then simply added additional text drawing functions as part of drawing the canvas-based control.  This was a great example of discovering that rolling your own control (or doing the drawing yourself) was a better fit than using someone’s pre-built control.

In the end, I felt pretty good about the clock, and about the other Free Code Camp projects I’d built so far.  Much of what I’d learned didn’t come from Free Code Camp, and other than suggestions for interesting projects, I’d begun to have concerns about whether Free Code Camp was actually helping my learning, or simply getting in the way.  I need to take another look at what resources are available.  It may be time for another course correction.

 

Advertisements

Wondering if Free Code Camp is for me…

I’m in the middle of blogging about the Pomodoro Calculator project I just finished yesterday.  As I was finishing that project, news broke that Free Code Camp had made another change to their curriculum.  One of the major focus was updating their challenges, with most of the changes affecting the four I have recently been working on.  When I started working on these, the four “Basic Front End Projects” were:

  1. Build a Personal Portfolio Webpage
  2. Build a Random Quote Machine
  3. Build a JavaScript Calculator
  4. Build a Pomodoro Clock

After the changes, there are only two Basic Front End Projects – the personal portfolio and a new “Tribute Page” project, which is a basic HTML page with some images.  I completely agree with the addition of this new, more basic project to kick things off.

What happened to the quote machine, calculator, and pomodoro clock projects?  The quote machine is now one of four Intermediate Front End Projects, and the calculator and pomodoro clock are two of the four Advanced Front End Projects.

This isn’t the first time Free Code Camp has changed their curriculum, and won’t be the last, but I’m starting to think that this continual moving target is not the best way to learn.  I’ve mentioned before the quote from Free Code Camp themselves, which says:

“…no one has actually completed our entire program, because campers get jobs before they’re able to.”

I’m starting to think that the main reason no one has completed the entire program is because the authors can’t keep the curriculum stable long enough for anyone to finish it.

As I was snooping around looking for information on the Free Code Camp changes, I ran across a disheartening post from another camper regarding the node.js section of the Free Code Camp curriculum.  The most poignant comment was the header of the reddit comment: “I have just finished the node.js tutorials on freeCodeCamp. I still know nothing about node.js.”

This has been my fear all along with these rushed-out, ramp-up inexperienced programmer-focused curricula.  And that, unfortunately, seems to be where Free Code Camp is at right now.

Still, that doesn’t take away from the great community that Free Code Camp has fostered, nor does it tarnish the leadership of Quincy Larson, who continues to do great things promoting coding education.  Despite its faults, Free Code Camp will continue to get better, and will hopefully help many folks take their first steps in web development.

Unfortunately for me, it seems a ill fit.

The Calculator Project (project 3)

The third of the Basic Front End Development Projects that are part of the Free Code Camp curriculum asks you to build a JavaScript calculator.  This is a progression from project 1, the Personal Portfolio Webpage, which was primarily focused on visual layout and design, and project 2, the Random Quote Machine, which added interactivity and a small bit of JavaScript.  The calculator I built required a little bit of everything I’d used so far, plus a much heavier dose of JavaScript programming.

calculator-project
My Free Code Camp JavaScript calculator

As you can see from the picture, I opted to try and make the calculator look realistic, including slicing up some images of an actual HP 15C calculator.  Deciding on a look and feel wasn’t the first thing I worked on, but it was definitely one of the more time consuming parts of the effort.  I’ll get into that a bit more below.

The first thing I worked on was getting the calculator functionality working.  That required a display, a grid of clickable elements representing numbers, mathematical operations, and the like.  The previous two projects were all about layout, and I used much of the same concepts in this project.

The display and buttons were initially just a bunch of

elements, and I used a little JQuery JavaScript to append numbers onto the end of the display.  Of course, clicking on a button means different things in different contexts in a calculator, and it became clear I would need to do a bit more than just append a value to the display when a button was clicked.

What sorts of “contexts” am I talking about?  Consider clicking on a number button.  If this is the first digit in the first number of the calculation, you’ll want to clear the initial zero from the display.  If it’s not the first digit, you can just append it.  But what if you had just clicked an operation button (e.g., +, -, etc.)?  In that case, you’ll want to clear the current number from the display first.  And so on.

There is a concept in computer science to deal with this situational behavior – a state machine.  The basic idea is that you keep track of the current state of the machine (in this case, the calculator), perform the action that is appropriate for the current combination of input and state, and if necessary, change from the current state to a new one.

Getting my calculator to work properly became a process of determining what states I thought the calculator might be in, and deciding what actions should take place when you clicked on each type of button.  My button types included: number buttons, operation buttons, the All Clear or AC button, the back button (which removed the right-most number from the display), and the equal button.  I also worked out which items I needed to store in variables, which included the two numbers to be used in the calculations, the operation to perform, the result, and the current state.  Finally, I created a list of the states, and what would happen in each state when you clicked on each type of button.

I’m not going to go into the details of state machines here, and the implementation used in my calculator is far from elegant, but I wanted you to have an idea of what my code is trying to do (if you decided to take a look.)

The one thing I missed in my initial state machine was what to do after the equal button had been pressed.  The unique thing about this state was that the next key press could either lead to a whole new calculation being started, or to a new operation performed on the existing value.  Adding this state and the corresponding logic to handle it completed my calculator functionality.

I was left with a calculator that worked, but looked like a bunch of rectangles you could click on.  My initial thought was to simply round some of the corners and select a pleasing color scheme, but I was never good at pleasing color schemes, so I decided to try the “realistic” style.

I Googled “calculator image” and sifted through a huge number of images.  I found several that would work, but the one that caught my eye was the HP already mentioned.  I had used a super-expensive HP calculator in college, and loved the click of the buttons.  I decided I would try to make the “button press” experience realistic, and started working on how to make that happen.

I started by cutting up the calculator image, and creating a button image that was free of text or symbols.  I then edited the button so it looked like the button was pressed.  This involved cutting off some of the bottom of the button, making the top of the button a little bit larger, and moving the whole thing down a little bit.  It took a bit of fiddling, but I really liked how it ended up.

creating calculator buttons

Once the images were created I thought I had done the bulk of the work, but getting them to look right in the browser was more difficult than I expected.

The primary challenge was that the text on the button had to move lower when the button was pressed.  This didn’t seem like a big deal, as getting one button to work correctly was simply a matter of changing the line-height on the active event.  Unfortunately, this didn’t work at all for a row of buttons, as the line height of the entire row was affected, throwing off the text on the other buttons.

The solution was to split the image from the text, and positioning the text absolutely.  Instead of putting the image on the background of a

and putting the text inside that

, I moved the text into a set of

tags inside that div, and positioned that

tag absolutely.  Here’s the HTML/CSS that moves the text lower:

1

.n-p { width: 50px; height: 35px; text-align: center; position: absolute; padding-top: 14px; padding-bottom: -15px; margin-left: 2px; top: -19px; left: -3px; ... } .n-p:active { top: -15px; }

That’s a lot of specific pixel positioning code, and I’m not particularly proud of it, but the end result is that the text moves down about four pixels when you press it, which makes the buttons look like real buttons.

Another challenge was finding a font that looked realistic on a calculator.  I first looked into 8-segment and 14-segment fonts, the sort of fonts that you see on old calculators, but had trouble finding the following combination of features: free, hosted, having a decimal character.  I found several that matched two out of the three, but none that matched them all.  Fortunately, Google had a terminal font called VT323, that ended up looking great.

The final polish bits were adding things like the back button and the decimal button.  The decimal button was a bit tricky, as it is kinda like a number button, in that it contributes to numbers, but unlike other numbers, there can be only one.  That was handled with this JavaScript:

if ($(this).text() == ".") {
  // special handling for adding a decimal point to the number
  if ($("#display").text().indexOf(".") == -1 ) {
    $("#display").append($(this).text()); 
  }
}

The indexOf() function returns the place in the string where the passed-in string starts, or a -1 if it isn’t found in the string.  Thus, if it isn’t found, we append it to the end of the display.  There was also some code that had to be added to get a zero to show up before the decimal when entering a new number.

 

This project took me more than a week of on-and-off focus.  It was a good code-focused project that required some thinking and design in order to pull off (though I’m sure there are simpler implementations than the one I ended up with.)

Next up, the final Basic Front End Development Project – the Pomodoro Clock.