一、机械时钟
1.最终效果
用 CSS 绘制的机械时钟效果如下:
HTML 中代码结构为:
<body><div class="clock"><ul class="min"></ul><ul class="hour"></ul><ul class="numbers"></ul><ul class="pointer"></ul></div></body>
其中 clock 类为表盘, min 类是分钟刻度,hour 类是时钟刻度,numbers 类是数字刻度,类名为 pointer 的 ul 中包含的则是时针、分针和秒针等。
2.绘制表盘
首先要把表盘和表盘中心给绘制出来,如下图:
表盘中心要处在正中心,使用绝对定位进行实现,代码如下:
/* 表盘 */ .clock { 200px; height: 200px; margin: 30px auto; border-radius: 100px; background-color: #292a38; position: relative; } .circle { position: absolute; top: 50%; left: 50%; background: white; 10px; height: 10px; border-radius: 5px; margin-top: -5px; margin-left: -5px; }
3.绘制刻度
钟表的刻度就是一个矩形,只不过需要根据表盘中心进行偏移,例如:
对应的代码为:
/* 刻度 */
.line-demo { position: absolute; 20px; height: 10px; left: 50%; top: 50%; transform-origin: left center; transform: translate(85px, -5px); }
但要实现一点到十二点总共十二个刻度,还需要使用 transform 中的 rotate() 进行旋转,实现的代码如下,其中 val 表示的是各个刻度线对应的旋转角度,而 key1 和 key2 分别表示 x 方向和 y 方向上的偏移量,而对 key1 和 key2 进行调整,是为了改善刻度线显示的效果。
1 function CreateHourLines() { 2 /* 绘制钟表的时钟刻度线 */ 3 var html = ""; 4 // key1表示x方向上的偏移量,key2表示y方向上的偏移量 5 var val, key1, key2; 6 for (var i = 0; i < 12; i++) { 7 val = i * 30; 8 key1 = 88; 9 key2 = 0; 10 if (val > 180 && val < 360) { 11 key1 = 90; 12 } 13 if (val > 0 && val < 180) { 14 key1 = 85 15 } 16 17 if (val > 90 && val < 270) { 18 key2 = 3; 19 } 20 if (val < 90 || val > 270) { 21 key2 = -3; 22 } 23 html += "<li style='transform: rotate(" + val + "deg) translate(" + key1 + "px, " + key2 + "px)'></li>"; 24 } 25 $(".hour").html(html); 26 }
分钟的刻度线绘制和时钟类似,除此之外,还要绘制各个小时的数字刻度,效果如下:
4.绘制指针
指针的绘制要把时针、分针和秒针都绘制出来,需要注意的是时钟最短最粗,秒针最长最细,而且都要用绝对定位使指针处在表盘中心,实现的效果如下:
时针、分针和秒针的 CSS 代码如下:
/* 指针 */ .p-hour { position: absolute; 45px; height: 3px; top: 50%; left: 50%; transform-origin: left center; background: #fff; margin-top: -2px; } .p-min { position: absolute; 60px; height: 2px; top: 50%; left: 50%; transform-origin: left center; background: #fff; margin-top: -2px; } .p-sec { position: absolute; 80px; height: 1px; top: 50%; left: 50%; transform-origin: left center; background: #fff; margin-top: -2px; }
5.转动指针
指针的转动要通过使用 transform 中的 rotate 进行实现,而转动的角度则要根据此刻的时分秒进行计算得到,代码如下:
1 function move() { 2 setInterval(function() { 3 // 获取当前时刻 4 var date = new Date(); 5 var sec = date.getSeconds(); 6 var min = date.getMinutes(); 7 var hour = date.getHours(); 8 // 计算各指针对应的角度 9 var secAngle = sec * 6 - 90; // s*6-90 10 var minAngle = min * 6 + sec * 0.1 - 90; // m*6+s*0.1-90 11 var hourAngle = hour * 30 + min * 0.5 - 90; // h*30+m*0.5 - 90 12 // 转动指针 13 $(".p-sec").css("transform", "rotate(" + secAngle + "deg)"); 14 $(".p-min").css("transform", "rotate(" + minAngle + "deg)"); 15 $(".p-hour").css("transform", "rotate(" + hourAngle + "deg)"); 16 }, 1000) 17 }
二、数字时钟
1.最终效果
用 CSS 绘制的数字时钟效果如下:
HTML 中代码结构为:
<body><div class="back"><div class="content"><div class="one"> </div><div class="two"></div><div class="three"></div><div class="four"></div><div class="five"></div><div class="six"></div><div class="seven"></div><div class="eight"></div></div></div></body>
其中 back 类是时钟的背景,content 类则是数字时钟表盘,在 content 类的 div 中包含了八个 div,分别表示六个数字和两个分隔符号。
2.绘制数字
每一个数字由七个部分组成,每个部分都类似下图中的样式:
这就是一个矩形,两端分别有一个三角形,而这两个三角形都可以通过使用伪元素 before 和 after 实现,实现的代码如下:
.part-1 { 30px; height: 6px; background: white; position: absolute; left: 10px; } .part-1::before { content: ""; position: absolute; left: -6px; 0; height: 0; border-top: 3px solid white; border-left: 3px solid; border-right: 3px solid white; border-bottom: 3px solid; } .part-1::after { content: ""; position: absolute; left: 30px; 0; height: 0; border-top: 3px solid white; border-left: 3px solid white; border-right: 3px solid; border-bottom: 3px solid; }
通过修改 CSS 样式就能将其余部分绘制出来了,除了绘制数字,还需要把每两个数字间的分隔符号给绘制出来,如下图:
3.显示数字
要显示数字0-9,需要将七个部分中的某些部分进行改动,例如将背景色修改成黑色,就能达到显示数字的效果,如下:
显示数字的代码如下,其中 showDigit() 需要传入两个参数,name 表示的是显示第几位数字的 CSS 类名,num 表示的是要显示的数字:
1 function showDigit(name, num) { 2 // show digit 3 if (num === 1) { 4 $(name + " .part-1").css("background", "black"); 5 $(name + " .part-1").addClass("change"); 6 $(name + " .part-2").css("background", "black"); 7 $(name + " .part-2").addClass("change"); 8 $(name + " .part-3").css("background", "black"); 9 $(name + " .part-3").addClass("change"); 10 $(name + " .part-6").css("background", "black"); 11 $(name + " .part-6").addClass("change"); 12 $(name + " .part-7").css("background", "black"); 13 $(name + " .part-7").addClass("change"); 14 } 15 if (num === 2) { 16 $(name + " .part-5").css("background", "black"); 17 $(name + " .part-5").addClass("change"); 18 $(name + " .part-6").css("background", "black"); 19 $(name + " .part-6").addClass("change"); 20 } 21 if (num === 3) { 22 $(name + " .part-6").css("background", "black"); 23 $(name + " .part-6").addClass("change"); 24 $(name + " .part-7").css("background", "black"); 25 $(name + " .part-7").addClass("change"); 26 } 27 if (num === 4) { 28 $(name + " .part-1").css("background", "black"); 29 $(name + " .part-1").addClass("change"); 30 $(name + " .part-3").css("background", "black"); 31 $(name + " .part-3").addClass("change"); 32 $(name + " .part-7").css("background", "black"); 33 $(name + " .part-7").addClass("change"); 34 } 35 if (num === 5) { 36 $(name + " .part-4").css("background", "black"); 37 $(name + " .part-4").addClass("change"); 38 $(name + " .part-7").css("background", "black"); 39 $(name + " .part-7").addClass("change"); 40 } 41 if (num === 6) { 42 $(name + " .part-4").css("background", "black"); 43 $(name + " .part-4").addClass("change"); 44 } 45 if (num === 7) { 46 $(name + " .part-2").css("background", "black"); 47 $(name + " .part-2").addClass("change"); 48 $(name + " .part-3").css("background", "black"); 49 $(name + " .part-3").addClass("change"); 50 $(name + " .part-6").css("background", "black"); 51 $(name + " .part-6").addClass("change"); 52 $(name + " .part-7").css("background", "black"); 53 $(name + " .part-7").addClass("change"); 54 } 55 if (num === 9) { 56 $(name + " .part-7").css("background", "black"); 57 $(name + " .part-7").addClass("change"); 58 } 59 if (num === 0) { 60 $(name + " .part-2").css("background", "black"); 61 $(name + " .part-2").addClass("change"); 62 } 63 }
在上面的代码中,每次改动都要 addClass("change"),其中 change 类是一个新的 class,用于对伪元素进行覆盖,相应代码为:
.change::before { border: 0; } .change::after { border: 0; }
4.显示时间
首先需要使用 JavaScript 获取当前时间,然后计算得到六个数字,再使用上面的 showDigit() 来显示数字,效果如下:
显示时间的代码为:
1 function getDigit() { 2 // get the present time 3 var date = new Date(); 4 var hour = date.getHours(); 5 var min = date.getMinutes(); 6 var sec = date.getSeconds(); 7 // six digits 8 var d1, d2, d3, d4, d5, d6; 9 d1 = parseInt(hour / 10); 10 d2 = hour % 10; 11 d3 = parseInt(min / 10); 12 d4 = min % 10; 13 d5 = parseInt(sec / 10); 14 d6 = sec % 10; 15 showDigit(".one", d1); 16 showDigit(".two", d2); 17 showDigit(".four", d3); 18 showDigit(".five", d4); 19 showDigit(".seven", d5); 20 showDigit(".eight", d6); 21 }
5.时间变换
由于我们显示数字的时候不仅修改了背景色,而且还增加了一个新的 class,所以在时间变换的时候,不仅需要修改显示的数字,还需要对相应的 CSS 进行修改,这样才能正确的变换时间。实现的具体方法为每次显示数字时,先把每个部分的 CSS 重置成最开始的样子,背景色改为白色,因而显示数字的代码改为:
1 function showDigit(name, num) { 2 // initial 3 $(name + " .part-1").css("background", "white"); 4 $(name + " .part-1").removeClass("change"); 5 $(name + " .part-2").css("background", "white"); 6 $(name + " .part-2").removeClass("change"); 7 $(name + " .part-3").css("background", "white"); 8 $(name + " .part-3").removeClass("change"); 9 $(name + " .part-4").css("background", "white"); 10 $(name + " .part-4").removeClass("change"); 11 $(name + " .part-5").css("background", "white"); 12 $(name + " .part-5").removeClass("change"); 13 $(name + " .part-6").css("background", "white"); 14 $(name + " .part-6").removeClass("change"); 15 $(name + " .part-7").css("background", "white"); 16 $(name + " .part-7").removeClass("change"); 17 // show digit 18 if (num === 1) { 19 $(name + " .part-1").css("background", "black"); 20 $(name + " .part-1").addClass("change"); 21 $(name + " .part-2").css("background", "black"); 22 $(name + " .part-2").addClass("change"); 23 $(name + " .part-3").css("background", "black"); 24 $(name + " .part-3").addClass("change"); 25 $(name + " .part-6").css("background", "black"); 26 $(name + " .part-6").addClass("change"); 27 $(name + " .part-7").css("background", "black"); 28 $(name + " .part-7").addClass("change"); 29 } 30 if (num === 2) { 31 $(name + " .part-5").css("background", "black"); 32 $(name + " .part-5").addClass("change"); 33 $(name + " .part-6").css("background", "black"); 34 $(name + " .part-6").addClass("change"); 35 } 36 if (num === 3) { 37 $(name + " .part-6").css("background", "black"); 38 $(name + " .part-6").addClass("change"); 39 $(name + " .part-7").css("background", "black"); 40 $(name + " .part-7").addClass("change"); 41 } 42 if (num === 4) { 43 $(name + " .part-1").css("background", "black"); 44 $(name + " .part-1").addClass("change"); 45 $(name + " .part-3").css("background", "black"); 46 $(name + " .part-3").addClass("change"); 47 $(name + " .part-7").css("background", "black"); 48 $(name + " .part-7").addClass("change"); 49 } 50 if (num === 5) { 51 $(name + " .part-4").css("background", "black"); 52 $(name + " .part-4").addClass("change"); 53 $(name + " .part-7").css("background", "black"); 54 $(name + " .part-7").addClass("change"); 55 } 56 if (num === 6) { 57 $(name + " .part-4").css("background", "black"); 58 $(name + " .part-4").addClass("change"); 59 } 60 if (num === 7) { 61 $(name + " .part-2").css("background", "black"); 62 $(name + " .part-2").addClass("change"); 63 $(name + " .part-3").css("background", "black"); 64 $(name + " .part-3").addClass("change"); 65 $(name + " .part-6").css("background", "black"); 66 $(name + " .part-6").addClass("change"); 67 $(name + " .part-7").css("background", "black"); 68 $(name + " .part-7").addClass("change"); 69 } 70 if (num === 9) { 71 $(name + " .part-7").css("background", "black"); 72 $(name + " .part-7").addClass("change"); 73 } 74 if (num === 0) { 75 $(name + " .part-2").css("background", "black"); 76 $(name + " .part-2").addClass("change"); 77 } 78 }
完整代码已上传到 GitHub!