最终效果图:

核心原理:
##### 利用系统时间实时计算时分秒针角度,实现模拟时钟效果。
第一步:创建表盘和表针:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*
{
margin:0;
padding:0;
list-style:none;
}
#box
{
width:300px;
height:300px;
border:1px solid #000;
border-radius:50%;
position:absolute;
left:300px;
top:100px;
background:#fff;
box-shadow:1px 1px 5px #000;
}
/*设置旋转中心*/
#box div
{
transform-origin:center bottom;
}
#box .cap
{
width:20px;
border-radius:50%;
height:20px;
background:#999;
position:absolute;
left:50%;
top:50%;
margin:-10px 0 0 -10px;
}
#box .hour
{
width:14px;
height:80px;
background:#000;
position:absolute;
left:50%;
margin-left:-7px;
top:50%;
margin-top:-80px;
border-radius:50% 50% 0 0;
}
#box .min
{
width:10px;
height:100px;
background:#282828;
position:absolute;
left:50%;
top:50%;
margin-left:-5px;
margin-top:-100px;
border-radius:50% 50% 0 0;
}
#box .sec
{
width:4px;
height:120px;
background:#f00;
position:absolute;
left:50%;
margin-left:-2px;
top:50%;
margin-top:-120px;
}
</style>
</head>
<body>
<div id="box">
<div class="hour"></div>
<div class="min"></div>
<div class="sec"></div>
<div class="cap"></div>
</div>
</body>
</html>
第一步效果如下图所示:

第二步:生成表盘刻度(创建刻度元素并添加样式):
添加Sript部分:
<script>
window.onload=function(){
//获取元素
var oBox=document.getElementById('box');
var oH=document.querySelector('.hour');
var oM=document.querySelector('.min');
var oS=document.querySelector('.sec');
//生成刻度(这里我自定义了1刻度=2分钟,总共是60刻度)
var N=60;
//创建元素
for(var i=0; i<N; i++){
var oSpan=document.createElement('span');
//将小时刻度与分钟刻度区分开并添加class
if(i%5==0){ //整点刻度
oSpan.className='bs';
var num=i/5==0?12:i/5;
oSpan.innerHTML='<em>'+num+'<\/em>'; //添加小时数
oSpan.children[0].style.transform='rotate('+-i*6+'deg)'; //调整角度与钟框垂直
}else{ //分钟刻度
oSpan.className='scale';
}
oBox.appendChild(oSpan);
oSpan.style.transform='rotate('+6*i+'deg)';
}
};
</script>
添加CSS部分:
/*整点刻度样式*/
.bs
{
width:6px;
height:18px;
background:#000;
position:absolute;
left:50%;
margin-left:-3px;
transform-origin:center 150px;
}
/*分钟刻度样式*/
#box span em
{
margin-top:20px;
width:100px;
position:absolute;
left:50%;
margin-left:-50px;
text-align:center;
font-style:normal;
}
第二步效果如下图所示:

