Kros的博客 Kros的博客
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云

Kros

凡心所向,素履以往,生如逆旅,一苇以航
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云
  • CSS

    • CSS绘制三角形
    • CSS排版上下文
    • CSS伪类
    • CSS伪元素
    • CSS实现列表元素分割线
    • CSS使用skew
    • CSS让物体居中
    • CSS绘制太极图
    • CSS使用实体替代预留符号
    • 动态修改after或before的content
    • CSS旋转border
    • CSS绘制空心五角星
    • CSS时钟
    • CSS图片手风琴伸缩效果
    • CSS的选择器
    • CSS波浪border
    • CSS内切圆角
    • CSS文字环绕
    • CSS outline使用详解
    • CSS使用transform缩放scale不生效
    • CSS使用linear-gradient或生成虚线
    • CSS 图片srcset属性
    • CSS object-fit属性详解
    • CSS 使用filter对颜色就行处理
    • CSS选择器的优先级
    • css与scss文件引入问题
    • CSS实现圆角梯形
    • 使用filter实现聚光灯效果
    • 利用backface-visibility hidden实现3d翻转双面card
    • 正方体3d旋转
    • 修改浏览器自动填充的背景颜色
    • CSS修改选中文字颜色
    • CSS实现打字机效果
    • marquee文字弹跳
    • logo文字图片倒影
    • 纯CSS实现popup弹窗
    • ie兼容inline-block
    • 浏览器默认样式
    • CSS效果-文字
    • CSS效果-按钮
    • css3 transition属性对linear-gradient渐变色无效
    • 不同预处理器下的样式穿透
    • 属性顺序
    • CSS重绘与回流
    • img标签与before和after
    • CSS实现文本两端对齐
    • CSS filter的contrast属性和blur属性奇特的结合
    • CSS不常用属性记录
    • CSS sprite雪碧图制作与使用
  • JavaScript

  • 工具

  • Vue

  • antdv踩坑记录

  • Vue3

  • 前端
  • CSS
kros
2021-02-24

CSS时钟

绘制时钟并不难,只要理解css基础知识和时钟角度转换就能很快实现。这里我借助vue简单实现时钟。先看效果:

时钟

第一步:计算角度绘制表盘

// 初始化刻度
initClockScale() {
	let time = [12,3,6,9], timePos = [{left: '50%', top: '0'},{left: '100%', top: '50%'},{left: '50%', top: '100%'},{left: '0', top: '50%'}], angle = 30, idx = 0;
	let scale = document.getElementById('scale');
	if(!scale) return;
	for(let i = 0; i <  time.length; i++) {			
		idx++;
		let elTime = this.createScale(angle, idx, time[i]);
		elTime.style.top = timePos[i].top;
		elTime.style.left = timePos[i].left;
		scale.appendChild(elTime);
		scale.appendChild(this.createScale(angle, idx)) && idx++;
		scale.appendChild(this.createScale(angle, idx)) && idx++;
	}
},
// 创建指针
createScale(angle, idx, content) {
	let m1 = document.createElement('div');
	m1.style.position = 'absolute';
	if(content) {
		m1.innerText = content;
		m1.style.color = '#CCCCCC';	
		m1.style.transform = 'translate(-50%, -50%)';
	}else {					
		m1.style.top = '0';
		m1.style.left = '50%';
		m1.style.width = '4px';
		m1.style.height = '8px';
		m1.style.transform = 'rotate('+ angle * idx +'deg)';
		m1.style.transformOrigin = '0 calc(85px)';
		m1.style.backgroundColor = '#CCCCCC';	
	}				
	return m1;
},
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

第二步:获取时间更新指针

let nowTime = new Date();
this.milliSecond = nowTime.getMilliseconds();
this.second = nowTime.getSeconds();
this.minute = nowTime.getMinutes();
this.hour = nowTime.getHours();	

