使用JavaScript實現(xiàn)一個炫酷的羅盤時鐘
前言
在探究前端動畫時。想到之前在鎖屏壁紙看到的羅盤時鐘,看著很是炫酷,于是說干就干,一起來研究下怎么用簡單的方法實現(xiàn)這個炫酷的效果。 需要源碼的小伙伴可到文章結(jié)尾直接復(fù)制使用。
先上效果圖:

實現(xiàn)思路
(1)首先我們需要定義一系列的月、日、時、分、秒的數(shù)組,用來展示羅盤不同圓環(huán)上的數(shù)字
var monthText = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]; var dayText = ["一日", "二日", "三日", "四日", "五日", "六日", "七日", "八日", "九日", "十日", "十一日", "十二日", "十三日", "十四日", "十五日", "十六日" , "十七日", "十八日", "十九日", "二十日", "二十一日", "二十二日", "二十三日", "二十四日", "二十五日", "二十六日", "二十七日", "二十八日", "二十九日", "三十日", "三十一日"]; var weekText = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]; var hourText = ["零時", "一時", "二時", "三時", "四時", "五時", "六時", "七時", "八時", "九時", "十時", "十一時", "十二時", "十三時", "十四時", "十五時", "十六時", "十七時", "十八時", "十九時", "二十時", "二十一時", "二十二時", "二十三時"]; ....
(2)通過循遍歷使用將這些數(shù)據(jù)生成dom節(jié)點放到html中
(3)通過setInterval循環(huán)運行,實時計算改變時分秒位置
開始實現(xiàn)
(1)定義基礎(chǔ)dom結(jié)構(gòu)
<body>
<div id="clock"></div>
</body>
(2)循環(huán)遍歷已定義的月、日、時、分、秒數(shù)組,通過document.createElement在clock下創(chuàng)建節(jié)點,并將創(chuàng)建的節(jié)點保存到textSet中,方便后面直接修改該dom的樣式。
//循環(huán)遍歷初始化數(shù)據(jù)
function init() {
clock = document.getElementById('clock');
for (var i = 0; i < textSet.length; i++) {
for (var j = 0; j < textSet[i][0].length; j++) {
var temp = createLabel(textSet[i][0][j]);
clock.appendChild(temp);
textSet[i][1].push(temp);
}
}
clock.style.transform = "rotate(90deg)";
}
//創(chuàng)建子節(jié)點
function createLabel(text) {
var div = document.createElement('div');
div.classList.add('label');
div.innerText = text;
return div;
}(3)計算每一層每一個節(jié)點的位置,首先獲取當(dāng)前時間,為了保證當(dāng)前時間始終處于平行位置,所以需要計算其他值相對于當(dāng)前位置的偏移角度,以及他們相對的X、Y的位置。計算每一層圓半徑的長度,通過Math.sin和Math.cos,以及獲取頁面寬和高定位到圓中心點就能得到每一個點的絕對位置。具體可以查看下面代碼解析。
function runTime() {
//獲取當(dāng)前時間
var now = new Date();
var month = now.getMonth();
var day = now.getDate();
var week = now.getDay();
var hour = now.getHours();
var minute = now.getMinutes();
var seconds = now.getSeconds();
var nowValue = [month, day - 1, week, hour, minute, seconds];
initStyle();
//當(dāng)前年月日時高亮
for (var i = 0; i < nowValue.length; i++) {
var num = nowValue[i];
textSet[i][1][num].style.color = '#fff';
}
//計算圓中心位置
var widthMid = document.body.clientWidth / 2;
var heightMid = document.body.clientHeight / 2;
for (var i = 0; i < textSet.length; i++) {
for (var j = 0; j < textSet[i][0].length; j++) {
//計算每一層的圓半徑
var r = (i + 1) * 35 + 50 * i;
//計算旋轉(zhuǎn)角度
var deg = 360 / textSet[i][1].length * (j - nowValue[i]);
//計算絕對位置
var x = r * Math.sin(deg * Math.PI / 180) + widthMid;
var y = heightMid - r * Math.cos(deg * Math.PI / 180);
//改變每一個節(jié)點的位置
var temp = textSet[i][1][j];
temp.style.transform = 'rotate(' + (-90 + deg) + 'deg)';
temp.style.left = x + 'px';
temp.style.top = y + 'px';
}
}
}
//還原所有的默認(rèn)樣式
function initStyle() {
var label = document.getElementsByClassName('label');
for (var i = 0; i < label.length; i++) {
label[i].style.color = '#4d4d4d';
}
}
(4)定義每一個節(jié)點的基本樣式,為了實現(xiàn)時間變化時有旋轉(zhuǎn)效果,增加transition: left 1s, top 1s;的過度動畫
.label {
position: absolute;
display: inline-block;
color: #4d4d4d;
text-align: center;
padding: 0 5px;
font-family: "Microsoft YaHei";
font-size: 19px;
font-weight: bolder;
transition: left 1s, top 1s;
transform-origin: 0% 0%
}
完整代碼
附上全部代碼,有需要的小伙伴可直接復(fù)制使用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>羅盤時鐘</title>
<style type="text/css">
* {
margin: 0;
padding: 0
}
html,
body {
width: 100%;
height: 100%;
background-color: black;
overflow: hidden
}
#clock {
position: relative;
width: 100%;
height: 100%;
background: black
}
.label {
position: absolute;
display: inline-block;
color: #4d4d4d;
text-align: center;
padding: 0 5px;
font-family: "Microsoft YaHei";
font-size: 19px;
font-weight: bolder;
transition: left 1s, top 1s;
transform-origin: 0% 0%
}
</style>
<script type="text/javascript">
var monthText = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
var dayText = ["一日", "二日", "三日", "四日", "五日", "六日", "七日", "八日", "九日", "十日", "十一日", "十二日", "十三日", "十四日", "十五日", "十六日"
, "十七日", "十八日", "十九日", "二十日", "二十一日", "二十二日", "二十三日", "二十四日", "二十五日", "二十六日", "二十七日", "二十八日", "二十九日", "三十日", "三十一日"];
var weekText = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
var hourText = ["零時", "一時", "二時", "三時", "四時", "五時", "六時", "七時", "八時",
"九時", "十時", "十一時", "十二時", "十三時", "十四時", "十五時", "十六時", "十七時", "十八時", "十九時", "二十時", "二十一時", "二十二時", "二十三時"];
var minuteText = ["零分", "一分", "二分", "三分", "四分", "五分", "六分", "七分", "八分", "九分", "十分", "十一分", "十二分", "十三分", "十四分", "十五分", "十六分", "十七分", "十八分",
"十九分", "二十分", "二十一分", "二十二分", "二十三分", "二十四分", "二十五分", "二十六分", "二十七分", "二十八分", "二十九分", "三十分", "三十一分", "三十二分", "三十三分",
"三十四分", "三十五分", "三十六分", "三十七分", "三十八分", "三十九分", "四十分", "四十一分", "四十二分", "四十三分", "四十四分", "四十五分", "四十六分", "四十七分",
"四十八分", "四十九分", "五十分", "五十一分", "五十二分", "五十三分", "五十四分", "五十五分", "五十六分", "五十七分", "五十八分", "五十九分"];
var secondsText = ["零秒", "一秒", "二秒", "三秒", "四秒", "五秒", "六秒", "七秒", "八秒", "九秒", "十秒", "十一秒", "十二秒", "十三秒", "十四秒", "十五秒", "十六秒",
"十七秒", "十八秒", "十九秒", "二十秒", "二十一秒", "二十二秒", "二十三秒", "二十四秒", "二十五秒", "二十六秒", "二十七秒", "二十八秒", "二十九秒", "三十秒", "三十一秒",
"三十二秒", "三十三秒", "三十四秒", "三十五秒", "三十六秒", "三十七秒", "三十八秒", "三十九秒", "四十秒", "四十一秒", "四十二秒", "四十三秒", "四十四秒", "四十五秒",
"四十六秒", "四十七秒", "四十八秒", "四十九秒", "五十秒", "五十一秒", "五十二秒", "五十三秒", "五十四秒", "五十五秒", "五十六秒", "五十七秒", "五十八秒", "五十九秒"];
var clock;
var monthList = [];
var dayList = [];
var weekList = [];
var hourList = [];
var minuteList = [];
var secondsList = [];
var textSet = [[monthText, monthList], [dayText, dayList], [weekText, weekList], [hourText, hourList], [minuteText, minuteList], [secondsText, secondsList]];
var labelX = [];
var labelY = [];
window.onload = function () {
init();
setInterval(function () { runTime(); }, 500);
}
function init() {
clock = document.getElementById('clock');
for (var i = 0; i < textSet.length; i++) {
for (var j = 0; j < textSet[i][0].length; j++) {
var temp = createLabel(textSet[i][0][j]);
clock.appendChild(temp);
textSet[i][1].push(temp);
}
}
console.log(textSet)
clock.style.transform = "rotate(90deg)";
}
function createLabel(text) {
var div = document.createElement('div');
div.classList.add('label');
div.innerText = text;
return div;
}
function runTime() {
var now = new Date();
var month = now.getMonth();
var day = now.getDate();
var week = now.getDay();
var hour = now.getHours();
var minute = now.getMinutes();
var seconds = now.getSeconds();
var nowValue = [month, day - 1, week, hour, minute, seconds];
initStyle();
//當(dāng)前年月日時高亮
for (var i = 0; i < nowValue.length; i++) {
var num = nowValue[i];
textSet[i][1][num].style.color = '#fff';
}
var widthMid = document.body.clientWidth / 2;
var heightMid = document.body.clientHeight / 2;
for (var i = 0; i < textSet.length; i++) {
for (var j = 0; j < textSet[i][0].length; j++) {
var r = (i + 1) * 35 + 50 * i;
var deg = 360 / textSet[i][1].length * (j - nowValue[i]);
var x = r * Math.sin(deg * Math.PI / 180) + widthMid;
var y = heightMid - r * Math.cos(deg * Math.PI / 180);
var temp = textSet[i][1][j];
temp.style.transform = 'rotate(' + (-90 + deg) + 'deg)';
temp.style.left = x + 'px';
temp.style.top = y + 'px';
}
}
}
function initStyle() {
var label = document.getElementsByClassName('label');
for (var i = 0; i < label.length; i++) {
label[i].style.color = '#4d4d4d';
}
}
</script>
<title> </title>
</head>
<body>
<div id="clock"></div>
</body>
</html>
總結(jié)
通過上面一頓操作,短短幾行代碼實現(xiàn)了這個炫酷的方法,在涉及定位每個節(jié)點位置的時候,不得不再去復(fù)習(xí)下初中數(shù)學(xué)知識sin和cos的用法
到此這篇關(guān)于使用JavaScript實現(xiàn)一個炫酷的羅盤時鐘的文章就介紹到這了,更多相關(guān)JavaScript羅盤時鐘內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js的隱含參數(shù)(arguments,callee,caller)使用方法
本篇文章只要是對js的隱含參數(shù)(arguments,callee,caller)使用方法進行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助2014-01-01
javaScript 刪除確認(rèn)實現(xiàn)方法小結(jié)
因為對于內(nèi)容的刪除是件很重要的事,所以一般的系統(tǒng)中,都需要刪除確認(rèn)一下,以免誤刪,具體的方法如下,大家可以參考下。2009-12-12
利用JavaScript實現(xiàn)靜態(tài)圖片局部流動效果
如果你有玩過《王者榮耀》、《陰陽師》?等手游,一定注意到過它的啟動動畫、皮膚立繪卡片等場景,經(jīng)常采用靜態(tài)底圖加局部液態(tài)流動效果的簡單動畫,本文將利用JavaScript實現(xiàn)這一效果,需要的可以參考一下2022-08-08
JS寫的數(shù)字拼圖小游戲代碼[學(xué)習(xí)參考]
昨天沒事做,就用JS寫了個數(shù)字拼圖的小游戲,自娛自樂。 可惜關(guān)于逆序數(shù)的問題還沒解決,現(xiàn)在有時是拼不成的,大家見諒了。2008-10-10

