跟隨滑鼠走的時鐘[跨瀏覽器支援]

水之原發表於2013-08-05
(function(){
    var document = window.document;
    var scrollTop = document.body.scrollTop;
    
    var addHandler = document.body.addEventListener ? w3cAddEvent : ieAddEvent;
    var removeHandler = document.body.removeEventListener ? w3cRemoveEvent : ieRemoveEvent;
    
    var daysArray = ["SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"];
    var monthsArray = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"];
    
    function $$(selector){
        return document.querySelectorAll(selector);
    }
    
    function getById(id){
        return document.getElementById(id);
    }
    
    function w3cAddEvent(target, eventType, handler){
        target.addEventListener(eventType, handler, false);
    }
    
    function ieAddEvent(target, eventType, handler){
        target.attachEvent("on" + eventType, handler);
    }
    
    function w3cRemoveEvent(target, eventType, handler){
        target.removeEventListener(eventType, handler, false);
    }
    
    function ieRemoveEvent(target, eventType, handler){
        target.detachEvent("on" + eventType, handler);
    }
    
    function isIE(){
        return navigator.userAgent.indexOf('MSIE') !== -1;
    };
    
    function Clock(options){
        options = options ||
        {};
        
        var dateColor = options.dateColor || '#000000';
        var faceColor = options.faceColor || '#000000';
        var secondsColor = options.secondsColor || '#00ff00';
        var minutesColor = options.minutesColor || '#0000ff';
        var hoursColor = options.hoursColor || '#ff0000';
        
        var i, len;
        var todaysArray = null;
        var face = null;
        var hours = null;
        var minutes = null;
        var seconds = null;
        
        var split = null;
        var dsplit = null;
        var y, x, Y, X, Dx, Dy, DX, DY;
        
        //constants
        var clockHeight = 40;
        var clockWidth = 40;
        var clockFromMouseY = 0;
        var clockFromMouseX = 100;
        
        var font = 'Arial';
        var size = 1;
        var dim = {};
        dim.width = size * 10;
        dim.height = size * 10;
        var speed = 0.6;
        
        var ymouse = 0;
        var xmouse = 0;
        
        var handHeight = clockHeight / 4.5
        var handWidth = clockWidth / 4.5
        var handY = -7;
        var handX = -2.5;
        var step = 0.06;
        var currStep = 0;
        
        function init(){
            todaysArray = getTodaysCharArray();
            faces = getFacesCharArray();
            hours = getHhoursCharArray();
            minutes = getMinutesCharArray();
            seconds = getSecondsCharArray();
            split = 360 / faces.length;
            dsplit = 360 / todaysArray.length;
            initAllArray();
            draw();
        }
        
        function initAllArray(){
            y = [];
            x = [];
            Y = [];
            X = [];
            for (i = 0, len = faces.length; i < len; i++) {
                y[i] = 0;
                x[i] = 0;
                Y[i] = 0;
                X[i] = 0
            }
            Dy = [];
            Dx = [];
            DY = [];
            DX = [];
            for (i = 0, len = todaysArray.length; i < len; i++) {
                Dy[i] = 0;
                Dx[i] = 0;
                DY[i] = 0;
                DX[i] = 0;
            }
        }
        
        function getTodaysCharArray(){
            var date = new Date();
            var day = date.getDate();
            var year = date.getYear();
            if (year < 2000) 
                year = year + 1900;
            var todaysDate = " " + daysArray[date.getDay()] + " " + day + " " + monthsArray[date.getMonth()] + " " + year;
            return todaysDate.split('');
        }
        
        function getFacesCharArray(){
            return '1 2 3 4 5 6 7 8 9 10 11 12'.split(' ');
        }
        
        function getHhoursCharArray(){
            return '...'.split('');
        }
        
        function getMinutesCharArray(){
            return '....'.split('');
        }
        
        function getSecondsCharArray(){
            return '.....'.split('');
        }
        
        function buildTodays(){
            var props2 = "<font face=" + font + " size=" + size + " color=" + dateColor + "><B>";
            var html = [];
            for (i = 0, len = todaysArray.length; i < len; i++) 
                html.push('<div class="cDates" style="position:absolute;top:0px;left:0;height:' + dim.height + ';width:' + dim.width + ';text-align:center">' + props2 + todaysArray[i] + '</B></font></div>');
            return html.join('');
        }
        
        function buildFaces(){
            var props = "<font face=" + font + " size=" + size + " color=" + faceColor + "><B>";
            var html = [];
            for (i = 0, len = faces.length; i < len; i++) 
                html.push('<div class="cFaces" style="position:absolute;top:0px;left:0;height:' + dim.height + ';width:' + dim.width + ';text-align:center">' + props + faces[i] + '</B></font></div>');
            return html.join('');
        }
        
        function buildHours(){
            var html = [];
            for (i = 0, len = hours.length; i < len; i++) 
                html.push('<div class="cHours" style="position:absolute;width:16px;height:16px;font-family:Arial;font-size:16px;color:' + hoursColor + ';text-align:center;font-weight:bold">' + hours[i] + '</div>');
            return html.join('');
        }
        
        function buildMinutes(){
            var html = [];
            for (i = 0, len = minutes.length; i < len; i++) 
                html.push('<div class="cMinutes" style="position:absolute;width:16px;height:16px;font-family:Arial;font-size:16px;color:' + minutesColor + ';text-align:center;font-weight:bold">' + minutes[i] + '</div>');
            return html.join('');
        }
        
        function buildSeconds(){
            var html = [];
            for (i = 0, len = seconds.length; i < len; i++) 
                html.push('<div class="cSeconds" style="position:absolute;width:16px;height:16px;font-family:Arial;font-size:16px;color:' + secondsColor + ';text-align:center;font-weight:bold">' + seconds[i] + '</div>');
            return html.join('');
        }
        
        function buildClockFace(){
            var html = [];
            html.push('<div id="Od" style="position:absolute;top:0px;left:0px"><div style="position:relative">');
            html.push(buildTodays());
            html.push('</div></div>');
            html.push('<div id="Of" style="position:absolute;top:0px;left:0px"><div style="position:relative">');
            html.push(buildFaces());
            html.push('</div></div>');
            html.push('<div id="Oh" style="position:absolute;top:0px;left:0px"><div style="position:relative">');
            html.push(buildHours());
            html.push('</div></div>');
            html.push('<div id="Om" style="position:absolute;top:0px;left:0px"><div style="position:relative">');
            html.push(buildMinutes());
            html.push('</div></div>')
            html.push('<div id="Os" style="position:absolute;top:0px;left:0px"><div style="position:relative">');
            html.push(buildSeconds());
            html.push('</div></div>')
            return html.join('');
        }
        
        function setCFacesPos(){
            getById("Of").style.top = scrollTop + 'px';
            
            var cFaces = $$(".cFaces");
            var cface;
            for (i = 0, len = cFaces.length; i < len; i++) {
                cface = cFaces[i];
                cface.style.top = y[i] + clockHeight * Math.sin(-1.0471 + i * split * Math.PI / 180) + 'px';
                cface.style.left = x[i] + clockWidth * Math.cos(-1.0471 + i * split * Math.PI / 180) + 'px';
            }
        }
        
        function setCHoursPos(hrs){
            getById("Oh").style.top = scrollTop + 'px';
            
            var cHours = $$(".cHours");
            var cHour;
            for (i = 0, len = cHours.length; i < len; i++) {
                cHour = cHours[i];
                cHour.style.top = y[i] + handY + (i * handHeight) * Math.sin(hrs) + 'px';
                cHour.style.left = x[i] + handX + (i * handWidth) * Math.cos(hrs) + 'px';
            }
        }
        
        function setCMinutesPos(min){
            getById("Om").style.top = scrollTop + 'px';
            
            var cMinutes = $$(".cMinutes");
            var cMinute;
            for (i = 0, len = cMinutes.length; i < len; i++) {
                cMinute = cMinutes[i];
                cMinute.style.top = y[i] + handY + (i * handHeight) * Math.sin(min) + 'px';
                cMinute.style.left = x[i] + handX + (i * handWidth) * Math.cos(min) + 'px';
            }
        }
        
        function setCSecondsPos(sec){
            getById("Os").style.top = scrollTop + 'px';
            
            var cSeconds = $$(".cSeconds");
            var cSecond;
            for (i = 0, len = cSeconds.length; i < len; i++) {
                cSecond = cSeconds[i];
                cSecond.style.top = y[i] + handY + (i * handHeight) * Math.sin(sec) + 'px';
                cSecond.style.left = x[i] + handX + (i * handWidth) * Math.cos(sec) + 'px';
            }
        }
        
        function setCDatesPos(){
            getById("Od").style.top = scrollTop + 'px';
            
            var cDates = $$(".cDates");
            var cDate;
            for (i = 0, len = cDates.length; i < len; i++) {
                cDate = cDates[i];
                cDate.style.top = Dy[i] + clockHeight * 1.5 * Math.sin(currStep + i * dsplit * Math.PI / 180) + 'px';
                cDate.style.left = Dx[i] + clockWidth * 1.5 * Math.cos(currStep + i * dsplit * Math.PI / 180) + 'px';
            }
            
            currStep -= step;
        }
        
        function clockAndAssign(){
            var time = new Date();
            var secs = time.getSeconds();
            var sec = -1.57 + Math.PI * secs / 30;
            var mins = time.getMinutes();
            var min = -1.57 + Math.PI * mins / 30;
            var hr = time.getHours();
            var hrs = -1.575 + Math.PI * hr / 6 + Math.PI * parseInt(time.getMinutes()) / 360;
            
            setCFacesPos();
            setCHoursPos(hrs);
            setCMinutesPos(min);
            setCSecondsPos(sec);
            setCDatesPos();
        }
        
        function delay(){
            Dy[0] = Math.round(DY[0] += ((ymouse) - DY[0]) * speed);
            Dx[0] = Math.round(DX[0] += ((xmouse) - DX[0]) * speed);
            for (i = 1, len = todaysArray.length; i < len; i++) {
                Dy[i] = Math.round(DY[i] += (Dy[i - 1] - DY[i]) * speed);
                Dx[i] = Math.round(DX[i] += (Dx[i - 1] - DX[i]) * speed);
            }
            y[0] = Math.round(Y[0] += ((ymouse) - Y[0]) * speed);
            x[0] = Math.round(X[0] += ((xmouse) - X[0]) * speed);
            for (i = 1, len = faces.length; i < len; i++) {
                y[i] = Math.round(Y[i] += (y[i - 1] - Y[i]) * speed);
                x[i] = Math.round(X[i] += (x[i - 1] - X[i]) * speed);
            }
            clockAndAssign();
        }
        
        function draw(){
            document.body.innerHTML += buildClockFace();
            return this;
        }
        
        function start(){
            addHandler(document, "mousemove", function(e){
                e = e || window.event;
                ymouse = !isIE() ? e.pageY + clockFromMouseY : e.y + clockFromMouseY;
                xmouse = !isIE() ? e.pageX + clockFromMouseX : e.x + clockFromMouseX;
            });
            
            addHandler(window, "load", function(e){
                window.clockTimer = setInterval(delay, 20);
            });
            
            return this;
        }
        
        function stop(){
            clearInterval(window.clockTimer);
            return this;
        }
        
        init();
        
        return {
            draw: draw,
            start: start,
            stop: stop
        };
    }
    
    window.Clock = Clock;
})();

Clock().start();

相關文章