今天我们来用html,css,js 实现一个时钟的效果
如图
这个时钟是实时的效果,既然效果是动态交互的我们就需要用js来实现这个功能。
首先我们来写整体结构html部分
html部分
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="clock">
<div class="outer-clock-face">
<div class="marking marking-one"></div>
<div class="marking marking-two"></div>
<div class="marking marking-three"></div>
<div class="marking marking-four"></div>
<div class="inner-clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
其实看这张图我们可以把这个时钟分成两个部分,一个是外部时钟面板,一个是内部时钟面板。外部时钟包含内部时钟。内部时钟里面包含时针、分针和秒钟。外部时钟除了存放内部时钟之外,我们还需要存放刻度,刻度有12个,其实2个对应的刻度就是用一根长条实现,因此我们只需要有6根长条就可以,6根长条我们分为两部分,一部分是细的长条,有四根,另一部分是粗的长条,有2根。大家肯定发现了,我这里的html只有4根,另外两根粗的长条去哪里了?其实另外两根长条是用伪元素实现的,伪元素写在样式里面的,一前一后。
好现在已经给出了整体方向,我们现在实现css效果
css部分
html
部分:- 设置整个网页的背景颜色为白色。
- 设置网页的默认字体大小为10像素(这是基准字体大小,后续的字体大小可以相对于这个值进行调整)。
body
部分:- 设置网页的外边距(margin)为0,以消除默认外边距。
- 将网页的默认字体大小设置为
2rem
,这里介绍下rem单位,rem是基于根标签,根标签通常都是html元素,html元素中字体为10px,所以2rem就是20px。这相当于20像素,相对于html
根元素的字体大小。 - 使用 Flex 布局,使其内容在垂直和水平方向上都居中对齐。
- 设置网页的高度为视口高度vh(viewport height)的100%,以确保网页占据整个屏幕高度。
.clock
部分:- 定义一个时钟容器的样式。
- 设置容器的宽度和高度为30rem,创建一个圆形容器,边框为7像素宽的淡黄色。
- border-radius: 50%;这个属性是改变元素边框圆角的弧度,一个参数代表四个角都有相同的弧度,百分比得话只要是>=50就都是圆形。
- 添加一个圆形阴影效果,包括外部和内部的阴影,这里需要讲下rgba,rgb大家都知道,a是什么呢,a是alpha,意思为透明度,取值0(完全透明)-1(完全不透明)之间。
- 设置背景图像,并将其大小调整为容器的111%。
- 设置内边距为2rem。
.outer-clock-face
部分:- 定义外部时钟面板的样式。
- 创建一个圆形容器,充满父容器的100%宽度和高度。
- 通过伪元素
::before
和::after
添加两个垂直线条,这里注意:css伪元素用于向特定元素添加样式,无需为该元素创建额外的HTML元素,所以大家看到我的HTML中少了两个粗长条,另外,伪元素默认是不显示的,我之前的文章也有提到过,大家可以翻看我的上期文章。
.marking
、.marking-one
、.marking-two
、.marking-three
、.marking-four
部分:- 定义时钟面上的标记线的样式,以不同的角度旋转,创建刻度标记。
.inner-clock-face
部分:- 定义内部时钟面板的样式。
- 设置一个圆形容器,位于外部时钟面板内部。
- 设置背景颜色,添加背景图像,大小调整为125%。
- 在中心添加一个小圆形标记,这个圆形标记我把他的图层提高了一位,默认层级都是1,大家可以记住这个z-index属性,用来改变图层的。
.hand
、.hour-hand
、.min-hand
、.second-hand
部分:- 定义时钟的时、分、秒针样式。
- 设置宽度、高度、颜色,以及旋转效果,使它们在合适的位置旋转。
这里的参数都是实践出来的,不清楚的跟着我一起敲没有关系,敲多了代码对这些参数的设定就会很熟悉了。
css代码总览
css
html{
background: #fff;
font-size: 10px;
}
body{
margin: 0;
font-size: 2rem;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;/*view height 浏览器的高度*/
}
.clock{
width: 30rem;
height: 30rem;
border: 7px solid #ffedbd;
border-radius: 50%;
box-shadow: -4px -4px 10px rgba(67,67,67,0.1),
inset 4px 4px 10px rgba(168,145,128,0.6),
inset -4px -4px 10px rgba(201,175,155,0.2),
4px 4px 10px rgba(168,145,128,0.6);
background-image: url('./p.jpg');
background-size: 111%;
padding: 2rem;
}
.outer-clock-face{
width: 100%;
height: 100%;
border-radius: 50%;
position: relative;
}
.outer-clock-face::before,
.outer-clock-face::after{
content: '';
width: 10px;
height: 100%;
background: #1c2e03;
position: absolute;
border-radius: 8px;
left: 50%;
margin-left: -5px;
}
.outer-clock-face::after{
transform: rotate(90deg);
transform-origin: center center;
}
.marking{
width: 3px;
height: 100%;
background: #1c2e03;
position: absolute;
left: 50%;
margin-left: -1.5px;
}
.marking-one{
transform: rotateZ(30deg);
transform-origin: center center;
}
.marking-two{
transform: rotateZ(60deg);
transform-origin: center center;
}
.marking-three{
transform: rotateZ(120deg);
transform-origin: center center;
}
.marking-four{
transform: rotateZ(150deg);
transform-origin: center center;
}
.inner-clock-face{
position: absolute;
top: 10%;
left: 10%;
width: 80%;
height: 80%;
background-color: bisque;
z-index: 2;/*层级提高*/
border-radius: 50%;
background-image: url('./p.jpg');
background-size: 125%;
}
.inner-clock-face::before{
content: '';
position: absolute;
width: 16px;
height: 16px;
border-radius: 50%;
background: black;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
z-index: 2;
}
.hand{
width: 50%;
height: 6px;
background: red;
border-radius: 6px;
position: absolute;
top: 50%;
right: 50%;
margin-top: -3px;
transform-origin: 100% 50%;
transform: rotate(90deg);
}
.hour-hand{
width: 30%;
}
.min-hand{
width: 40%;
height: 3px;
background: yellow;
}
.second-hand{
background: grey;
width: 45%;
height: 2px;
}
js部分
先上代码
ini
const secondHand = document.querySelector('.second-hand')
const minHand = document.querySelector('.min-hand')
const hourHand = document.querySelector('.hour-hand')
// console.log(secondHand);
function setTime(){
const now = new Date()
//获取当前的秒数
const seconds = now.getSeconds()
const secondsDegrees = seconds * 6 + 90//从90°开始旋转
secondHand.style.transform = `rotate(${secondsDegrees}deg)`
//获取当前的分钟
const minutes = now.getMinutes()
const minutesDegrees = minutes * 6 + 90
minHand.style.transform = `rotate(${minutesDegrees}deg)`
//获取当前的时针
const hour = now.getHours()
const hoursDegrees = hour *30 + 90 + (minutes/60)*30
hourHand.style.transform = `rotate(${hoursDegrees}deg)`
}
setTime()
setInterval(setTime, 1000)
下面解释下这些代码,内容有点多,大家耐心看完
const secondHand = document.querySelector('.second-hand')
、const minHand = document.querySelector('.min-hand')
、const hourHand = document.querySelector('.hour-hand')
:这三行代码分别使用document.querySelector
方法从DOM中选择具有相应类名的HTML元素,并将它们分别存储在secondHand
、minHand
和hourHand
变量中。这些元素也通常是用于表示时钟的秒、分和时针的指针。function setTime()
:自定义一个js函数,用于获取当前时间并将其显示在指针上。函数内的代码如下:const now = new Date()
:创建一个Date
对象来获取当前的秒数。- 获取当前秒数、分钟数和小时数,并计算相应的角度:
const seconds = now.getSeconds()
:获取当前秒数。const secondsDegrees = seconds * 6 + 90
:将秒数乘以6,再加上90度,以将0秒对应于垂直向上的12点位置。const minutes = now.getMinutes()
:获取当前分钟数。const minutesDegrees = minutes * 6 + 90
:将分钟数乘以6,再加上90度。const hour = now.getHours()
:获取当前小时数。const hoursDegrees = hour * 30 + 90 + (minutes / 60) * 30
:将小时数乘以30,再加上90度,并添加分钟的偏移量,以考虑到小时指针在分钟内的旋转。
- 设置指针的旋转角度:
secondHand.style.transform =
rotate(${secondsDegrees}deg)``:通过修改style.transform
属性,将秒针的旋转角度设置为secondsDegrees
度。minHand.style.transform =
rotate(${minutesDegrees}deg)``:将分钟针的旋转角度设置为minutesDegrees
度。hourHand.style.transform =
rotate(${hoursDegrees}deg)``:将时针的旋转角度设置为hoursDegrees
度。
setTime()
:调用setTime
函数。setInterval(setTime, 1000)
:这一行设置了一个定时器,每1000毫秒(1秒)调用一次setTime
函数,以更新指针位置,实现实时显示当前时间。
最后的开头的效果就实现了,大家这里的图片可以放上女朋友的照片[doge],然后自己也做一个页面出来发给女朋友看看,哈哈哈。
关注我,获取更多有意思的前端小项目。如果觉得本文对你有帮助的话,可以给个免费的赞吗[doge] 还有可以给我的gitee链接codeSpace: 记录coding中的点点滴滴 (gitee.com)点一个免费的star吗[星星眼]