JavaScript 制作圆形时钟

上次用html和css制作了CSS时钟、高级动画,不过上次的只是会动,时间不准的,今天做的这个是和电脑系统时间一致的,而且是用纯JavaScript制作的。下面看看代码:

HTML:

1. <!DOCTYPE html>
2. <html lang="en">
3.     <head>
4.         <meta charset="utf-8">
5.         <title>时钟</title>
6.         <script src="js/control.js"></script>
7.         <script src="js/dot.js"></script>
8.         <script src="js/second.js"></script>
9.         <script src="js/Minute.js"> </script>
10.         <script src="js/hour.js"> </script>
11.         <script src="js/Diamond.js"></script>
12.         <script src="js/clock.js"></script>
13.         <style>
14.         </style>
15.     </head>
16.     <body>
17.         <script>
18.             new Clock()
19.
20.
21.         </script>
22.     </body>
23. </html>

**control.js**

1. // 控件类 页面所有可见元素都从这里继承
2. // 提供了创建功能(render方法) 和布局功能(layout方法)
3. function Control(){
4.         this.reader()
5.         this.layout()
6. }
7. // 填充颜色
8. Control.prototype.fillColor = 'black'
9. // 添加到页面上
10.
11. Control.prototype.reader = function(){
12.     this.ele = document.createElement('div')
13.     this.ele.style.backgroundColor = this.fillColor
14.     this.ele.style.position = 'absolute'
15.     document.body.appendChild(this.ele)
16. }
17. // 调整大小的页面上的位置
18. Control.prototype.layout = function(){}
19. Control.windowResized = function(){
20.     Control.clientWidth = document.documentElement.clientWidth
21.     Control.clientHeight = document.documentElement.clientHeight
22.     Control.radius = Math.min(Control.clientWidth,Control.clientHeight) / 2
23.     console.log('窗口工作区%d,%d',Control.clientWidth,Control.clientHeight,Control.radius)
24. }
25. Control.windowResized()

**dot.js**

1. function Dot(){
2.     Control.call(this)
3. }
4. Dot.prototype = Object.create(Control.prototype)
5. Dot.prototype.constructor = Dot
6.
7. Dot.prototype.reader = function(){
8.     Control.prototype.reader.call(this)
9.      this.ele.style.borderRadius = '50%'
10.      this.ele.style.zIndex = 10
11.      console.log(this.ele)
12.
13. }
14. Dot.prototype.layout = function(){
15.     var radius  = Control.radius * 0.04
16.     this.ele.style.width = radius * 2 + 'px'
17.     this.ele.style.height = radius * 2 + 'px'
18.     this.ele.style.top = Control.clientHeight / 2 - radius + 'px'
19.     this.ele.style.left = Control.clientWidth / 2 - radius + 'px'
20. }

**second.js**

1. function Second(color){
2.     this.fillColor = color || 'red'
3.     Control.call(this)
4. }
5. Second.prototype = Object.create(Control.prototype)
6. Second.prototype.constructor = Second
7.
8. Second.prototype.caclArgs = function(){
9.       var args = {}
10.       args.duration = 60
11.       args.zIndex = 9
12.       var time = new Date()
13.       var s = time.getSeconds()*-1
14.
15.       args.delay = s - 15
16.       return args
17. }
18. Second.prototype.calcLayoutArgs = function(){
19.     var args ={}
20.     args.radius = Control.radius * 0.9
21.     args.width = args.radius * 1.15
22.     args.height = args.radius * 0.01
23.     return args
24. }
25. Second.prototype.reader = function(){
26.     var args = this.caclArgs()
27.     Control.prototype.reader.call(this)
28.     this.ele.style.backgroundColor ='initial'
29.     this.ele.style.animationName = 'rotate'
30.     this.ele.style.animationTimingFunction = 'linear'
31.     this.ele.style.animationIterationCount = 'infinite'
32.     this.ele.style.animationDuration = args.duration + 's'
33.     this.ele.style.animationDelay = args.delay +'s'
34.     this.ele.style.zIndex= args.zIndex
35.
36.     this.el = document.createElement('span')
37.     this.el.style.display = 'block'
38.     this.el.style.backgroundColor = this.fillColor
39.     this.ele.appendChild(this.el)
40.
41. }
42. Second.prototype.layout = function(){
43.     var args = this.calcLayoutArgs()
44.     this.ele.style.width = args.radius * 2  + 'px'
45.     this.ele.style.height = 10 +'px'
46.     this.ele.style.top = Control.clientHeight / 2 - 5 + 'px'
47.     this.ele.style.left = Control.clientWidth / 2 - args.radius + 'px'
48.
49.     this.el.style.width = args.width + 'px'
50.     this.el.style.height = args.height + 'px'
51.     this.el.style.marginTop = 5 - args.height / 2 + 'px'
52.     this.el.style.borderRadius = args.height / 2 + 'px'
53. }

