JavaScript動態圓形鐘錶效果詳解

admin發表於2018-11-27

分享一段程式碼例項,它利用JavaScript和CSS3實現了動態走動的鐘表效果。

時間是獲取本地客戶端的,下面介紹一下它的實現過程。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
.box{
  width: 300px;
  height: 300px;
  border-radius: 50%;
  border: 5px solid #ccc;
  margin: 100px auto;
  position: relative;
}
.kedu{
  width: 300px;
  height: 300px;
  border-radius: 50%;
  position: relative;
  overflow: hidden;
}
.kedu div{
  height: 300px;
  position: absolute;
  left: 50%;
}
.kedu div:nth-child(1){
  width: 6px;
  background: #333;
  margin-left: -3px;
}
.kedu div:nth-child(2){
  width: 2px;
  background: #666;
  margin-left: -3px;
  transform: rotate(30deg);
}
.kedu div:nth-child(3){
  width: 2px;
  background: #666;
  margin-left: -3px;
  transform: rotate(60deg);
}
.kedu div:nth-child(4){
  width: 6px;
  background: #333;
  margin-left: -3px;
  transform: rotate(90deg);
}
.kedu div:nth-child(5){
  width: 2px;
  background: #666;
  margin-left: -3px;
  transform: rotate(120deg);
}
.kedu div:nth-child(6){
  width: 2px;
  background: #666;
  margin-left: -3px;
  transform: rotate(150deg);
}
.disc{
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #000;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -10px;
  margin-top: -10px;
  z-index: 2;
}
.middisc{
  width: 260px;
  height: 260px;
  border-radius: 50%;
  background: #fff;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -130px;
  margin-top: -130px;
}
.hour{
  width: 6px;
  height: 60px;
  background: #000;
  position: absolute;
  top: -50px;
  left: 50%;
  margin-left: -3px;
  transform-origin: bottom center;
  /*animation: move 43200s steps(60) 0s infinite;*/
}
.minu{
  width: 4px;
  height: 80px;
  background: green;
  position: absolute;
  top: -70px;
  left: 50%;
  margin-left: -2px;
  transform-origin: bottom center;
  /*animation: move 3600s steps(60) 0s infinite;*/
}
.second{
  width: 2px;
  height: 100px;
  background: #f00;
  position: absolute;
  top: -90px;
  left: 50%;
  margin-left: -1px;
  transform-origin: bottom center;
  /*-webkit-animation: move 60s steps(60) infinite;*/
}
.cover{
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #000;
  position: absolute;
}
@keyframes move{
  0%{
    transform: rotate(0deg);
  }
  100%{
    transform: rotate(360deg);
  }
}
</style>
<script>
function $(id){
  return document.getElementById(id);
}
function fnime(){
  var time = new Date();
  var hour = time.getHours();
  var minute = time.getMinutes();
  var second = time.getSeconds();
  if(hour>12){
    hour = hour - 12;
  }
  $("second").style.transform = "rotate("+second*6+"deg)";
  $("minu").style.transform = "rotate("+minute*6+"deg)";
  $("hour").style.transform = "rotate("+(hour+minute/60)*5*6+"deg)";
}
window.onload = function () {
  fnime();
  setInterval(fnime, 1000)
}        
</script>
</head>
<body>
<div class="box">
  <div class="kedu">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
  </div>
  <div class="disc">
    <div class="hour" id="hour"></div>
    <div class="minu" id="minu"></div>
    <div class="second" id="second"></div>
    <div class="cover"></div>
  </div>
  <div class="middisc"></div>
</div>
</body>
</html>

上面的程式碼實現了我們的要求,下面介紹一下它的實現過程。

一.程式碼註釋:

[CSS] 純文字檢視 複製程式碼
.box{
  width: 300px;
  height: 300px;
  border-radius: 50%;
  border: 5px solid #ccc;
  margin: 100px auto;
  position: relative;
}

設定圓形錶盤邊框的樣式,邊框5px就是我們看到的鐘表灰色邊框。

同時設定為相對定位,那麼它定位的子元素就可以用它作為定位參考物件。