// 初始化指针
initClockPointer() {
	// 计算秒钟角度
	let sAngle = (this.second + this.milliSecond / 1000) / 60 * 360;
	this.secondAngle = sAngle.toFixed(2);
	// 计算分针角度
	let mAngle = (sAngle / 3600 / 60 + this.minute / 60) * 360;
	this.minuteAngle = mAngle.toFixed(2);
	// 计算时针角度,注意时钟是12刻度不是60刻度
	let hAngle = (mAngle / 3600 / 60 + (this.hour > 12 ? (this.hour - 12) : this.hour) / 12) * 360 ;
	this.hourAngle = hAngle.toFixed(2);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

完整代码:

<template>
	<div class="pages">
		<div class="clock">
			<div class="scale" id="scale"></div>
			<div class="hour" :style="{transform: 'rotate('+hourAngle+'deg)'}"></div>
			<div class="minute" :style="{transform: 'rotate('+minuteAngle+'deg)'}"></div>
			<div class="second" :style="{transform: 'rotate('+secondAngle+'deg)'}"></div>
			<div class="dot"></div>
		</div>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				secondAngle: 0,
				minuteAngle: 0,
				hourAngle: 0
			}
		},
		methods: {
			// 初始化刻度
			initClockScale() {
				let time = [12,3,6,9], timePos = [{left: '50%', top: '0'},{left: '100%', top: '50%'},{left: '50%', top: '100%'},{left: '0', top: '50%'}], angle = 30, idx = 0;
				let scale = document.getElementById('scale');
				if(!scale) return;
				for(let i = 0; i <  time.length; i++) {			
					idx++;
					let elTime = this.createScale(angle, idx, time[i]);
					elTime.style.top = timePos[i].top;
					elTime.style.left = timePos[i].left;
					scale.appendChild(elTime);
					scale.appendChild(this.createScale(angle, idx)) && idx++;
					scale.appendChild(this.createScale(angle, idx)) && idx++;
				}
			},
			// 初始化指针
			initClockPointer() {
				// 计算秒钟角度
				let sAngle = (this.second + this.milliSecond / 1000) / 60 * 360;
				this.secondAngle = sAngle.toFixed(2);
				// 计算分针角度
				let mAngle = (sAngle / 3600 / 60 + this.minute / 60) * 360;
				this.minuteAngle = mAngle.toFixed(2);
				// 计算时针角度
				let hAngle = (mAngle / 3600 / 60 + (this.hour > 12 ? (this.hour - 12) : this.hour) / 12) * 360 ;
				this.hourAngle = hAngle.toFixed(2);
			},
			// 创建指针
			createScale(angle, idx, content) {
				let m1 = document.createElement('div');
				m1.style.position = 'absolute';
				if(content) {
					m1.innerText = content;
					m1.style.color = '#CCCCCC';	
					m1.style.transform = 'translate(-50%, -50%)';
				}else {					
					m1.style.top = '0';
					m1.style.left = '50%';
					m1.style.width = '4px';
					m1.style.height = '8px';
					m1.style.transform = 'rotate('+ angle * idx +'deg)';
					m1.style.transformOrigin = '0 calc(85px)';
					m1.style.backgroundColor = '#CCCCCC';	
				}				
				return m1;
			},
			// 开始时针
			startClock() {
				let that = this;
				// 整合毫秒差
				setTimeout(function() {
					that.initClockPointer();
					that.milliSecond = 0;
					setInterval(function() {
						// 固定间隔,直接获取时间,避免程序运行的误差
						let nowTime = new Date();
						that.milliSecond = nowTime.getMilliseconds();
						that.second = nowTime.getSeconds();
						that.minute = nowTime.getMinutes();
						that.hour = nowTime.getHours();
						that.initClockPointer();
					}, 1000);
				}, 1000 - that.milliSecond);
			}
		},
		mounted() {		
			let nowTime = new Date();
			this.milliSecond = nowTime.getMilliseconds();
			this.second = nowTime.getSeconds();
			this.minute = nowTime.getMinutes();
			this.hour = nowTime.getHours();	
			this.initClockScale();
			this.startClock();
			console.log(this.hour);
		}
	}
</script>

<style scoped lang="scss">
	.pages {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 100vw;
		height: 100vh;
		background: #002B36;
		.clock {
			position: relative;
			width: 200px;
			height: 200px;
			border-radius: 50%;
			box-shadow: inset 0 -3px 5px 2px rgba(255,255,255,.1);
			.scale {
				position: absolute;
				left: 15px;
				top: 15px;
				width: 170px;
				height: 170px;
				// 基准线
				// &::before {
				// 	content: '';
				// 	position: absolute;
				// 	top: 0;
				// 	left: 50%;
				// 	width: 1px;
				// 	height: 100%;
				// 	background: white;
				// }
				
				// &::after {
				// 	content: '';
				// 	position: absolute;
				// 	top: 50%;
				// 	left: 0;
				// 	width: 100%;
				// 	height: 1px;
				// 	background: white;
				// }
			}
			
			.dot {
				position: absolute;
				left: 50%;
				top: 50%;
				width: 15px;
				height: 15px;
				border-radius: 50%;
				transform: translate(-50%, -50%);
				background: #CCCCCC;
			}
			
			.hour {
				position: absolute;
				top: calc(50% - 40px);
				left: calc(50% - 4px);
				width: 8px;
				height: 40px;
				border-radius: 8px;
				transform: rotate(30deg);
				transform-origin: bottom;
				background: #710909;
			}
			
			.minute {
				position: absolute;
				top: calc(50% - 50px);
				left: calc(50% - 3px);
				width: 5px;
				height: 50px;
				border-radius: 5px;
				transform: rotate(45deg);
				transform-origin: bottom;
				background: black;
			}
			
			.second {
				position: absolute;
				top: 40px;
				left: calc(50% - 1px);
				width: 2px;
				height: 80px;
				border-radius: 2px;
				transform: rotate(360deg);
				transform-origin: 50% 60px;
				background: white;
			}
		}
	}
</style>

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

在线尝试:时钟demo

上次更新: 2025/09/05, 8:09:00
CSS绘制空心五角星
CSS图片手风琴伸缩效果

← CSS绘制空心五角星 CSS图片手风琴伸缩效果→

最近更新
01
Find the next perfect square
09-05
02
Regex validate PIN code
09-05
03
Find the odd int
09-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 kros king
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
icon-heart-o icon-heart icon-infinity icon-pause icon-play link next prev