**Minute.js**

1. function Minute(color){
2.    Second.call(this,color || 'black')
3. }
4. Minute.prototype = Object.create(Second.prototype)
5. Minute.prototype.constructor = Minute
6.
7. Minute.prototype.caclArgs = function(){
8.       var args = {}
9.       args.duration = 3600
10.       args.zIndex = 8
11.       var time = new Date()
12.       var s = time.getSeconds()*-1
13.       var m = time.getMinutes() * -1
14.
15.
16.       args.delay = (m * 60) - ( 15 * 60) + s;
17.       return args
18. }
19. Minute.prototype.calcLayoutArgs = function(){
20.     var args ={}
21.     args.radius = Control.radius * 0.8
22.     args.width = args.radius * 1.12
23.     args.height = args.radius * 0.03
24.     return args
25. }

**hour.js**

1. function Hour(color){
2.     Second.call(this,color || 'black')
3. }
4. Hour.prototype = Object.create(Second.prototype)
5. Hour.prototype.constructor = Hour
6.
7. Hour.prototype.caclArgs = function(){
8.       var args = {}
9.       args.duration = 43200
10.       args.zIndex = 7
11.       var time = new Date()
12.       var s = time.getSeconds()*-1
13.       var m = time.getMinutes() * -1
14.       var h = time.getHours()
15.       h = h>12?h-12:h
16.       h = h*-1
17.       args.delay =(h*60*60) - (3*60*60) + (m*60) + s
18.       return args
19. }
20.
21. Hour.prototype.calcLayoutArgs = function(){
22.     var args ={}
23.     args.radius = Control.radius * 0.6
24.     args.width = args.radius * 1.13
25.     args.height = args.radius * 0.05
26.     return args
27. }

**clock.js**

1. function Clock(){
2.     // 添加样式表
3.     var i = 0
4.     var style = document.createElement('style')
5.     document.head.appendChild(style)
6.     style.sheet.insertRule('html{height:100%}',i++)
7.     style.sheet.insertRule('body{margin:0;height:100%}',i++)
8.     style.sheet.insertRule('*{box-sizing:border-box}',i++)
9.     style.sheet.insertRule('@keyframes rotate{from{ transform:rotate(0);} to{transform:rotate(360deg); }}',i++)
10.
11.     // 创建时钟
12.     var dot = new Dot()
13.     var second = new Second()
14.     var minute = new Minute('yellow')
15.     var hour = new Hour('blue')
16.     var diamonds = []
17.     for(var i = 0;i<60;i++){
18.         var sizeRadio = i % 5 == 0 ? 0.02:0
19.         diamonds.push(new Diamond(i,sizeRadio))
20.     }
21.     window.onresize = function(){
22.         Control.windowResized()
23.         dot.layout()
24.         second.layout()
25.         minute.layout()
26.         hour.layout()
27.        for(var i =0;i<60;i++){
28.            diamonds[i].layout()
29.        }
30.     }
31. }

**Diamond.js**

1. // 时钟周围小圆点
2. function Diamond(minute,sizeRadio){
3.     this.minute  = minute
4.     this.sizeRadio = sizeRadio || 0.01
5.     //  弧度 = 角度*Math.PI / 180
6.     this.arc = 6*(this.minute - 15)*Math.PI / 180
7.     Control.call(this)
8. }
9.
10. Diamond.prototype = Object.create(Control.prototype)
11. Diamond.prototype.constructor = Diamond
12.
13. Diamond.prototype.reader = function(){
14.     Control.prototype.reader.call(this)
15.     this.ele.style.borderRadius = '50%'
16.     this.ele.style.zIndex = 5
17.
18. }
19. Diamond.prototype.layout =function(){
20.     var size = Control.radius * this.sizeRadio
21.     this.ele.style.width = size * 2 + 'px'
22.     this.ele.style.height = size * 2 + 'px'
23.
24.     var radius = Control.radius * 0.9
25.     var left = radius * Math.cos(this.arc)
26.     var top = radius*Math.sin(this.arc)
27.
28.
29.     this.ele.style.top = Control.clientHeight / 2 + top - size + 'px'
30.     this.ele.style.left = Control.clientWidth / 2 + left - size + 'px'
31.
32.
33. }

演示效果:

时钟