JS四步实现毫秒拖拽时钟

最终效果图:

JS实时毫秒时钟
核心原理:
##### 利用系统时间实时计算时分秒针角度,实现模拟时钟效果。
第一步:创建表盘和表针:
<!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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,273评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,349评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,709评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,520评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,515评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,158评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,755评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,660评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,203评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,287评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,427评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,122评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,801评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,272评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,393评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,808评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,440评论 2 359

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,264评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,117评论 4 61
  • 我很讨厌现在的自己 总是三分钟热度没有毅力 做事情推三阻四而且懒惰大于决心 激励自己的话说了太多却说说就过 计划定...
    邪帝陌邪阅读 1,118评论 0 0
  • 之前我们告诉了大家 要想啪的好! 臀和腰很重要!柔韧也需要! 但是除了它们,还有什么也是不可忽视的呢 Bingo!...
    RonaldMcDonald阅读 420评论 0 5
  • 两年前,相濡以沫欣喜交错…… 两年后,风景如故人不当初。 你还记得那片葱郁林木,瑰红的落日, 以及那只无名的寻归之...
    听云窃雨阅读 3,708评论 0 3