插件窝 干货文章 使用JavaScript实现一个炫酷的罗盘时钟

使用JavaScript实现一个炫酷的罗盘时钟

var textSet div class 88    来源:    2024-10-18

前言

在探究前端动画时。想到之前在锁屏壁纸看到的罗盘时钟,看着很是炫酷,于是说干就干,一起来研究下怎么用简单的方法实现这个炫酷的效果。 需要源码的小伙伴可到文章结尾直接复制使用。

先上效果图:

实现思路

(1)首先我们需要定义一系列的月、日、时、分、秒的数组,用来展示罗盘不同圆环上的数字

var monthText = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
        var dayText = ["一日", "二日", "三日", "四日", "五日", "六日", "七日", "八日", "九日", "十日", "十一日", "十二日", "十三日", "十四日", "十五日", "十六日"
            , "十七日", "十八日", "十九日", "二十日", "二十一日", "二十二日", "二十三日", "二十四日", "二十五日", "二十六日", "二十七日", "二十八日", "二十九日", "三十日", "三十一日"];
var weekText = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
var hourText = ["零时", "一时", "二时", "三时", "四时", "五时", "六时", "七时", "八时",
            "九时", "十时", "十一时", "十二时", "十三时", "十四时", "十五时", "十六时", "十七时", "十八时", "十九时", "二十时", "二十一时", "二十二时", "二十三时"];

....

(2)通过循遍历使用将这些数据生成dom节点放到html中

(3)通过setInterval循环运行,实时计算改变时分秒位置

开始实现

(1)定义基础dom结构

<body>
    <div id="clock"></div>
</body>

(2)循环遍历已定义的月、日、时、分、秒数组,通过document.createElement在clock下创建节点,并将创建的节点保存到textSet中,方便后面直接修改该dom的样式。

//循环遍历初始化数据
function init() {
    clock = document.getElementById('clock');
    for (var i = 0; i < textSet.length; i++) {
        for (var j = 0; j < textSet[i][0].length; j++) {
            var temp = createLabel(textSet[i][0][j]);
            clock.appendChild(temp);
            textSet[i][1].push(temp);
        }
    }
    clock.style.transform = "rotate(90deg)";
}

//创建子节点
function createLabel(text) {
        var div = document.createElement('div');
        div.classList.add('label');
        div.innerText = text;
        return div;
}

(3)计算每一层每一个节点的位置,首先获取当前时间,为了保证当前时间始终处于平行位置,所以需要计算其他值相对于当前位置的偏移角度,以及他们相对的X、Y的位置。计算每一层圆半径的长度,通过Math.sinMath.cos,以及获取页面宽和高定位到圆中心点就能得到每一个点的绝对位置。具体可以查看下面代码解析。

function runTime() {
    //获取当前时间
    var now = new Date();
    var month = now.getMonth();
    var day = now.getDate();
    var week = now.getDay();
    var hour = now.getHours();
    var minute = now.getMinutes();
    var seconds = now.getSeconds();
    var nowValue = [month, day - 1, week, hour, minute, seconds];
    initStyle();

    //当前年月日时高亮
    for (var i = 0; i < nowValue.length; i++) {
            var num = nowValue[i];
            textSet[i][1][num].style.color = '#fff';
    }
    //计算圆中心位置
    var widthMid = document.body.clientWidth / 2;
    var heightMid = document.body.clientHeight / 2;
    for (var i = 0; i < textSet.length; i++) {
        for (var j = 0; j < textSet[i][0].length; j++) {
            //计算每一层的圆半径
            var r = (i + 1) * 35 + 50 * i;
            //计算旋转角度
            var deg = 360 / textSet[i][1].length * (j - nowValue[i]);
            //计算绝对位置
            var x = r * Math.sin(deg * Math.PI / 180) + widthMid;
            var y = heightMid - r * Math.cos(deg * Math.PI / 180);
            //改变每一个节点的位置
            var temp = textSet[i][1][j];
            temp.style.transform = 'rotate(' + (-90 + deg) + 'deg)';
            temp.style.left = x + 'px';
            temp.style.top = y + 'px';
        }
    }
}

//还原所有的默认样式
function initStyle() {
    var label = document.getElementsByClassName('label');
    for (var i = 0; i < label.length; i++) {
        label[i].style.color = '#4d4d4d';
    }
}

(4)定义每一个节点的基本样式,为了实现时间变化时有旋转效果,增加transition: left 1s, top 1s;的过度动画

.label {
    position: absolute;
    display: inline-block;
    color: #4d4d4d;
    text-align: center;
    padding: 0 5px;
    font-family: "Microsoft YaHei";
    font-size: 19px;
    font-weight: bolder;
    transition: left 1s, top 1s;
    transform-origin: 0% 0%
}

完整代码

