JavaScript仿IOS Clock
參考
描述
用JavaScript模仿IOS上Clock時鐘
效果
項目分析
- 時鐘,首先得獲取本地時間
- 時鐘有3個指針敛腌,通過添加動畫的方式讓它圍繞中心點旋轉
- 通過獲取到的hour/minute/second值分別計算時針/分針/秒針的角度值
HTML & CSS
布局
<div class="box">
<article class="clock">
<div class="hours-container">
<div class="hours"></div>
</div>
<div class="minutes-container">
<div class="minutes"></div>
</div>
<div class="seconds-container">
<div class="seconds"></div>
</div>
</article>
</div>
- .box是為了布局的方便
- 每個指針都需要一個*.container容器
添加背景樣式
html {
/* font-size必須大于等于12刨晴,否則不生效*/
font-size: 12px;
}
html, body {
margin: 0px;
padding: 0px;
}
.box {
width: 35rem;
height: 38rem;
background: rgb(205, 205, 205);
border-radius: 1rem;
margin: 5% auto;
display: flex;
justify-content: center;
align-items: center;
}
.clock {
width: 30rem;
height: 30rem;
background: #fff url('./images/ios_clock.svg') no-repeat center;
background-size: 88%;
border-radius: 50%;
position: relative;
}
- 設置.box的width和height铆遭,建議用rem單位,這樣手機上效果也很好
- .box采用Flex布局沿猜,并且.clock在水平和垂直方向上都居中枚荣,具體Flex布局后面章再介紹
- Clock的背景使用了一張圖片,具體見最后的項目地址
添加中心軸
.clock:after {
/* content是必須的啼肩,不然偽元素不會顯示 */
content: '';
width: 1.5rem;
height: 1.5rem;
background: #000;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
/* 向坐上移動自身的50% */
transform: translate(-50%, -50%);
z-index: 10;
}
- 使用CSS3中的偽元素為時鐘添加實心小圓點橄妆,指針都圍繞這個點轉
- content: '';是必須的,不然偽元素無法顯示
- 相對定位祈坠,top: 50%; left: 50%; 無法是小圓點在正中心害碾,使用transform: translate(-50%, -50%)向左上方移動自身寬高的一半
- z-index: 10;為了使小圓點在視圖的最上層,遮擋指針交叉的地方
指針容器
.hours-container, .minutes-container, .seconds-container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
- 添加指針容器后赦拘,暫時并無效果
- 指針的轉動慌随,實際是通過動態(tài)調整指針容器的角度實現(xiàn)的
- 添加指針容器后,可以添加指針的樣式了
添加指針
.hours {
width: 3%;
height: 20%;
background: #000;
position: absolute;
top: 30%;
left: 48.5%;
}
.minutes {
width: 2%;
height: 37%;
background: #000;
position: absolute;
top: 13%;
left: 49%;
}
.seconds {
width: 1%;
height: 40%;
background: #f00;
position: absolute;
top: 20%;
left: 49.5%;
z-index: 8;
}
- 分別添加時針躺同、分針阁猜、秒針
- 時針較粗,分針次之笋籽,秒針最細蹦漠,采用3%、2%车海、1%遞減笛园,可以自己調整
- %是相對于各自的*.container容器元素的
- 時針top: 30%; height: 20%; 兩者相加正好為50%,即下邊緣與中心軸重合侍芝,分針同理
- 時針width: 3%; left: 48.5%; width/2 + left == 50%研铆,分針、秒針同理
- 秒針top: 20%; height: 40%; top + height == 60%州叠,秒針下邊緣超過中心軸棵红,超出10%
動畫
定義動畫規(guī)則
@keyframes rotate {
100% {
transform: rotateZ(360deg);
}
}
采用@keyframes規(guī)則定義一個動畫,動畫名稱為rotate咧栗,這個動畫的元素會沿著Z軸旋轉360°
定時器
.hours-container {
animation: rotate 36s infinite linear;
}
.minutes-container {
animation: rotate 18s infinite steps(60);
}
.seconds-container {
animation: rotate 3s infinite steps(60);
}
- 為了演示的方便逆甜,固定的事件并未按真實的時間來設置虱肄。時針是12小時(43200秒)、分針是60分鐘(3600秒)交煞,秒針是60秒咏窿。
- 為了有咔嚓咔嚓的跳動,秒針素征、分針采用steps(60)集嵌,每步60°
- 由于CSS的時間是有一定誤差的,所以不能直接采用1. 中的值
- 請刪除或注釋定義動畫規(guī)則和定時器中的CSS代碼
時鐘
獲取本地時間御毅,并計算每個指針應該旋轉的角度根欧,并設置
獲取每個指針
const hourHand = document.querySelector('.hours-container');
const minuteHand = document.querySelector('.minutes-container');
const secondHand = document.querySelector('.seconds-container');
實際獲取的是指針的容器
獲取本地時間
const now = new Date();
const hour = now.getHours();
const minute = now.getMinutes();
const second = now.getSeconds();
計算指針角度
在CSS3中角度單位一共有4種:
- deg (度,一個圓360度)
- grad (梯度端蛆,一個圓400梯度)
- turn (轉/圈凤粗,一個圓1圈)
- rad (弧度,一個圓2π弧度)
const secondDegree = second * 6;
const minuteDegree = minute * 6;
const hourDegree = (hour * 30) + (minute / 2);
- 秒針一圈是360°欺税,60秒侈沪,每秒360 / 60 = 6°,所以秒針角度為second * 6
- 分針一圈是360°晚凿,60分鐘亭罪,每分鐘360 / 60 = 6°,所以分針角度為minute * 6
- 時針一圈是360°歼秽,12小時应役,每小時360 / 12 = 30°,又由于分針轉動時燥筷,時針也會產生微小的移動箩祥,minute * 30° / 60分鐘 = minute / 2,所以時針角度為(hour * 30) + (minute / 2)
設置角度值
hourHand.style.transform = `rotateZ(${hourDegree}deg)`;
minuteHand.style.transform = `rotateZ(${minuteDegree}deg)`;
secondHand.style.transform = `rotateZ(${secondDegree}deg)`;
以上可以根據(jù)本地時間設置時鐘角度肆氓,但想要時鐘實時轉動袍祖,則需要增加setInterval
定時更新
<script>
function clockWalk() {
const hourHand = document.querySelector('.hours-container');
const minuteHand = document.querySelector('.minutes-container');
const secondHand = document.querySelector('.seconds-container');
const now = new Date();
const hour = now.getHours();
const minute = now.getMinutes();
const second = now.getSeconds();
const secondDegree = second * 6;
const minuteDegree = minute * 6;
const hourDegree = (hour * 30) + (minute / 2);
hourHand.style.transform = `rotateZ(${hourDegree}deg)`;
minuteHand.style.transform = `rotateZ(${minuteDegree}deg)`;
secondHand.style.transform = `rotateZ(${secondDegree}deg)`;
}
setInterval(function() {
clockWalk();
}, 1000);
</script>
通過以上動態(tài)圖可知,指針轉動實際是通過轉動*.container對應的div來實現(xiàn)的
這樣谢揪,整個時鐘就完成了
項目地址:碼云/c02954/ios_clock