在body中用SVG格式实现时钟的绘制,在script标签中定义更新事件的方法,并通过setInternal函数实现重复绘制。通过将时间的变化转换为在钟面上的旋转角度,把相应的SVG元素进行旋转,实现时分秒中的转动。
<body>
<!-- viewBox是坐标系,width和height是屏幕大小 -->
<div id="time" style="margin-left: 625px">
<script src="change.js"></script>
</div>
<svg id="clock" viewBox="0 0 100 100" width="500" height="500">
<defs>
<!--定义下拉阴影的滤镜-->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur" />
<feOffset in="blur" dx="1" dy="1" result="shadow" />
<feMerge>
<feMergeNode in="SourceGraphic" />
<feMergeNode in="shadow" />
</feMerge>
</filter>
</defs>
<circle id="face" cx="50" cy="50" r="45" />
<!-- 钟面 -->
<!-- 初始绘制成竖直的指针,之后通过JavaScript代码来做旋转 -->
<g id="hands" filter="url(#shadow)">
<!-- 给指针添加阴影 -->
<line id="secondhand" x1="50" y1="50" x2="50" y2="10" />
<line id="hourhand" x1="50" y1="50" x2="50" y2="18" />
<line id="minutehand" x1="50" y1="50" x2="50" y2="11" />
</g>
<g id="ticks">
<!-- 12小时的刻度 -->
<line x1='50' y1='5.000' x2='50.00' y2='10.00' />
<line x1='72.50' y1='11.03' x2='70.00' y2='15.36' />
<line x1='88.97' y1='27.50' x2='84.64' y2='30.00' />
<line x1='95.00' y1='50.00' x2='90.00' y2='50.00' />
<line x1='88.97' y1='72.50' x2='84.84' y2='70.00' />
<line x1='72.50' y1='88.97' x2='70.00' y2='84.64' />
<line x1='50.00' y1='95.00' x2='50.00' y2='90.00' />
<line x1='27.50' y1='88.97' x2='30.00' y2='84.64' />
<line x1='11.03' y1='72.50' x2='15.36' y2='70.00' />
<line x1='5.000' y1='50.00' x2='10.00' y2='50.00' />
<line x1='11.03' y1='27.50' x2='15.36' y2='30.00' />
<line x1='27.50' y1='11.03' x2='30.00' y2='15.36' />
</g>
<g id="numbers">
<!-- 标记重要的几个刻度 -->
<text x="50" y="18">12</text>
<text x="85" y="53">3</text>
<text x="50" y="88">6</text>
<text x="15" y="53">9</text>
</g>
</svg>
<script>
setInterval(function updateTime() { //更新SVG时钟来显示当前时间
var now = new Date(); //当前时间
var sec = now.getSeconds(); //秒
var min = now.getMinutes(); //分钟
var hour = (now.getHours() % 12) + min / 60 + sec / 3600;
//转换成可以在时钟上表示的时间
var secangle = sec * 6; //每6°表示一秒钟
var minangle = min * 6; //每6°表示一分钟
var hourangle = hour * 30; //每30°表示一个小时
//获取表示时钟时针和分针的SVG元素
var sechand = document.getElementById("secondhand");
var minhand = document.getElementById("minutehand");
var hourhand = document.getElementById("hourhand");
//设置这些元素的SVG属性,将他们移动到钟面上
sechand.setAttribute("transform", "rotate(" + secangle + ",50,50)");
minhand.setAttribute("transform", "rotate(" + minangle + ",50,50)");
hourhand.setAttribute("transform", "rotate(" + hourangle + ",50,50)");
}, 1000);
</script>
</body>
没有将css样式渲染写在单独的文件中,而是定义在head标签部分,style里定义的样式都会根据id作用于相应的元素上。
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>时钟</title>
<style>
/*以下定义的所有CSS样式都会作用在SVG元素上*/
#face {
stroke-width: 3px; /*时钟的外边框*/
stroke: #C4C4C4;
}
#hourhand { /*相对较粗的时针*/
stroke-width: 1.5px;
stroke: #EDEDED;
}
#minutehand {
stroke-width: 1px; /*相对较细的分针*/
stroke: #EDEDED;
}
#secondhand {
stroke-width: 0.5px; /*最细的秒针*/
stroke: #F7F7F7;
}
#numbers { /*如何绘制数字*/
font-family: sans-serif;
font-size: 7px;
font-weight: bold;
text-anchor: middle;
stroke: none;
fill: black;
}
#clock { /*用于时钟的全局样式*/
stroke: #EEE9E9;
stroke-linecap: round; /*圆角*/
stroke: ButtonHighlight;
fill: #EEE9E9; /*以前灰色为背景*/
margin-left: 400px;
}
#ticks {
stroke-width: 2px; /*标记每个小时的线段*/
stroke: #C4C4C4;
}
</style>
</head>
function addLoadEvent(func) {
//把现有的window.onload事件处理函数的值存入变量onload
var oldonload = window.onload;
//如果在这个处理函数上还没有绑定任何函数,就像平时那样把新函数添加给它
if (typeof window.onload != 'function') {
window.onload = func;
} else {
//如果在这个处理函数上已经绑定了一些函数,就把心函数追加到现有指令的末尾
window.onload = function () {
oldonload();
func();
}
}
}
function showTime() {
var now = new Date();
var weekday = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
var date = weekday[now.getDay()] + "<br>" + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds();
document.getElementById("time").innerHTML = date;
setTimeout(showTime, 1000);
}
//将showTime()函数添加到处理事件队列
addLoadEvent(showTime());
最终效果图如下: