学学jscode的超酷HTML5时钟

    看了jscode的《HTML5编程百例之一:HTML5时钟》,很赞!不过有一些地方觉得不太合理,就自己动手重构了下,欢迎大家拍砖!

    改进的地方有:

1、不用反复重绘不变的圆盘、刻度和数字;

2、封装了一下;

    效果图:

00:00:00
插入文件的功能用不了,只有贴出源代码了,郁闷。  
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>超酷HTML5时钟(作者:http://www.cnblogs.com/jscode/)</title>
    <style type="text/css">
         .time {
            text-align: center;
            400px;
            font-family: "Book Antiqua",Palatino,serif;
            font-size: 40px;
            font-weight: bold;
            text-shadow: 1px 1px 3px #333;
            position:absolute;
        }
        .time em {
            background: white;
            position: absolute;
            top: 5px;
            left: 130px;
            height: 18px;
             140px;
            opacity: 0.4;
        }
    </style>
</head>
<body>
    <h1>超酷HTML5时钟(作者:http://www.cnblogs.com/jscode/)</h1>
    <canvas id="clock" width="400px" height="400px"></canvas>
    <div class="time"><span id="currtime">00:00:00</span><em></em></div>
</body>
</html>
<script type="text/javascript">
    (function(window, canvasID){
        if(window.Clock){
            return null;
        }
        
        window.Clock = (function(window, canvasID){
            function Clock(canvasID){
                this.date = new Date();
                this.id = canvasID;
                this.canvas = window.document.getElementById("clock");
                this.context = this.canvas.getContext("2d");
                this.radius = Math.min(this.canvas.width / 2, this.canvas.height / 2) - 25;
                this.center = {x: this.canvas.width/2, y: this.canvas.height/2};
                this.defaultStyle = {fill: "#EFEFEF", stroke: "#000"};
                this.hourStyle = {lineWidth: 8, length: this.radius - 10 };
                this.minuteStyle = {lineWidth: 5, length: this.radius - 20 };
                this.secondStyle = {lineWidth: 3, length: this.radius - 30 };
                this.dialStyle = {lineWidth:18};//表盘
                this.scaleStyle = { thin: {lineWidth:1}, wide: {lineWidth:3} };//刻度
                this.backStyle = { font: "bold 20px 宋体" };
                
            }
            
            Clock.prototype.drawBackground = function(){
                var context = this.context;
                
                context.save();
                context.lineWidth = this.dialStyle.lineWidth;
                context.fillStyle = this.backStyle.fill || this.defaultStyle.fill;
                context.strokeStyle = this.backStyle.stroke || this.defaultStyle.stroke;
                context.beginPath();
                context.arc(this.center.x, this.center.y, this.radius, 0, Math.PI * 2, 0);
                context.stroke();
                context.fill();
                context.closePath();
                context.restore();
                context.fillStyle = this.backStyle.fill || this.defaultStyle.fill;
                context.strokeStyle = this.backStyle.stroke || this.defaultStyle.stroke; 
                for (var i = 0; i < 30; i++) {
                    context.save();
                    context.lineWidth = i%5 === 0 ? this.scaleStyle.wide.lineWidth : this.scaleStyle.thin.lineWidth;
                    context.beginPath();
                    context.moveTo(this.center.x + (this.radius-6) * Math.cos((i + 30) * 6 * Math.PI / 180), this.center.y - (this.radius-5) * Math.sin((i + 30) * 6 * Math.PI / 180));
                    context.lineTo(this.center.x + (this.radius-6) * Math.cos(i * 6 * Math.PI / 180), this.center.y - (this.radius-5) * Math.sin(i * 6 * Math.PI / 180));
                    context.fill();
                    context.stroke();
                    context.closePath();
                    context.restore();
                }
                context.moveTo(this.center.x, this.center.y);
                context.save();
                context.fillStyle = this.backStyle.fill;
                context.beginPath();
                context.arc(this.center.x, this.center.y, this.radius-16, 0, Math.PI * 2, 0);
                context.fill();
                context.closePath();
                context.restore();
            
                var r = this.radius - 25;
                context.fillStyle = this.defaultStyle.stroke;
                context.font = this.backStyle.font;
                var jiaodu = 0;
                for ( var i=1, step=30; i < 13; i++ ) {
                       if( i <= 3 ){
                           jiaodu = 90 - i*30;
                       } else {
                           jiaodu = 360 - (i - 3)*30;
                       }
                       this.drawtext(i, this.center.x + (Math.cos(jiaodu * Math.PI / 180) * r), this.center.y - (Math.sin(jiaodu * Math.PI / 180) * r));    
                }

                context.moveTo(this.center.x, this.center.y);
                context.save();
                context.fillStyle = this.defaultStyle.stroke;
                context.beginPath();
                context.arc(this.center.x, this.center.y, 10, 0, Math.PI * 2, 0);
                context.fill();
                context.closePath();
                context.restore();
            };
            
            Clock.prototype.drawtext = function(content, x, y) {
                content = content.toString()
                var context = this.context;
                context.save();
                x -= (context.measureText(content).width / 2);
                y += 9;
                context.beginPath();
                context.translate(x, y);
                context.fillText(content, 0, 0);
                context.restore();
            };

            Clock.prototype.drawHands = function(){
                var hour = this.date.getHours() % 12;
                var minute = this.date.getMinutes();
                var second = this.date.getSeconds();
                
                var paddingLeft = function( n ){
                    return n.toString().length == 1 ? n.toPrecision(2).toString().split(".").reverse().join("") : n.toString();
                };
                
                document.getElementById("currtime").innerHTML = [].concat(paddingLeft(hour), paddingLeft(minute), paddingLeft(second)).join(":");
                
                var hourJiaodu = hour * 30 * Math.PI / 180 + (minute / 60) * 30 * Math.PI / 180 + 90 * Math.PI / 180;
                var minuteJiaodu = minute * 6 * Math.PI / 180 + second / 60 * 6 * Math.PI / 180 + 90 * Math.PI / 180;
                var secondJiaodu = second * 6 * Math.PI / 180 + 90 * Math.PI / 180;
                
                this.drawHand(this.hourStyle, hourJiaodu, 110);
                this.drawHand(this.minuteStyle, minuteJiaodu, 60);
                this.drawHand(this.secondStyle, secondJiaodu, 40);
            };
            
            Clock.prototype.drawHand = function(style, jiaodu, step){
                var context = this.context;
                
                context.save();
                context.lineWidth = style.lineWidth || this.defaultStyle.lineWidth;
                context.fillStyle = style.fill || this.defaultStyle.fill;
                context.strokeStyle = style.stroke || this.defaultStyle.stroke;
                context.beginPath();
                context.moveTo(this.center.x + 20 * Math.cos(jiaodu), this.center.y + 20 * Math.sin(jiaodu));
                context.lineTo(this.center.x - (this.radius - step) * Math.cos(jiaodu), this.center.y - (this.radius - step) * Math.sin(jiaodu));
                context.closePath();
                context.fill();
                context.stroke();
                context.restore();
            };
            
            Clock.prototype.reset = function(){
                var context = this.context;
                
                //清空指针
                context.save();
                context.lineWidth = 0;
                context.fillStyle = this.defaultStyle.fill;
                context.beginPath();
                context.arc(this.center.x, this.center.y, this.radius-38, 0, Math.PI * 2, 0);
                context.fill();
                context.closePath();
                context.restore();

                //绘制圆心
                context.save();
                context.fillStyle = this.defaultStyle.stroke;
                context.beginPath();
                context.arc(this.center.x, this.center.y, 10, 0, Math.PI * 2, 0);
                context.fill();
                context.closePath();
                context.restore();
                
            };
            
            Clock.prototype.draw = function(){
                this.date = new Date();
                this.reset();
                this.drawHands();
            };
            
            Clock.prototype.run = function(){
                this.drawBackground();
                var that = this;
                setInterval(function(){
                    Clock.prototype.draw.apply(that)
                }, 1000);
            };
            
            return new Clock(canvasID);
        })(window, canvasID);
        
        window.Clock.run();
        
    })(window, "clock");
</script>


demo
原文地址:https://www.cnblogs.com/ihada/p/2442780.html