//SOLVE: A visual clock

Reading the time and doing circle math

This one will appeal to some mathematicians. Every second, the page rereads the year, month, date, hour, minute, and second. Then it displays them as a series of moving dots - one for each measure of time.

Part of the problem includes finding the size and centres of the screen, which will be different for each person visiting.

However, the real magic comes from converting the time measurements into fractions of a circle, and then from there into left and right coodinates using trigonometry.

Source code

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>A visual clock</title>
        
        <!-- link to jQuery for animations -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
        <script>
            // clock OBJECT
            //  properties:
            //      clock.timeProperties
            //
            //      clock.year
            //      clock.month
            //      clock.day
            //      clock.hour
            //      clock.minute
            //      clock.second
            //
            //      clock.maximum
            //
            //      clock.width
            //      clock.height
            //      clock.screen
            //      clock.centreLeft
            //      clock.centerTop
            //
            //  methods:
            //      clock.getTime()
            //      clock.padZero()
            //      clock.displayText()
            //      clock.calculateCenters()
            //      clock.displayOrrery()
            //
            var clock = {
                // an array to hold the list of time units
                timeProperties: [
                    "year",
                    "month",
                    "day",
                    "hour",
                    "minute",
                    "second"
                ],
                    
                // store the current time information
                second:    0,
                minute:    0,
                hour:      0,
                day:       0,
                month:     0,
                year:      0,
                
                // store the maximums for each time measure
                maximum: {
                    second:    60,
                    minute:    60,
                    hour:      24,
                    day:       31,
                    month:     12,
                    year:      3000
                },
                
                // INIT: define the screen dimensions
                width:          window.innerWidth - 20,
                height:         window.innerHeight - 20,
                screen:         Math.min( window.innerWidth, window.innerWidth ),
                centerLeft:     0,
                centerTop:      0,
                                    
                // INPUT: get and store the current time information
                getTime: function () {
                    var dateObject = new Date();
                    
                    this.hour       = dateObject.getHours();
                    this.minute     = dateObject.getMinutes();
                    this.second     = dateObject.getSeconds();
                    
                    this.month      = dateObject.getMonth() + 1;
                    this.day        = dateObject.getDate();
                    this.year       = dateObject.getFullYear();
                },
                
                // PROCESS: adds a zero to the front of hrs, secs, mins 
                padZero: function ( number ) {
                    var padded = "0" + number; 
                    return padded.substr(padded.length - 2, 2);
                },
                
                // OUTPUT: displays the current time as text
                displayText: function () {
                    // loop through each time property
                    for (i in this.timeProperties) {
                        // display the stored time inside the correct #ID 
                        document.getElementById( this.timeProperties[i] + 'ID' ).innerHTML 
                            = this.padZero( this[ this.timeProperties[i] ] );
                    }
                },
                
                // PROCESS: this calculates the center of the page                  
                calculateCenters: function () {
                    this.centerLeft = this.width / 2;
                    this.centerTop = this.height / 2;
                },
                
                // PROCESS: calculate the new position of this circle marker
                calculatePosition: function ( currentValue, maximumValue, unitRank) {
                    // define position as an empty object
                    var position    = {};
                    
                    // calculate the ratio of the current unitRank
                    // this will be how far around the circle the marker is
                    // for example, if it is 05:23:19
                    // hours ratio = 5/24, minutes ratio = 23/60, seconds ratio = 19/60
                    var ratio       = currentValue / maximumValue;
                    
                    // calculate how far the marker is out from the centre
                    // the year is closest to the centre, seconds are furthermost
                    var radius      = this.screen / 4 * unitRank / 5.6;
                                        
                    // calculate the top and left positions based on the:
                    //      radius
                    //      centre coordinates
                    //      ratio
                    position.top    = this.centerTop    + radius    * Math.sin( 2 * Math.PI * ratio - Math.PI / 2);     
                    position.left   = this.centerLeft   + radius    * Math.cos( 2 * Math.PI * ratio - Math.PI / 2 );
                        
                    return position;
                },
                
                // OUTPUT: displays the orrery
                displayOrrery: function () {
                    // loop through each time property
                    for (i in this.timeProperties) {
                        // get the new position
                        var position    = this.calculatePosition( 
                                            this[ this.timeProperties[i] ], 
                                            this.maximum[ this.timeProperties[i] ], 
                                            i 
                                        );
                                        
                        //animate to the new positions
                        $( '#' + this.timeProperties[i] + 'PlanetID' ).animate(
                            {   top:        position.top + 'px',
                                left:       position.left + 'px' },
                            {   duration:   800,
                                easing:     'linear' }
                        );
                    }
                }
            }

            // tick along changing things every second
            setInterval( function () {
                clock.getTime();
                clock.displayText();
                clock.displayOrrery();
                }, 1000
            );
                
            // triggered when the page has finished loading
            var mainProcedure = function () {
                clock.calculateCenters()
            }
        </script>
        <style>
            body {
                background-color:   black;
                color:              #444444;
                font-family:        "Consolas", monospace;
                font-size:          30px;
                text-align:         left;
            }
            div {
                position:   absolute;
                top:            50%;
                left:           50%;
                height:         16px;
                width:          16px;
                border-radius:  8px;
            }
            #yearPlanetID {
                background-color:   #222222;
            }
            #yearID {
                color:              #222222;
            }
            #monthPlanetID {
                background-color:   #444444;
            }
            #monthID {
                color:              #444444;
            }
            #dayPlanetID {
                background-color:   #666666;
            }
            #dayID {
                color:              #666666;
            }
            #hourPlanetID {
                background-color:   #888888;
            }
            #hourID {
                color:              #888888;
            }
            #minutePlanetID {
                background-color:   #aaaaaa;
            }
            #minuteID {
                color:              #aaaaaa;
            }
            #secondPlanetID {
                background-color:   #cccccc;
            }
            #secondID {
                color:              #cccccc;
            }
        </style>
    </head>
    <body onload="mainProcedure();">
        <p>
            A visual<br />clock<br />
            <span id="yearID"></span>
            <span id="monthID"></span>
            <span id="dayID"></span>
            <br />
            <span id="hourID"></span>
            <span id="minuteID"></span>
            <span id="secondID"></span>
            
        </p>

        <div id="yearPlanetID"></div> 
        <div id="monthPlanetID"></div> 
        <div id="dayPlanetID"></div> 

        <div id="hourPlanetID"></div>
        <div id="minutePlanetID"></div> 
        <div id="secondPlanetID"></div> 

    </body>
</html>