This is the 8th day of my participation in Gwen Challenge

preface

See beautiful thing, still can like very much! Today, when I was setting up the wallpaper of my mobile phone, I saw a cool time wheel and thought it looked good. So I want to do it myself

Analysis and preparation

Because it is only a small demo, directly choose to use native JS to achieve, establish the directory structure as follows

In the CSS file, you can do some simple initialization styles. For convenience, I will introduce reset.css directly:

/ * http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) * /

html.body.div.span, applet, object.iframe.h1.h2.h3.h4.h5.h6.p.blockquote, pre,
a.abbr, acronym, address, big, cite.code.del.dfn.em.img.ins.kbd.q, s, samp,
small, strike, strong, sub, sup, tt, var.b, u, i, center,
dl.dt.dd.ol.ul.li.fieldset.form.label.legend.table.caption.tbody.tfoot.thead.tr.th.td.article.aside.canvas.details, embed, 
figure.figcaption.footer.header.hgroup.menu.nav, output, ruby, section.summary.time.mark.audio.video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article.aside.details.figcaption.figure.footer.header.hgroup.menu.nav.section {
	display: block;
}
body {
	line-height: 1;
}
ol.ul {
	list-style: none;
}
blockquote.q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: ' ';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
Copy the code

Add demo.css and demo.js to index.html and add div elements:

<div id="clock"></div>
Copy the code

JS part

1. First declare several arrays

Declare arrays of monthText, dayText, weekText, hourText, minuteText, and secondsText, each with text corresponding to month, day, week, hour, minute, and second. The main reason is to generate the DOM later

var monthText = ["Month"."February"."March"."April"."May"."June"."July"."August"."September"."October".November.December];
var dayText = ["Number one"."2"."3"."4"."V"."6"."7"."8"."9"."十号"."Eleven"."Number twelve"."Number thirteen"."Fourteenth"."Number fifteen"."Number sixteen"."Number seventeen"."Number eighteen"."Number nineteen"."Number twenty"."Twenty-one"."Number 22"."Twenty-three"."The twenty-fourth"."The twenty-fifth"."Number twenty-six"."No. 27"."Number twenty-eight"."Number twenty-nine"."Number thirty"."Thirty-one"];
var weekText = ["Sunday"."Monday"."Tuesday"."Wednesday"."Thursday"."Friday"."Saturday"];
var hourText = ["Zero"."A little"."Two"."Three"."Four"."5"."6"."Seven"."Eight"."Nine"."Ten"."Eleven o 'clock"."Twelve o 'clock"."Thirteen points"."Fourteen points"."Fifteen"."Sixteen"."Seventeen"."Eighteen"."Nineteen"."Twenty o 'clock".blackjack."Twenty two"."Twenty-three"];
var minuteText = ["One point"."Binary"."Three points"."Four points"."Five minutes"."Six points"."Seven"."Eight"."Nine points"."Very"."Eleven cents"."Twelve points"."Thirteen cents"."Fourteen minutes"."Fifteen minutes"."Sixteen minutes"."Seventeen points"."Eighteen"."Nineteen cents"."Twenty"."Twenty-one points"."Twenty-two points"."Twenty-three points"."Twenty-four points"."Twenty-five cents"."Twenty-six cents"."Twenty-seven cents"."Twenty-eight"."Twenty-nine cents"."Thirty"."Thirty-one minutes"."Thirty-two points"."Thirty-three minutes"."Thirty-four minutes"."Thirty-five points"."Thirty-six minutes"."Thirty-seven minutes"."Thirty-eight"."Thirty-nine minutes"."Forty points"."Forty-one"."Forty-two points"."Forty-three minutes"."Forty-four points"."Forty-five minutes"."Forty-six"."Forty-seven minutes"."Forty-eight"."Forty-nine minutes"."Fifty points"."Fifty-one cents"."Fifty-two points"."Fifty-three minutes"."Fifty-four points"."Fifty-five minutes"."Fifty-six"."Fifty-seven minutes"."Fifty-eight"."Fifty-nine"."Sixty points"];
var secondsText = ["A second"."Two seconds"."Three seconds"."Four seconds"."5 seconds"."Six seconds"."Seven seconds"."Eight seconds"."Nine seconds"."Ten seconds"."Eleven seconds"."Twelve seconds".Thirteen seconds."Fourteen seconds"."Fifteen seconds"."Sixteen seconds"."Seventeen seconds"."Eighteen seconds"."Nineteen seconds"."Twenty seconds"."Twenty-one seconds"."Twenty-two seconds"."Twenty-three seconds"."Twenty-four seconds."."Twenty-five seconds"."Twenty-six seconds"."Twenty-seven seconds"."Twenty-eight seconds"."Twenty-nine seconds"."Thirty seconds"."Thirty-one seconds"."Thirty-two seconds"."Thirty-three seconds"."Thirty-four seconds"."35 seconds"."Thirty-six seconds"."Thirty-seven seconds"."Thirty-eight seconds"."Thirty-nine seconds"."Forty seconds"."Forty-one seconds"."Forty-two seconds"."Forty-three seconds"."Forty-four seconds"."Forty-five seconds"."Forty-six seconds"."Forty-seven seconds"."Forty-eight seconds"."Forty-nine seconds"."Fifty seconds"."Fifty-one seconds"."Fifty-two seconds"."Fifty-three seconds"."54 seconds"."Fifty-five seconds"."Fifty-six seconds"."Fifty-seven seconds"."Fifty-eight seconds"."Fifty-nine seconds"."Sixty seconds"];
Copy the code

2. Declare the corresponding empty array

To manipulate the DOM, store the DOM in categories. For example, DOM related to a month is in a monthList, DOM related to a week is in a weekList, and so on

var monthList = [];
var dayList = [];
var weekList = [];
var hourList = [];
var minuteList = [];
var secondsList = [];
Copy the code

3. Declare a two-dimensional array

Two-dimensional arrays are mainly used to hold text content and page display labels

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

4. The initialization

Define an init function that generates label elements, fills in the corresponding text and adds class as ‘label’, stores the generated labels in their respective lists, and finally calls init after the page loads.

function init() {
    clock = document.getElementById('clock');
    // Generate a label to store text display
    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); }}}// Create a label and fill it with text
function createLabel(text) {
    var div = document.createElement('div');
    div.classList.add('label');
    div.innerText = text;
    return div;
}
window.onload = function () {
    init();
}
Copy the code

5. Style the label

Add a simple CSS style

html.body{
    width:100%;
    height:100%;
    background-color: # 000;
    overflow: hidden;
}
body #clock {
    position: relative;
    width: 100%;
    height: 100%;
    background: black;
}
body #clock .label{
    display:inline-block;
    color:#4d4d4d;
    text-align: center;
    padding:0 5px;
    font-size:19px;
    transition:left 1s.top 1s;
    transform-origin: 0% 0%;
}
Copy the code

6. Next, add a timer

This timer is used to update the page time at regular intervals, such as:

window.onload = function () {...// Get the current time every 100ms update page time display
    setInterval(function () {
        runTime();
    }, 100);    
}
Copy the code

Here we use a runTime function, which does the following:

  • Gets the current time
  • Sets the initialization style and sets the style for the current time
  • Turn into a circle (determine the center of the circle and the position of each element)
function runTime() {
    // Use the time object to get the current time
    var now = new Date(a);// Get month date hour minute second
    var month = now.getMonth();
    var day = now.getDate();
    var week = now.getDay();
    var hour = now.getHours();
    var minute = now.getMinutes();
    var seconds = now.getSeconds();
    // Initialize the time color and set the elapsed time to gray
    initStyle();
    // Set the current time to white
    // Store the current month in an array
    var nowValue = [month, day - 1, week, hour, minute, seconds];
    for (var i = 0; i < nowValue.length; i++) {
        var num = nowValue[i];
        textSet[i][1][num].style.color = '#fff';
    }

    // make a circle
    if (isCircle) {
        // Determine the center of the circle
        var widthMid = document.body.clientWidth / 2;
        var heightMid = document.body.clientHeight / 2;
        // Assign each DOM element to its circle position
        for (var i = 0; i < textSet.length; i++) {
            for (var j = 0; j < textSet[i][0].length; j++) {
                // Add each element's position x and y
                // The radius of each circle is related to the position of the minutes and seconds
                var r = (i + 1) * 35 + 50 * i;
                // Calculate each average Angle and align each unit into radians
                var deg = 360 / textSet[i][1].length * (j - nowValue[i]) ;
                // Calculate the coordinates of each DOM element
                var x = r * Math.sin(deg * Math.PI / 180) + widthMid;
                var y = heightMid - r*Math.cos(deg * Math.PI / 180);
                // Set the style
                var temp =  textSet[i][1][j];
                temp.style.transform = 'rotate(' + (-90 + deg ) + 'deg)';
                temp.style.left = x + 'px';
                temp.style.top = y + 'px'; }}}}Copy the code

The custom function initStyle is also used, which initializes all label labels to gray, as shown below

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

7. Change the position

Modify position before it becomes a circle

window.onload = function () {... changePosition(); }Copy the code
function changePosition() {
    for (let i = 0; i < textSet.length; i++) {
        for (let j = 0; j < textSet[i][1].length; j++) {
            // Get the original position and change position left top
            let tempX = textSet[i][1][j].offsetLeft + "px";
            let tempY = textSet[i][1][j].offsetTop + "px";
            setTimeout(function () {
                textSet[i][1][j].style.position = "absolute";
                textSet[i][1][j].style.left = tempX;
                textSet[i][1][j].style.top = tempY;
            }, 50); }}}Copy the code

8. Turn into a circle

window.onload = function () {...setTimeout(function () {
        changeCircle();
    }, 2000);
}
function changeCircle() {
    isCircle = true;
    clock.style.transform = "rotate(90deg)";
}
Copy the code

After the above general steps, the final result is displayed, as shown

conclusion

  1. Demo to consider performance issues, to be optimized
  2. The specific code can be viewed: github.com/jCodeLife/r…