第三步:实时走动(获取系统时间、计算角度、添加定时器)
添加JS部分:
function clock(){
var oDate=new Date();
var h=oDate.getHours();
var m=oDate.getMinutes();
var s=oDate.getSeconds();
var ms=oDate.getMilliseconds();
//1h=60min;1h=30°;
oH.style.transform='rotate('+(h*30+m/60*30)+'deg)';
//1min=60s;1min=6°;
oM.style.transform='rotate('+(m*6+s/60*6)+'deg)';
//1s=1000ms;1s=6°;
oS.style.transform='rotate('+(s*6+ms/1000*6)+'deg)';
}
//防止打开卡顿一下
clock();
//设置定时器
setInterval(clock,30);
第四步:拖拽(获取旧位置设置新位置)
添加JS部分:
function drag(oDiv){
oDiv.onmousedown=function(ev){
var oEvent=ev || event;
//获取旧位置
var disX=oEvent.clientX-oDiv.offsetLeft;
var disY=oEvent.clientY-oDiv.offsetTop;
document.onmousemove=function(ev){
var oEvent=ev || event;
//设置新位置
oDiv.style.left=oEvent.clientX-disX+'px';
oDiv.style.top=oEvent.clientY-disY+'px';
};
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
//释放捕获
oDiv.releaseCapture && oDiv.releaseCapture();
};
//设置捕获
oDiv.setCapture && oDiv.setCapture();
return false;
};
};
完整代码:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*
{
margin:0;
padding:0;
list-style:none;
}
#box
{
width:300px;
height:300px;
border:1px solid #000;
border-radius:50%;
position:absolute;
left:300px;
top:100px;
background:#fff;
box-shadow:1px 1px 5px #000;
}
#box .cap
{
width:20px;
border-radius:50%;
height:20px;
background:#999;
position:absolute;
left:50%;
top:50%;
margin:-10px 0 0 -10px;
}
#box div
{
transform-origin:center bottom;
}
#box .hour
{
width:14px;
height:80px;
background:#000;
position:absolute;
left:50%;
margin-left:-7px;
top:50%;
margin-top:-80px;
border-radius:50% 50% 0 0;
}
#box .min
{
width:10px;
height:100px;
background:#282828;
position:absolute;
left:50%;
margin-left:-5px;
top:50%;
margin-top:-100px;
border-radius:50% 50% 0 0;
}
#box .sec
{
width:4px;
height:120px;
background:#f00;
position:absolute;
left:50%;
margin-left:-2px;
top:50%;
margin-top:-120px;
}
.scale
{
width:4px;
height:10px;
background:#000;
position:absolute;
left:50%;
margin-left:-2px;
transform-origin:center 150px;
}
.bs
{
width:6px;
height:18px;
background:#000;
position:absolute;
left:50%;
margin-left:-3px;
transform-origin:center 150px;
}
#box span em
{
margin-top:20px;
width:100px;
position:absolute;
left:50%;
margin-left:-50px;
text-align:center;
font-style:normal;
}
</style>
<script>
window.onload=function(){
var oBox=document.getElementById('box');
var oH=document.querySelector('.hour');
var oM=document.querySelector('.min');
var oS=document.querySelector('.sec');
//生成刻度
var N=60;
for(var i=0; i<N; i++){
var oSpan=document.createElement('span');
if(i%5==0){
oSpan.className='bs';
var num=i/5==0?12:i/5;
oSpan.innerHTML='<em>'+num+'<\/em>';
oSpan.children[0].style.transform='rotate('+-i*6+'deg)';
}else{
oSpan.className='scale';
}
oBox.appendChild(oSpan);
oSpan.style.transform='rotate('+6*i+'deg)';
}
function clock(){
var oDate=new Date();
var h=oDate.getHours();
var m=oDate.getMinutes();
var s=oDate.getSeconds();
var ms=oDate.getMilliseconds();
oH.style.transform='rotate('+(h*30+m/60*30)+'deg)';
oM.style.transform='rotate('+(m*6+s/60*6)+'deg)';
oS.style.transform='rotate('+(s*6+ms/1000*6)+'deg)';
}
clock();
setInterval(clock,30);
drag(oBox);
//拖拽
function drag(oDiv){
oDiv.onmousedown=function(ev){
var oEvent=ev || event;
var disX=oEvent.clientX-oDiv.offsetLeft;
var disY=oEvent.clientY-oDiv.offsetTop;
document.onmousemove=function(ev){
var oEvent=ev || event;
oDiv.style.left=oEvent.clientX-disX+'px';
oDiv.style.top=oEvent.clientY-disY+'px';
};
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
oDiv.releaseCapture && oDiv.releaseCapture();
};
oDiv.setCapture && oDiv.setCapture();
return false;
};
};
};
</script>
</head>
<body>
<div id="box">
<div class="hour"></div>
<div class="min"></div>
<div class="sec"></div>
<div class="cap"></div>
</div>
</body>
</html>
最后一个可以拖拽的毫秒时钟就做好了¬_¬!
(转载请注明出处: http://www.jianshu.com/p/70e6ff8171e5)
网友评论