获取中...

-

Just a minute...

罗盘时钟

不刷抖音但是最近也听说了有很火的罗盘时钟,
废话不多说直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
const $$ = function (select) {
return document.querySelectorAll(select);
}
const numToChinese = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '二十一', '二十二', '二十三', '二十四', '二十五', '二十六', '二十七', '二十八', '二十九', '三十', '三十一'];
let timer = null;
const monthLength = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
let currentYear = new Date().getFullYear()
if (currentYear % 4 === 0 && currentYear % 400 !== 0) {
monthLength[1] = 29;
}
const currentMonthLength = monthLength[new Date().getMonth()]

function start() {
const tableList = ['month', 'day', 'week', 'hour', 'min', 'seconds'];


const [monthDom, dayDom, weekDom, hourDom, minDom, secondsDom] = tableList.map(className => $$(`#app .${className}`)[0]);

const setTransform = (dom, rate) => {
dom.style.transform = `rotateZ(${-rate}deg)`
};
const setActive = (dom, currentIndex) => {
//如果有兄弟节点高亮的,先移除
const domList = dom.querySelectorAll('.active');
if (domList.length > 0) {
dom.querySelector('.active').classList.remove('active')
}
const allNode = dom.querySelectorAll('li');
const currentLi = currentIndex - 1 < 0 ? allNode[allNode.length] : allNode[currentIndex - 1];
currentLi.classList.add('active');
}

const taskObj = {
setMonthRate(currentDate) {
const currentIndex = currentDate.getMonth() + 1; //0-11 so +1
const rate = currentIndex * 30 - 90;

setActive(monthDom, currentIndex)
setTransform(monthDom, rate)
},
setWeekRate(currentDate) {
const currentIndex = currentDate.getDay(); // 0-6
const rate = (currentIndex - 1) * 360 / 7;//周日算0,所以前移一位

setActive(weekDom, currentIndex)
setTransform(weekDom, rate)
},
setDayRate(currentDate) {
const currentIndex = currentDate.getDate() + 1; //1-31
const rate = currentIndex * parseInt(360 / currentMonthLength) - 90;

setActive(dayDom, currentIndex - 1)
setTransform(dayDom, rate)
},
setHourRate(currentDate) {
const currentIndex = currentDate.getHours();
const rate = currentIndex * 15 - 90;

setActive(hourDom, currentIndex)
setTransform(hourDom, rate)
},
setMinRate(currentDate) {
const currentIndex = currentDate.getMinutes();
const rate = currentIndex * 6 - 90;

setActive(minDom, currentIndex)
setTransform(minDom, rate)

},
setSecondsRate(currentDate) {
const currentIndex = currentDate.getSeconds();//0-59
const rate = currentIndex * 6 - 90;

setActive(secondsDom, currentIndex)
setTransform(secondsDom, rate);
}

}

timer = setInterval(() => {
const currentDate = new Date();
Object.values(taskObj).forEach(fun => fun(currentDate))
}, 500)
}

function end() {
clearInterval(timer)
}
function createTable(config = {}) {
const data = { radius: 200, num: 12, unit: '', className: '' };
config = Object.assign(data, config)
const offset = parseInt(- config.num / 4);//往回转的刻度数,不然水平右边的是1,应该是3

let i = 1;
let ul = `<ul style="width:${config.radius * 2}px;height:${config.radius * 2}px" class="scale ${config.className}">`;
while (i <= config.num) {
let rate = 360 / config.num * (i + offset);
ul += `<li style="transform:rotateZ(${rate}deg);left:${config.radius / 2}px;top:${config.radius - 10}px;width:${config.radius}px"><span>${config.showChinese ? numToChinese[i - 1] : i}${config.unit}</span></li>`;
i++
}
ul += '</ul>';
return ul;
}
function createHr(data = {}) {
const { radius = 800, left = 170 } = data;
const year = new Date().getFullYear()
const html = `<div id="hr" style="width:${radius / 2}px;left:${radius / 4}px">
<span>${year}年</span>
<span style="position:absolute;left:${left}px">星期</span>
</div>`;
return html;
}
function init() {
const clientMin = Math.min(document.body.clientHeight, document.body.clientWidth);
const clientMinRate = clientMin / 1297;

let list = [
{ radius: 250, num: 12, unit: '月', className: 'month', showChinese: true },
{ radius: 450, num: 31, unit: '日', className: 'day', showChinese: true },
{ radius: 600, num: 7, className: 'week', showChinese: true },
{ radius: 700, num: 24, unit: '时', className: 'hour' },
{ radius: 800, num: 60, unit: '分', className: 'min', },
{ radius: 900, num: 60, unit: '秒', className: 'seconds', }
].map(e => {
e.radius = clientMinRate * e.radius
return e;
});
let tableHTML = list.reduce((total, ele) => {
return total + createTable(ele)
}, '');
const hrLine = createHr({ radius: 900 * clientMinRate, left: clientMinRate * 235 });

$$('#app')[0].innerHTML = tableHTML + hrLine;
start()
}
init()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
* {
margin: 0;
padding: 0;
/* font-size: 18px; */
font-size: 1rem;
}

