reptile7's JavaScript blog
Thursday, December 14, 2017
 
A JavaScript 1.2 Calendar and Clock, Part 3
Blog Entry #385

We continue today our discussion of the image-based digital clock ("image clock" hereafter) on the left side of the Multiple Java Calendar script's js-caltop1.html display. We wrote out the clock's underlying HTML and rendered its initial form in the Clock intro section at the end of the previous post, and we are now ready to set the dynamic parts of the clock via the js-caltop1.html date( ) function.

This will be our second go at an image clock script: In Blog Entries #101 and #359 we created an image clock via a script that
(ST) is discussed by HTML Goodies' JavaScript Script Tips #84, #85, and #86, and
(CCC) is also provided by the Calendars, Clocks, and Calculators sector(s) of JavaScript/Java Goodies.
If truth be told, the Script Tips #84-86 script is much better written than the js-caltop1.html date( ) function, and we will be calling on the former as is appropriate in the deconstruction below.

date( ) intro, noon1, hour

The date( ) function is the first of six functions in the js-caltop1.html source and is the only function in the scripts[0] script. As befits a clock-creating function, the date( ) function is a recursive function, and it is first called when the js-caltop1.html document has loaded.

<body onload="date( );" bgcolor="black" onunload="reseter( );" text="white">
<form name="head"> <!-- We'll get rid of this form later. -->
<input name="hour" type="hidden">
<input name="min" type="hidden">
<input name="sec" type="hidden">
<input name="noon" type="hidden">
</form>
<script> /* Neither a language attribute nor a type attribute is provided for any of the js-caltop1.html script elements. */
var a = 12;
var b = 15;
function date( ) {
    ...clock-creation code...
    window.setTimeout("date( );", 1000); /* Updates the clock every 1000 milliseconds. */ }


Like every other clock script we've covered previously, the date( ) function codes a 12-hour clock, and it loads a dga.gif A image or a dgp.gif P image for a.m. or p.m. respectively into the <img name="noon1"> placeholder. The first date( ) statement assigns dga.gif as a default of sorts (without regard to the hour of the day) to the src of the noon1 img.

document.noon1.src = "dga.gif";

Next, date( ) constructs a today Date object and then gets hour, minute, and second information for that object.

today = new Date( );
hour = today.getHours( );
min = today.getMinutes( );
sec = today.getSeconds( );


We previously constructed a today Date object having a global scope in the date string part of the code; that today would allow us to create a static time display but to create a running clock it is necessary to construct a new Date again and again.

If the getHours( ) return is in the 13-23 range - if we're somewhere between 1 p.m. and midnight - then 12 is subtracted from the return and the noon1 img's src is switched to dgp.gif.

if (hour > 12) {
    hour = today.getHours( ) - 12;
    document.noon1.src = "dgp.gif"; }


• Do we need to call getHours( ) a second time? Nope, hour -= 12; would give us what we want.
• The midnight to 1 a.m. hour is left at 0: it is not subsequently normalized to 12.
document.noon1.src is not subsequently switched to dgp.gif for the noon to 1 p.m. hour (12).

For the hour part of the clock, date( ) loads
(t) either the dgbl.gif blank or a dg1.gif 1 image into the tens-place <img name="hour1"> placeholder, and
(o) a dg0.gif-dg9.gif 0-9 image into the ones-place <img name="hour2"> placeholder.

if (hour < 10) {
    document.hour1.src = "dgbl.gif";
    document.hour2.src = "dg" + hour + ".gif"; }
else {
    document.hour1.src = "dg1.gif";
    document.hour2.src = "dg" + (10 - hour) + ".gif"; }


• The Multiple Java Calendar file set includes a calcbl.gif blank that doesn't have the faint character template present in dgbl.gif; you may want to use the former in place of the latter.
• For the 11 and 12 hours the (10 - hour) subtraction gives -1 and -2, respectively; leaving aside that we could just reverse the order of operands ((hour - 10)), the Multiple Java Calendar file set includes a dg-1.gif 1 image and a dg-2.gif 2 image to accommodate these hours.

OK, let's tighten this up. We'll begin with the a.m./p.m. part because - is everyone writing this down? - if you're coding a 12-hour clock with an a.m./p.m. part, then the a.m./p.m. part is in fact the first part you should deal with. The Script Tips #84-86 script does this indirectly via an amPM variable; we'll use a direct approach. In the present case, one simple line of code gives the right a.m./p.m. setting for every hour of the day:

document.noon1.src = hour > 11 ? "dgp.gif" : "dga.gif";

Upon bringing all of the hours into the 1-12 range

if (hour == 0) hour = 12;
if (hour > 12) hour -= 12;


we can similarly handle the hour part with:

document.hour1.src = hour < 10 ? "calcbl.gif" : "dg1.gif";
document.hour2.src = hour < 10 ? "dg" + hour + ".gif" : "dg" + (hour - 10) + ".gif";


The ?: conditional operator is documented here; it is precedence-wise lower than both </> and +.

As we'll be using the % remainder operator below, let me lastly note that we can alternatively set the hour2.src for every hour of the day via:

document.hour2.src = "dg" + hour % 10 + ".gif";

min, sec, demo

(Near the end of Blog Entry #382 I warned you that the js-caltop1.html source is 'highlighted' by some major-league bloat. Here we go, folks...)

For the min and sec parts of the clock, date( ) loads
(t) a dg0.gif-dg5.gif image into the tens-place <img name="min1"> and <img name="sec1"> placeholders, and
(o) a dg0.gif-dg9.gif image into the ones-place <img name="min2"> and <img name="sec2"> placeholders.
Each part is handled by a sprawling, 11-clause if...else if...else if... cascade.

if (min < 10) {
    document.min1.src = "dg0.gif";
    document.min2.src = "dg" + min + ".gif"; }
else if (min == 10) {
    document.min1.src = "dg1.gif";
    document.min2.src = "dg0.gif"; }
else if (min < 20) {
    document.min1.src = "dg1.gif";
    document.min2.src = "dg" + ((10 - (30 - min)) + 10) + ".gif"; }
...
else if (sec == 50) {
    document.sec1.src = "dg5.gif";
    document.sec2.src = "dg0.gif"; }
else if (sec < 60) {
    document.sec1.src = "dg5.gif";
    document.sec2.src = "dg" + ((10 - (70 - sec)) + 10) + ".gif"; }


The tens-place assignments are straightforward enough, but if there's any rhyme or reason to those ((10 - (x - min|sec)) + 10) ones-place calculations, I don't see it. In any case, our study of the Script Tips #84-86 script gratifyingly enables us to replace each cascade with two lines of code:

document.min1.src = "dg" + Math.floor(min / 10) + ".gif";
document.min2.src = "dg" + min % 10 + ".gif";
document.sec1.src = "dg" + Math.floor(sec / 10) + ".gif";
document.sec2.src = "dg" + sec % 10 + ".gif";


We're good to go at this point. Here's what our clock should look like:


Demo confession:
Blogger's weird image-upload URLs, which I discuss in Blog Entry #359, required me to abandon the
imageObject.src = "dg" + x + ".gif" assignments
in favor of
imageObject.src = dg[x] assignments,
dg being an array of the digit images, à la the Script Tips #84-86 script - a blogger's gotta do what a blogger's gotta do - still, what you see is what you get if you are able to make use of the former.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)