附上全部代码,有需要的小伙伴可直接复制使用:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>罗盘时钟</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0
        }

        html,
        body {
            width: 100%;
            height: 100%;
            background-color: black;
            overflow: hidden
        }

        #clock {
            position: relative;
            width: 100%;
            height: 100%;
            background: black
        }

        .label {
            position: absolute;
            display: inline-block;
            color: #4d4d4d;
            text-align: center;
            padding: 0 5px;
            font-family: "Microsoft YaHei";
            font-size: 19px;
            font-weight: bolder;
            transition: left 1s, top 1s;
            transform-origin: 0% 0%
        }
    </style>
    <script type="text/javascript">
        var monthText = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
        var dayText = ["一日", "二日", "三日", "四日", "五日", "六日", "七日", "八日", "九日", "十日", "十一日", "十二日", "十三日", "十四日", "十五日", "十六日"
            , "十七日", "十八日", "十九日", "二十日", "二十一日", "二十二日", "二十三日", "二十四日", "二十五日", "二十六日", "二十七日", "二十八日", "二十九日", "三十日", "三十一日"];
        var weekText = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
        var hourText = ["零时", "一时", "二时", "三时", "四时", "五时", "六时", "七时", "八时",
            "九时", "十时", "十一时", "十二时", "十三时", "十四时", "十五时", "十六时", "十七时", "十八时", "十九时", "二十时", "二十一时", "二十二时", "二十三时"];
        var minuteText = ["零分", "一分", "二分", "三分", "四分", "五分", "六分", "七分", "八分", "九分", "十分", "十一分", "十二分", "十三分", "十四分", "十五分", "十六分", "十七分", "十八分",
            "十九分", "二十分", "二十一分", "二十二分", "二十三分", "二十四分", "二十五分", "二十六分", "二十七分", "二十八分", "二十九分", "三十分", "三十一分", "三十二分", "三十三分",
            "三十四分", "三十五分", "三十六分", "三十七分", "三十八分", "三十九分", "四十分", "四十一分", "四十二分", "四十三分", "四十四分", "四十五分", "四十六分", "四十七分",
            "四十八分", "四十九分", "五十分", "五十一分", "五十二分", "五十三分", "五十四分", "五十五分", "五十六分", "五十七分", "五十八分", "五十九分"];
        var secondsText = ["零秒", "一秒", "二秒", "三秒", "四秒", "五秒", "六秒", "七秒", "八秒", "九秒", "十秒", "十一秒", "十二秒", "十三秒", "十四秒", "十五秒", "十六秒",
            "十七秒", "十八秒", "十九秒", "二十秒", "二十一秒", "二十二秒", "二十三秒", "二十四秒", "二十五秒", "二十六秒", "二十七秒", "二十八秒", "二十九秒", "三十秒", "三十一秒",
            "三十二秒", "三十三秒", "三十四秒", "三十五秒", "三十六秒", "三十七秒", "三十八秒", "三十九秒", "四十秒", "四十一秒", "四十二秒", "四十三秒", "四十四秒", "四十五秒",
            "四十六秒", "四十七秒", "四十八秒", "四十九秒", "五十秒", "五十一秒", "五十二秒", "五十三秒", "五十四秒", "五十五秒", "五十六秒", "五十七秒", "五十八秒", "五十九秒"];
        var clock;
        var monthList = [];
        var dayList = [];
        var weekList = [];
        var hourList = [];
        var minuteList = [];
        var secondsList = [];

        var textSet = [[monthText, monthList], [dayText, dayList], [weekText, weekList], [hourText, hourList], [minuteText, minuteList], [secondsText, secondsList]];

        var labelX = [];
        var labelY = [];
        window.onload = function () {
            init();
            setInterval(function () { runTime(); }, 500);
        }

        function init() {
            clock = document.getElementById('clock');
            for (var i = 0; i < textSet.length; i++) {
                for (var j = 0; j < textSet[i][0].length; j++) {
                    var temp = createLabel(textSet[i][0][j]);
                    clock.appendChild(temp);
                    textSet[i][1].push(temp);
                }
            }
            console.log(textSet)

            clock.style.transform = "rotate(90deg)";
        }

        function createLabel(text) {
            var div = document.createElement('div');
            div.classList.add('label');
            div.innerText = text;
            return div;
        }

        function runTime() {
            var now = new Date();
            var month = now.getMonth();
            var day = now.getDate();
            var week = now.getDay();
            var hour = now.getHours();
            var minute = now.getMinutes();
            var seconds = now.getSeconds();
            var nowValue = [month, day - 1, week, hour, minute, seconds];
            initStyle();

            //当前年月日时高亮
            for (var i = 0; i < nowValue.length; i++) {
                var num = nowValue[i];
                textSet[i][1][num].style.color = '#fff';
            }


            var widthMid = document.body.clientWidth / 2;
            var heightMid = document.body.clientHeight / 2;
            for (var i = 0; i < textSet.length; i++) {
                for (var j = 0; j < textSet[i][0].length; j++) {
                    var r = (i + 1) * 35 + 50 * i;
                    var deg = 360 / textSet[i][1].length * (j - nowValue[i]);
                    var x = r * Math.sin(deg * Math.PI / 180) + widthMid;
                    var y = heightMid - r * Math.cos(deg * Math.PI / 180);
                    var temp = textSet[i][1][j];
                    temp.style.transform = 'rotate(' + (-90 + deg) + 'deg)';
                    temp.style.left = x + 'px';
                    temp.style.top = y + 'px';
                }
            }
        }

        function initStyle() {
            var label = document.getElementsByClassName('label');
            for (var i = 0; i < label.length; i++) {
                label[i].style.color = '#4d4d4d';
            }
        }
    </script>

    <title> </title>


</head>

<body>
    <div id="clock"></div>
</body>

</html>

总结

通过上面一顿操作,短短几行代码实现了这个炫酷的方法,在涉及定位每个节点位置的时候,不得不再去复习下初中数学知识sin和cos的用法

到此这篇关于使用JavaScript实现一个炫酷的罗盘时钟的文章就介绍到这了,更多相关JavaScript罗盘时钟内容请搜索插件窝以前的文章或继续浏览下面的相关文章希望大家以后多多支持插件窝!