1 前言
用css和js实现一个时钟,再加上切换时区。
2 制作思路
- 画表盘
- 添加时针,分针,秒针
- 设置指针
- 设置时区
3 代码实现
画表盘
先实现一个表盘的表框,
#title {
width: 200px;
font-size: 30px;
text-align: center;
color: aquamarine;
margin: 100px auto 10px;
}
#box {
width: 200px;
height: 200px;
position: relative;
border-radius: 50%;
border: 5px solid black;
margin: 0 auto;
}
#scale {
width: 200px;
height: 200px;
position: absolute;
}
#scale div {
width: 20px;
height: 200px;
position: absolute;
left: 92px;
}
再把数字添加到表盘中
<div id="scale">
<div><span>12</span></div>
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
<div><span>6</span></div>
<div><span>7</span></div>
<div><span>8</span></div>
<div><span>9</span></div>
<div><span>10</span></div>
<div><span>11</span></div>
</div>
现在的效果是有一个黑色圆框,数字都叠在了一起。如图:
用css一个一个改变位置太麻烦了,可以用js获取所有节点,遍历改变角度,如图:
for (let i = 0; i < scaleDivs.length; i++) {
//表盘一圈360度,总共有12个刻度,每个刻度之间是360/12=30度
scaleDivs[i].style.transform = "rotate(" + i * 30 + "deg)";
}
但是刻度值有正反向问题,里面的span在反转回去,如图
//解决刻度值显示正向问题,反向转回去就可以了
scaleDivs[i].firstChild.style.transform = "rotate(" + -i * 30 + "deg)";
添加时针,分针,秒针
添加表针这个属性可以记一下transform-origin
,这个属性可以改变中心点,因为指针是有一个中心点,我们把指针的中心点设置在底部中间的位置。
#hour {
width: 4px;
height: 50px;
position: absolute;
background-color: red;
left: 97px;
top: 50px;
/*这个属性可以改变旋转的中心点*/
transform-origin: bottom center;
}
#minute {
width: 4px;
height: 70px;
position: absolute;
background-color: cyan;
left: 97px;
top: 30px;
/*这个属性可以改变旋转的中心点*/
transform-origin: bottom center;
}
#second {
width: 4px;
height: 90px;
position: absolute;
background-color: pink;
left: 97px;
top: 10px;
/*这个属性可以改变旋转的中心点*/
transform-origin: bottom center;
}
<div id="hour"></div>
<div id="minute"></div>
<div id="second"></div>
效果如图:
设置指针
- 秒针:一圈360度,一圈60秒,每秒是360/60=6度
- 分针:一圈360度,一圈60分,每分是360/60=6度
- 时针:一圈360度,一圈12小时,每秒是360/12=30度
按照上面的想法,在给个定时器是不是就动起来
//获取时分秒针DIV
var hourDiv = document.querySelector("#hour");
var minuteDiv = document.querySelector("#minute");
var secondDiv = document.querySelector("#second");
//获取时分秒
var date = new Date();
//把小时转换成12进制,方便运算
var hour = date.getHours() % 12;
var minute = date.getMinutes();
var second = date.getSeconds();
//设置指针
function setPointers() {
second++;
if (second == 60) {
second = 0;
minute++;
if (minute == 60) {
minute = 0;
hour++;
if (hour == 13) {
hour = 0;
}
}
}
//一圈360度,一圈60秒,每秒是360/60=6度
secondDiv.style.transform = "rotate(" + second * 6 + "deg)";
//一圈360度,一圈60分,每分是360/60=6度
minuteDiv.style.transform = "rotate(" + minute * 6 + "deg)";
//一圈360度,一圈12小时,每秒是360/12=30度
//一小时是30度,一小时是60分钟,一分钟是30/60=0.5度
hourDiv.style.transform = "rotate(" + (hour * 30 + minute * 0.5) + "deg)";
}
setPointers();
//创建定时器
setInterval(function () {
setPointers();
},1000);
效果如图:
这里我为了指针和刻度能够对齐,给1位数字的刻度加了点样式,以12数字的宽度为基础,然后居中
#box div:nth-of-type(2) span,
#box div:nth-of-type(3) span,
#box div:nth-of-type(4) span,
#box div:nth-of-type(5) span,
#box div:nth-of-type(6) span,
#box div:nth-of-type(7) span,
#box div:nth-of-type(8) span,
#box div:nth-of-type(9) span,
#box div:nth-of-type(10) span{
width: 20px;
text-align: center;
}
设置时区
世界这么多的时区,得有一个标准,就是GMT,格林尼治时间
百度百科:世界时UT [1] 即格林尼治 [1] 平太阳时间,是指格林尼治所在地的标准时间,也是表示地球自转速率的一种形式。
添加select,选择时区
<div id="select_box">
<label>
<select onchange="onChangeTimeFunc(value)">
<!--东区时间-->
<option value="0">零时区</option>
<option value="1">东一区</option>
<option value="2">东二区</option>
<option value="3">东三区</option>
<option value="4">东四区</option>
<option value="5">东五区</option>
<option value="6">东六区</option>
<option value="7">东七区</option>
<option value="8" selected="selected">东八区</option>
<option value="9">东九区</option>
<option value="10">东十区</option>
<option value="12">东十二区</option>
<!--西区时间-->
<option value="-10">西十区</option>
<option value="-9">西九区</option>
<option value="-8">西八区</option>
<option value="-7">西七区</option>
<option value="-6">西六区</option>
<option value="-5">西五区</option>
<option value="-4">西四区</option>
<option value="-3">西三区</option>
</select>
</label>
</div>
选择时区处理函数
// 选择时区的时间
function onChangeTimeFunc(value) {
clearInterval(timer);
// 获取当前时区时间
const date = getLocalTime(Number(value));
// 设置指针
setPointers(date);
// 启动定时器
timer = setInterval(function () {
// 每次获取当前时区时间
const currentDate = getLocalTime(Number(value));
setPointers(currentDate);
}, 1000);
}
获取选择的时区的当前时间
//得到标准时区的时间的函数
function getLocalTime(i) {
//参数i为时区值数字,比如北京为东八区则输进8,西八区则输入-8
const d = new Date();
//得到1970年一月一日到现在的秒数
const len = d.getTime();
//本地时间与GMT时间的时间偏移差
const offset = d.getTimezoneOffset() * 60000;
//得到现在的格林尼治时间
const utcTime = len + offset;
return new Date(utcTime + 3600000 * i);
}
需要再把之前写的setPointers
方法重新封装一下,时间就不能用当前时间,要用传入的参数
//设置指针
function setPointers(date) {
//把小时转换成12进制,方便运算
let hour = date.getHours() % 12;
let minute = date.getMinutes();
let second = date.getSeconds();
second++;
if (second === 60) {
second = 0;
minute++;
if (minute === 60) {
minute = 0;
hour++;
if (hour === 13) {
hour = 0;
}
}
}
//一圈360度,一圈60秒,每秒是360/60=6度
secondDiv.style.transform = "rotate(" + second * 6 + "deg)";
//一圈360度,一圈60分,每分是360/60=6度
minuteDiv.style.transform = "rotate(" + minute * 6 + "deg)";
//一圈360度,一圈12小时,每秒是360/12=30度
//一小时是30度,一小时是60分钟,一分钟是30/60=0.5度
hourDiv.style.transform = "rotate(" + (hour * 30 + minute * 0.5) + "deg)";
}
默认调用东八区北京时间
// 默认选中北京-东八区时间
onChangeTimeFunc(8);
效果如图
最后美化了一下,添加一个title,显示一个数码方式时钟,效果如图:
4 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#title {
width: 200px;
font-size: 30px;
text-align: center;
color: aquamarine;
margin: 100px auto 10px;
}
#box {
width: 200px;
height: 200px;
position: relative;
border-radius: 50%;
border: 5px solid black;
margin: 0 auto;
}
#scale {
width: 200px;
height: 200px;
position: absolute;
}
#scale div {
width: 20px;
height: 200px;
position: absolute;
left: 92px;
}
#box span {
display: block;
position: absolute;
}
#box div:nth-of-type(2) span,
#box div:nth-of-type(3) span,
#box div:nth-of-type(4) span,
#box div:nth-of-type(5) span,
#box div:nth-of-type(6) span,
#box div:nth-of-type(7) span,
#box div:nth-of-type(8) span,
#box div:nth-of-type(9) span,
#box div:nth-of-type(10) span{
width: 20px;
text-align: center;
}
#hour {
width: 4px;
height: 50px;
position: absolute;
background-color: red;
left: 97px;
top: 50px;
/*这个属性可以改变旋转的中心点*/
transform-origin: bottom center;
}
#minute {
width: 4px;
height: 70px;
position: absolute;
background-color: cyan;
left: 97px;
top: 30px;
/*这个属性可以改变旋转的中心点*/
transform-origin: bottom center;
}
#second {
width: 4px;
height: 90px;
position: absolute;
background-color: pink;
left: 97px;
top: 10px;
/*这个属性可以改变旋转的中心点*/
transform-origin: bottom center;
}
#current_time_box, #select_box {
width: 200px;
margin: 0 auto;
}
#current_time_box {
padding: 20px 0;
text-align: center;
}
#current_time_box span {
height: 22px;
}
#select_box select{
width: 100%;
height: 30px;
}
</style>
</head>
<body>
<div id="title">
世界名表
</div>
<div id="box">
<div id="scale">
<div><span>12</span></div>
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
<div><span>6</span></div>
<div><span>7</span></div>
<div><span>8</span></div>
<div><span>9</span></div>
<div><span>10</span></div>
<div><span>11</span></div>
</div>
<div id="hour"></div>
<div id="minute"></div>
<div id="second"></div>
</div>
<div id="current_time_box">
<span id="current_time">--</span>
</div>
<div id="select_box">
<label>
<select onchange="onChangeTimeFunc(value)">
<!--东区时间-->
<option value="0">零时区</option>
<option value="1">东一区</option>
<option value="2">东二区</option>
<option value="3">东三区</option>
<option value="4">东四区</option>
<option value="5">东五区</option>
<option value="6">东六区</option>
<option value="7">东七区</option>
<option value="8" selected="selected">东八区</option>
<option value="9">东九区</option>
<option value="10">东十区</option>
<option value="12">东十二区</option>
<!--西区时间-->
<option value="-10">西十区</option>
<option value="-9">西九区</option>
<option value="-8">西八区</option>
<option value="-7">西七区</option>
<option value="-6">西六区</option>
<option value="-5">西五区</option>
<option value="-4">西四区</option>
<option value="-3">西三区</option>
</select>
</label>
</div>
<script src="https://unpkg.com/dayjs"></script>
<script type="text/javascript">
const scaleDivs = document.querySelectorAll("#scale div");
// 定时器
let timer = null;
//循环控制刻度形变的角度
for (let i = 0; i < scaleDivs.length; i++) {
//表盘一圈360度,总共有12个刻度,每个刻度之间是360/12=30度
scaleDivs[i].style.transform = "rotate(" + i * 30 + "deg)";
//解决刻度值显示正向问题,反向转回去就可以了
scaleDivs[i].firstChild.style.transform = "rotate(" + -i * 30 + "deg)";
}
//获取时分秒针DIV
const hourDiv = document.querySelector("#hour");
const minuteDiv = document.querySelector("#minute");
const secondDiv = document.querySelector("#second");
// 获取文本显示span
const currentTimeSpan = document.querySelector("#current_time");
// 选择时区的时间
function onChangeTimeFunc(value) {
clearInterval(timer);
currentTimeSpan.innerHTML = '';
// 获取当前时区时间
const date = getLocalTime(Number(value));
// 设置指针
setPointers(date);
// 启动定时器
timer = setInterval(function () {
// 每次获取当前时区时间
const currentDate = getLocalTime(Number(value));
setPointers(currentDate);
}, 1000);
}
//得到标准时区的时间的函数
function getLocalTime(i) {
//参数i为时区值数字,比如北京为东八区则输进8,西八区则输入-8
const d = new Date();
//得到1970年一月一日到现在的秒数
const len = d.getTime();
//本地时间与GMT时间的时间偏移差
const offset = d.getTimezoneOffset() * 60000;
//得到现在的格林尼治时间
const utcTime = len + offset;
return new Date(utcTime + 3600000 * i);
}
//设置指针
function setPointers(date) {
//把小时转换成12进制,方便运算
let hour = date.getHours() % 12;
let minute = date.getMinutes();
let second = date.getSeconds();
second++;
if (second === 60) {
second = 0;
minute++;
if (minute === 60) {
minute = 0;
hour++;
if (hour === 13) {
hour = 0;
}
}
}
//一圈360度,一圈60秒,每秒是360/60=6度
secondDiv.style.transform = "rotate(" + second * 6 + "deg)";
//一圈360度,一圈60分,每分是360/60=6度
minuteDiv.style.transform = "rotate(" + minute * 6 + "deg)";
//一圈360度,一圈12小时,每秒是360/12=30度
//一小时是30度,一小时是60分钟,一分钟是30/60=0.5度
hourDiv.style.transform = "rotate(" + (hour * 30 + minute * 0.5) + "deg)";
// 赋值span
currentTimeSpan.innerHTML = dayjs(date).format('YYYY-MM-DD HH:mm:ss');
}
// 默认选中北京-东八区时间
onChangeTimeFunc(8);
</script>
</body>
</html>
最后
今天是平安夜,希望大家平安快乐!
各位,早点下班,顺便留下你的脚印,谢谢