漂亮的SVG时钟

效果图:

代码如下,复制即可使用:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>漂亮的SVG时钟</title>
<style>
body {
background: #1e2730;
font-family: Arial;
}
svg {
width: 100vmin;
margin: 0 auto;
display: block;
}
circle {
fill: none;
stroke-width: 3;
}
#secondsPath {
stroke-width: 3;
pointer-events: none;
stroke-linecap: round;
}
#minPath {
stroke-width: 3;
pointer-events: none;
stroke-linecap: round;
}
#hoursPath {
stroke-width: 3;
pointer-events: none;
stroke-linecap: round;
}
text {
dominant-baseline: central;
text-anchor: middle;
font-size: 5px;
fill: Linen;
}
svg text::selection {
background: none;
} #hub {
fill: #24303a;
stroke-width: 0;
}
#toggle,
#reset {
cursor: pointer;
} </style>
</head>
<body>
<svg viewBox="0 0 50 50">
<g>
<circle id="secondsCirc" r="14" stroke="#24303a" />
<path id="secondsPath" d="" fill="transparent" stroke="#1ed5f6" ></path> <circle id="minCirc" r="10" stroke="#24303a" />
<path id="minPath" d="" fill="transparent" stroke="#f61ed5" ></path> <circle id="hoursCirc" r="6" stroke="#24303a" />
<path id="hoursPath" d="" fill="transparent" stroke="#d5f61e" ></path> <circle id="hub" cx="0" cy="0" r="3.5" fill="#24303a" />
</g>
<text id="text" transform="translate(25 5)">00:00:00</text>
<text id="toggle" transform="translate(15 45)">STOP</text>
<text id="reset" transform="translate(37 45)">RESET</text>
</svg>
</body>
<script>
const rad = Math.PI / 180;
let requestId = null;
let stop = false;
const svg = document.querySelector("svg");
const g = document.querySelector("g"); const TIME = "16:07:50";
// counters
let h = parseInt(TIME.split(":")[0]);
let m = h * 60 + parseInt(TIME.split(":")[1]);
let s = h * 60 * 60 + m * 60 + parseInt(TIME.split(":")[2]);
//data
let circles = {
s: {
path: secondsPath,
divisions: 60,
r: secondsCirc.getAttribute("r"),
stroke: "#1ed5f6",
start: (parseInt(TIME.split(":")[2]))%60
},
m: {
path: minPath,
divisions: 60,
r: minCirc.getAttribute("r"),
stroke: "#f61ed5",
start: (parseInt(TIME.split(":")[1]))%60
},
h: {
path: hoursPath,
divisions: 24,
r: hoursCirc.getAttribute("r"),
stroke: "#d5f61e",
start: (parseInt(TIME.split(":")[0]))%24
}
}; let translation = { x: 25, y: 25 }; //translate
let rotation = -90;
let rot = -(rotation * rad);
g.setAttributeNS(
null,
"transform",
`translate(${translation.x} ${translation.y}) rotate(${rotation})`
); const spring = 0.09;
const friction = 0.8; class Clock {
constructor(o) {
this.path = o.path;
this.divisions = o.divisions; //24 || 60
this.R = o.r;
this.start = o.start;
this.strokeDashoffset = 0;
this.definePath(this.path);
this.vel = 0;
} update(time) {
let t = time % this.divisions; this.strokeLength = this.target;
this.target = t * this.pathLength / this.divisions; if (this.pathLength - this.strokeLength <= this.delta) {
this.strokeDashoffset += this.pathLength;
this.strokeLength = 0.1;
}
} updateStrokeLength() {
this.dist = this.target - this.strokeLength;
this.acc = this.dist * spring;
this.vel += this.acc;
this.vel *= friction;
this.strokeLength += this.vel;
this.path.style.strokeDasharray = `${this.strokeLength},${this.pathLength -
this.strokeLength}`;
this.path.style.strokeDashoffset = this.strokeDashoffset; } definePath() {
let d =
"M" +
this.R +
"," +
0 +
" A" +
this.R +
"," +
this.R +
" 0 " +
1 +
"," +
1 +
this.R +
"," +
-1 +
"z";
//y-1: the circles are rotated 90 degs this.path.setAttributeNS(null, "d", d);
this.pathLength = this.path.getTotalLength();
this.delta = this.pathLength / this.divisions;
this.strokeLength = this.start * this.delta;
this.target = this.strokeLength;
this.path.style.strokeDasharray = `${this.strokeLength},${this.pathLength -
this.strokeLength}`;
this.path.style.strokeDashoffset = this.strokeDashoffset;
}
} let secondsTrack = new Clock(circles.s);
let minTrack = new Clock(circles.m);
let hoursTrack = new Clock(circles.h); let sid = setInterval(setCron, 1000); function addZero(i) {
if (i < 10) {
i = "0" + i;
}
return i;
} function setText(h, m, s) {
text.textContent =
addZero(h % 24) + ":" + addZero(m % 60) + ":" + addZero(s % 60);
} setText(h, m, s); function Animation() {
requestId = window.requestAnimationFrame(Animation);
secondsTrack.updateStrokeLength();
minTrack.updateStrokeLength();
hoursTrack.updateStrokeLength();
}
Animation(); reset.addEventListener("click",resetCron,false); function resetCron(){
secondsTrack = new Clock(circles.s);
minTrack = new Clock(circles.m);
hoursTrack = new Clock(circles.h); h = parseInt(TIME.split(":")[0]);
m = h * 60 + parseInt(TIME.split(":")[1]);
s = h * 60 * 60 + m * 60 + parseInt(TIME.split(":")[2]); setText(h, m, s);
}
function setCron() {
secondsTrack.update(s);
if (s % 60 == 0) {
minTrack.update(m);
}
if (s % (60 * 60) == 0) {
hoursTrack.update(h);
} setText(h, m, s); s++;
if (s % 60 == 0) {
m++;
}
if (s % (60 * 60) == 0) {
h++;
}
} toggle.addEventListener("click",function(){ if(stop) {
stop = false;
toggle.textContent = "STOP";
sid = setInterval(setCron, 1000); }else{
stop = true;
toggle.textContent ="GO";
clearInterval(sid);
}
},false); </script>
</html>

