罗盘时钟

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

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;

}

相关文章
评论
分享
  • 如何判定我点了margin?

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

    如何判定我点了margin?
  • 自动微信读书

    前言最近在学习ReactNative,真机调试的时候安装的ADB调试工具,突发奇想,既然PC可以操控手机,是不是可以做一些懒得做的事情 流程 通过USB链接真机调试 执行wifi调试 123adb tcpip 5555adb co...

    自动微信读书
  • docker-Dockerfile篇

    什么是DockerfileDockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明,相当于快速构建时候的脚本文件 获取images 首先明确需要获取的image版本,以目前LTS的nodejs版...

    docker-Dockerfile篇
  • Docker-安装篇

    what is DockerDocker 是一个开源的应用容器引擎换句话说就是运行的系统里的虚拟机,可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。优点是容...

    Docker-安装篇
  • 初探electron

    什么是 electron使用html、css、javascipt、nodejs来编写跨平台的客户端程序,可以使windows、linux、macos 优点一次代码编写,多端打包 起步

    初探electron
  • 粘贴图片上传功能

    粘贴图片并上传最近在写博客的时候,纯MarkDown语法写,但是发现图片是个需求,需要经常截图并且写到MarkDown里面之前的做法是用QQ截图,然后另存为到本地桌面,然后再上传,返回URI地址,贴到博客编辑器里面最近发现有些页面支持...

    粘贴图片上传功能
  • 记一次sql性能优化

    有个小需求,在表里根据页码和页数查询,并排序,很简单,3秒就写出的sql 1select * from newslist order by id desc limit ${(currPage - 1) * pageSize&...

    记一次sql性能优化
  • 花式log

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

    花式log
  • 记一次js页面跳转

    碰到一个需求,软件站的某个页面想要用js做404跳转,但是不想删除cms后台的软件,还想做SEO,不然降低SEO权重要求是从搜索引擎来的,页面源码还是原来的,但是展示404直接访问地址URL,跳转真实的404页面 根据页面标题,包含违...

    记一次js页面跳转
  • 旋转时钟

    实现原生的时钟 #warp{ --scale-radius:300px; background:red; width:calc(var(--scale-radius) *2); ...

    旋转时钟