[CSS] 純文字檢視 複製程式碼
.kedu{
  width: 300px;
  height: 300px;
  border-radius: 50%;
  position: relative;
  overflow: hidden;
}

這個是設定錶盤的樣式,和上面相比沒有邊框,只有內部空白的部分,用來放置刻度。

[CSS] 純文字檢視 複製程式碼
.kedu div{
  height: 300px;
  position: absolute;
  left: 50%;
}

設定刻度的複用的樣式。

都是絕對定位,left值50%(會和後面margin-left配合使其達到居中效果)。

[CSS] 純文字檢視 複製程式碼
.kedu div:nth-child(1){
  width: 6px;
  background: #333;
  margin-left: -3px;
}

設定垂直刻度,也就是12點和6點的刻度。

width值是6px,然後設定margin-left為-3px,那麼就可以將其實現居中了。

[CSS] 純文字檢視 複製程式碼
.disc{
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #000;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -10px;
  margin-top: -10px;
  z-index: 2;
}

設定鐘錶中心黑色小圓形部分的樣式。

[CSS] 純文字檢視 複製程式碼
.middisc{
  width: 260px;
  height: 260px;
  border-radius: 50%;
  background: #fff;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -130px;
  margin-top: -130px;
}

在上面我們說過.kedu的div是用來放置刻度的,並且每一個刻度都是貫穿的,為什麼只會看到兩端的一小段刻度呢。就是因為通過這個圓形div的遮擋來實現的。

[CSS] 純文字檢視 複製程式碼
.hour{
  width: 6px;
  height: 60px;
  background: #000;
  position: absolute;
  top: -50px;
  left: 50%;
  margin-left: -3px;
  transform-origin: bottom center;
}

設定小時指標的樣式。

[JavaScript] 純文字檢視 複製程式碼
function $(id){
  return document.getElementById(id);
}

模擬jQuery的id選擇器,可以獲取對應id屬性值的元素物件。

[JavaScript] 純文字檢視 複製程式碼
function fnime(){
  // code
}

此函式實現了鐘錶時間變化效果。

[JavaScript] 純文字檢視 複製程式碼
var time = new Date();

建立時間日期物件。

[JavaScript] 純文字檢視 複製程式碼
var hour = time.getHours();
var minute = time.getMinutes();
var second = time.getSeconds();

獲取當前時間點的小時、分鐘和秒。

[JavaScript] 純文字檢視 複製程式碼
if(hour>12){
    hour = hour - 12;
  }

當小時大於12的時候,就減去12,比如hour為13的時候,減去12就成為1,也就是一點鐘。

[JavaScript] 純文字檢視 複製程式碼
$("second").style.transform = "rotate("+second*6+"deg)";

每走一秒跳動6度,也就是走完一圈(一分鐘)需要跳動60下(一週360度)。

[JavaScript] 純文字檢視 複製程式碼
$("minu").style.transform = "rotate("+minute*6+"deg)";

和秒錶的走動是同樣的道理,當然秒錶需要走動60次,它才走動一次。

[JavaScript] 純文字檢視 複製程式碼
$("hour").style.transform = "rotate("+(hour+minute/60)*5*6+"deg)";

原理和上面是一樣的,minute/60,每走60分鐘,就增加1小時。

之所以5*6,因為小時與小時之間間隔30度,5等分間隔。

[JavaScript] 純文字檢視 複製程式碼
window.onload = function () {
  fnime();
  setInterval(fnime, 1000)
}

文件內容完全載入完畢,執行fnime函式(防止一秒延遲)。

然後再使用定時器函式,每隔1秒執行一次fnime函式。

二.相關閱讀:

(1).border-radius參閱CSS3 border-radius一章節。

(2).:nth-child()參閱CSS E:nth-child(n)一章節。

(3).transform參閱CSS3 transform一章節。

(4).transform-origin參閱css3 transform-origin一章節。

(5).@keyframes參閱CSS3 @keyframes一章節。

(6).setInterval()參閱window.setInterval()一章節。

相關文章