如有错误,欢迎联系我改正,非常感谢!!!

最新文章

  1. 让Android程序获得系统的权限,实现关机重启,静默安装等功能
  2. Android 开发有用代码积累
  3. 当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误
  4. Android:利用SharedPreferences实现自动登录
  5. session 重写进入redis测试
  6. js设置radio选中
  7. Codeforces Round #311 (Div. 2) D - Vitaly and Cycle(二分图染色应用)
  8. Android 开发60条技术经验总结(转)
  9. mybatis框架搭建学习初步
  10. TODOList项目
  11. secureCRT自动化脚本
  12. 2017-2-17 c#基础学习 (控制台程序的创建,输出,输入,定义变量,变量赋值,值覆盖,值拼接,值打印)
  13. BZOJ 3027 Sweets 生成函数,容斥
  14. 【Java入门提高篇】Day3 抽象类与接口的比较
  15. .NET Core开源API网关 – Ocelot中文文档
  16. pycharm 的安装及selenium环境的搭建
  17. Selenium的发展历史及原理
  18. python 关于django 2.X from django.contrib.auth.views import login
  19. python操作MONGODB数据库,提取部分数据再存储
  20. MongoDB安全使用指引

热门文章

  1. WEB入门一 网页设计基础
  2. 小技巧--tab键自动补齐Git命令
  3. 6: Junit1_@Test
  4. QT 登陆对话框
  5. shell 中的操作符
  6. 1044 Shopping in Mars
  7. 转:NSString / NSData / char* 类型之间的转换
  8. Vue.js学习笔记(一)
  9. 洛谷P1102 A-B数对
  10. Swing教程