#app {
position: relative;
width: 1600px;
height: 1600px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
background-color: #000;
color: gray;
}

#hr {
height: 20px;
text-align: left;
position: relative;
vertical-align: baseline;
border-bottom: 1px dashed #fff;
color: #fff;
}

.scale {
position: absolute;
transition: all 1s linear;
}


.scale li {
position: absolute;
left: 100px;
top: 190px;
width: 200px;
height: 20px;
display: inline-block;
text-align: right;
}

.scale li.active {
color: #ffffff;

}

相关文章
评论
分享
  • 微任务宏任务

    微任务队列宏任务队列 javascript是单线程,多线程都是模拟出来的, script、setTimeOut、setInterval是宏任务 Promise,process.nextTick是微任务 setTimeOut是n毫秒之后...

    微任务宏任务
  • 如何判定我点了margin?

    这个世界上唯有两样东西能让我们的心灵感到深深的震撼:一是我们头顶上灿烂的星云,二是我们心中崇高的道德法则。 one - 康德 前言页面的绑定事件都是绑定在DOM元素上的,诸如此类 123document.getElementById(...

    如何判定我点了margin?
  • 花式log

    各种控制台输出常见的控制台打印12345678console.log() // 打印日志console.debug() // 打印调试console.error() // 打印错误console.info() // 打印...

    花式log
  • 只要不失去你的崇高整个世界就会向你敞开

    7 月 29 日周五,临下班之前问了一下领导,下周不会出差吧,这周我要回家领导说:放心回马鞍山吧,不出差,注意疫情防控就行。结果刚到高铁站就打电话来,说是一个很紧急的项目要去桂林出差,赶紧订周日或者周一的飞机票过去年龄越大,就越难有反...

    只要不失去你的崇高整个世界就会向你敞开
  • 端午小记

    端午小记很遗憾 三个月没到就分手了 为什么是她因为刚好是她合适的时间合适的地点相遇再加上一些多巴胺和荷尔蒙的催化下我也想试试,以为这就是不等人的缘分 为什么是我因为刚好是我出现在合适的时间合适的地点在她被不喜欢的人追求时一面挡箭牌出现...

    端午小记
  • 利用微信小程序扫码授权

    微信小程序扫码授权背景想要使用微信扫码登录自己的网址,通过授权快速获取用户的昵称,头像功能由于没有企业认证账号,故只能通过微信小程序实现, 体验地址https://api.nnnnzs.cn/screen-demo.html?env=...

    利用微信小程序扫码授权
  • Math.ceil(25/10)*10 === 30

    终于是到了四舍五入等于 30 的年龄了其实这应该是一篇放在 2022 年 3 月 8 日更新的博客内容应该是来南京工作一年的总结拖到五一假期,整理一下思绪打算发的结果五一又忙着帮别人搬家生日也得过且过,所以拖到了现在 感情发上一篇帖...

    Math.ceil(25/10)*10 === 30
  • 强制加载element-dialog

    强制加载element-dialog背景123<el-dialog> <MyComponent /></el-dialog> 自己封装的组件 MyComponent ,放在了el-dialog里...

    强制加载element-dialog
  • github action部署到vps

    在 ECS 上创建用户,并设置密码 adduser github-action asswd passwd github-action 免密登陆 生成密钥 1ssh-keygen -t rsa -C 'github-act...

    github action部署到vps
  • leancloud-基础存储操作

    对象安装使用1234npm install leancloud-storage --save# debug模式DEBUG=leancloud* node src/leancloud.js 初始化12345678const AV = ...

    leancloud-基础存储操作