美文网首页
JavaScript仿IOS Clock

JavaScript仿IOS Clock

作者: 泥垢樂 | 来源:发表于2018-07-04 23:29 被阅读0次

    JavaScript仿IOS Clock

    参考

    原文JavaScript仿Clock IOS时钟

    描述

    用JavaScript模仿IOS上Clock时钟

    效果

    IOS Clock

    项目分析

    1. 时钟,首先得获取本地时间
    2. 时钟有3个指针,通过添加动画的方式让它围绕中心点旋转
    3. 通过获取到的hour/minute/second值分别计算时针/分针/秒针的角度值

    HTML & CSS

    布局

    <div class="box">
        <article class="clock">
            <div class="hours-container">
                <div class="hours"></div>
            </div>
            <div class="minutes-container">
                <div class="minutes"></div>
            </div>
            <div class="seconds-container">
                <div class="seconds"></div>
            </div>
        </article>
    </div>
    
    1. .box是为了布局的方便
    2. 每个指针都需要一个*.container容器

    添加背景样式

    html {
        /* font-size必须大于等于12,否则不生效*/
        font-size: 12px; 
    }
    
    html, body {
        margin: 0px;
        padding: 0px;
    }
    
    .box {
        width: 35rem;
        height: 38rem;
        background: rgb(205, 205, 205);
        border-radius: 1rem;
        margin: 5% auto;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    
    .clock {
      width: 30rem;
      height: 30rem;
      background: #fff url('./images/ios_clock.svg') no-repeat center;
      background-size: 88%;
      border-radius: 50%;
      position: relative;
    }
    
    Background
    1. 设置.box的width和height,建议用rem单位,这样手机上效果也很好
    2. .box采用Flex布局,并且.clock在水平和垂直方向上都居中,具体Flex布局后面章再介绍
    3. Clock的背景使用了一张图片,具体见最后的项目地址

    添加中心轴

    .clock:after {
      /* content是必须的,不然伪元素不会显示 */
      content: '';
      width: 1.5rem;
      height: 1.5rem;
      background: #000;
      border-radius: 50%;
      position: absolute;
      top: 50%;
      left: 50%;
      /* 向坐上移动自身的50% */
      transform: translate(-50%, -50%); 
      z-index: 10;
    }
    
    Central Axis
    1. 使用CSS3中的伪元素为时钟添加实心小圆点,指针都围绕这个点转
    2. content: '';是必须的,不然伪元素无法显示
    3. 相对定位,top: 50%; left: 50%; 无法是小圆点在正中心,使用transform: translate(-50%, -50%)向左上方移动自身宽高的一半
    4. z-index: 10;为了使小圆点在视图的最上层,遮挡指针交叉的地方

    指针容器

    .hours-container, .minutes-container, .seconds-container {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }
    
    1. 添加指针容器后,暂时并无效果
    2. 指针的转动,实际是通过动态调整指针容器的角度实现的
    3. 添加指针容器后,可以添加指针的样式了

    添加指针

    .hours {
      width: 3%;
      height: 20%;
      background: #000;
      position: absolute;
      top: 30%;
      left: 48.5%;
    }
    
    .minutes {
      width: 2%;
      height: 37%;
      background: #000;
      position: absolute;
      top: 13%;
      left: 49%;
    }
    
    .seconds {
      width: 1%;
      height: 40%;
      background: #f00;
      position: absolute;
      top: 20%;
      left: 49.5%;
      z-index: 8;
    }
    
    Hand
    1. 分别添加时针、分针、秒针
    2. 时针较粗,分针次之,秒针最细,采用3%、2%、1%递减,可以自己调整
    3. %是相对于各自的*.container容器元素的
    4. 时针top: 30%; height: 20%; 两者相加正好为50%,即下边缘与中心轴重合,分针同理
    5. 时针width: 3%; left: 48.5%; width/2 + left == 50%,分针、秒针同理
    6. 秒针top: 20%; height: 40%; top + height == 60%,秒针下边缘超过中心轴,超出10%

    动画

    定义动画规则

    @keyframes rotate {
      100% {
        transform: rotateZ(360deg);
      }
    }
    

    采用@keyframes规则定义一个动画,动画名称为rotate,这个动画的元素会沿着Z轴旋转360°

    定时器

    .hours-container {
      animation: rotate 36s infinite linear;
    }
    
    .minutes-container {
      animation: rotate 18s infinite steps(60);
    }
    
    .seconds-container {
      animation: rotate 3s infinite steps(60);
    }
    
    Animation
    1. 为了演示的方便,固定的事件并未按真实的时间来设置。时针是12小时(43200秒)、分针是60分钟(3600秒),秒针是60秒。
    2. 为了有咔嚓咔嚓的跳动,秒针、分针采用steps(60),每步60°
    3. 由于CSS的时间是有一定误差的,所以不能直接采用1. 中的值
    4. 请删除或注释定义动画规则定时器中的CSS代码

    时钟

    获取本地时间,并计算每个指针应该旋转的角度,并设置

    获取每个指针

    const hourHand = document.querySelector('.hours-container');
    const minuteHand = document.querySelector('.minutes-container');
    const secondHand = document.querySelector('.seconds-container');
    

    实际获取的是指针的容器

    获取本地时间

    const now = new Date();
    const hour = now.getHours();
    const minute = now.getMinutes();
    const second = now.getSeconds();
    

    计算指针角度

    在CSS3中角度单位一共有4种:

    • deg (度,一个圆360度)
    • grad (梯度,一个圆400梯度)
    • turn (转/圈,一个圆1圈)
    • rad (弧度,一个圆2π弧度)
    const secondDegree = second * 6;
    const minuteDegree = minute * 6;
    const hourDegree = (hour * 30) + (minute / 2);
    
    1. 秒针一圈是360°,60秒,每秒360 / 60 = 6°,所以秒针角度为second * 6
    2. 分针一圈是360°,60分钟,每分钟360 / 60 = 6°,所以分针角度为minute * 6
    3. 时针一圈是360°,12小时,每小时360 / 12 = 30°,又由于分针转动时,时针也会产生微小的移动,minute * 30° / 60分钟 = minute / 2,所以时针角度为(hour * 30) + (minute / 2)

    设置角度值

    hourHand.style.transform = `rotateZ(${hourDegree}deg)`;
    minuteHand.style.transform = `rotateZ(${minuteDegree}deg)`;
    secondHand.style.transform = `rotateZ(${secondDegree}deg)`;
    

    以上可以根据本地时间设置时钟角度,但想要时钟实时转动,则需要增加setInterval

    定时更新

    <script>
        function clockWalk() {
            const hourHand = document.querySelector('.hours-container');
            const minuteHand = document.querySelector('.minutes-container');
            const secondHand = document.querySelector('.seconds-container');
    
            const now = new Date();
            const hour = now.getHours();
            const minute = now.getMinutes();
            const second = now.getSeconds();
    
            const secondDegree = second * 6;
            const minuteDegree = minute * 6;
            const hourDegree = (hour * 30) + (minute / 2);
    
            hourHand.style.transform = `rotateZ(${hourDegree}deg)`;
            minuteHand.style.transform = `rotateZ(${minuteDegree}deg)`;
            secondHand.style.transform = `rotateZ(${secondDegree}deg)`;
        }
        setInterval(function() {
            clockWalk();
        }, 1000);
    </script>
    
    F12

    通过以上动态图可知,指针转动实际是通过转动*.container对应的div来实现的

    这样,整个时钟就完成了

    项目地址:码云/c02954/ios_clock

    相关文章

      网友评论

          本文标题:JavaScript仿IOS Clock

          本文链接:https://www.haomeiwen.com/subject/uuxuuftx.html