1 introduction

Use CSS and JS to implement a clock, plus switching time zones.

2 Production Ideas

  1. Draw the dial
  2. Add hour, minute, and second hands
  3. Set the pointer
  4. Set the time zone

3 Code Implementation

Draw the dial

First implement a watch face of the watch frame,

#title {
    width: 200px;
    font-size: 30px;
    text-align: center;
    color: aquamarine;
    margin: 100px auto 10px;
}

#box {
    width: 200px;
    height: 200px;
    position: relative;
    border-radius: 50%;
    border: 5px solid black;
    margin: 0 auto;
}

#scale {
    width: 200px;
    height: 200px;
    position: absolute;
}

#scale div {
    width: 20px;
    height: 200px;
    position: absolute;
    left: 92px;
}
Copy the code

Add the numbers to the dial

<div id="scale">
    <div><span>12</span></div>
    <div><span>1</span></div>
    <div><span>2</span></div>
    <div><span>3</span></div>
    <div><span>4</span></div>
    <div><span>5</span></div>
    <div><span>6</span></div>
    <div><span>7</span></div>
    <div><span>8</span></div>
    <div><span>9</span></div>
    <div><span>10</span></div>
    <div><span>11</span></div>
</div>
Copy the code

The effect now is a black circle with the numbers stacked on top of each other. As shown in figure:

Using CSS to change the position one by one is too much trouble. You can use JS to get all the nodes and iterate to change the Angle, as shown in the following figure:

for (let i = 0; i < scaleDivs.length; ScaleDivs [I].style. Transform = "rotate(" + I * 30 + "deg)"; scaleDivs[I].transform = "rotate(" + I * 30 + "deg)"; }Copy the code

However, the scale values have positive and negative problems, and the span inside is reversed, as shown in the figure

/ / solve the problem of scale value shows positive, it is ok to reverse back scaleDivs [I] firstChild. Style.css. Transform = "rotate (" I * 30 + + -" deg) ";Copy the code

Add hour, minute, and second hands

The transform-origin property will change the center point, because the pointer has a center point, so we set the center point of the pointer in the middle of the bottom.

#hour { width: 4px; height: 50px; position: absolute; background-color: red; left: 97px; top: 50px; /* This property can change the center point of rotation */ transform-origin: bottom center; } #minute { width: 4px; height: 70px; position: absolute; background-color: cyan; left: 97px; top: 30px; /* This property can change the center point of rotation */ transform-origin: bottom center; } #second { width: 4px; height: 90px; position: absolute; background-color: pink; left: 97px; top: 10px; /* This property can change the center point of rotation */ transform-origin: bottom center; }Copy the code
<div id="hour"></div>
<div id="minute"></div>
<div id="second"></div>
Copy the code

The effect is as follows:

Set the pointer

  • Second hand: a circle of 360 degrees, a circle of 60 seconds, 360/60=6 degrees per second
  • Minute hand: a round of 360 degrees, a round of 60 minutes, each minute is 360/60=6 degrees
  • Hour hand: a circle of 360 degrees, a circle of 12 hours, 360/12=30 degrees per second

According to the above idea, give a timer is not to move

Var hourDiv = document.querySelector("#hour"); var minuteDiv = document.querySelector("#minute"); var secondDiv = document.querySelector("#second"); Var date = new date (); Var hour = date.gethours () % 12; var minute = date.getMinutes(); var second = date.getSeconds(); // set pointer function setPointers() {second++; if (second == 60) { second = 0; minute++; if (minute == 60) { minute = 0; hour++; if (hour == 13) { hour = 0; }}} / / a circle of 360 degrees, a circle of 60 seconds, every second is 360/60 = 6 degrees secondDiv. Style.css. Transform = "rotate (" + second * 6 +" deg) "; / / a circle of 360 degrees, a circle of 60 points, each of them is 360/60 = 6 minuteDiv. The style.css. Transform = "rotate (" + minute * 6 +" deg) "; // One circle is 360 degrees, one circle is 12 hours, 360/12=30 degrees per second // One hour is 30 degrees, one hour is 60 minutes, Transform = "rotate(" + (hour * 30 + minute * 0.5) + "; hourdiv.style. transform = "rotate(" + (hour * 30 + minute * 0.5) + "; } setPointers(); // setInterval(function () {setInterval(); }, 1000);Copy the code

The effect is as follows:

In order to align the pointer with the scale, I styled the 1-digit scale based on the width of the 12-digit scale and centered it

#box div:nth-of-type(2) span,
#box div:nth-of-type(3) span,
#box div:nth-of-type(4) span,
#box div:nth-of-type(5) span,
#box div:nth-of-type(6) span,
#box div:nth-of-type(7) span,
#box div:nth-of-type(8) span,
#box div:nth-of-type(9) span,
#box div:nth-of-type(10) span{
    width: 20px;
    text-align: center;
}
Copy the code

Set the time zone

With so many time zones in the world, there has to be a standard, which is GMT, Greenwich Mean time

Universal time UT [1] is Greenwich Mean solar time [1]. It is the standard time at the location of Greenwich. It is also a form of the earth’s rotation rate.

Add select to select a time zone

<div id="select_box"> <label> <select onchange="onChangeTimeFunc(value)"> <! -- Eastern time --> <option value="0"> Zero time zone </option> <option value="1"> Eastern one zone </option> <option value="2"> Eastern two zone </option> <option Value ="3"> </option> <option value="4"> </option> <option value="5"> </option> <option value="6"> <option value="7"> Select </option> <option value="8" selected="selected"> Select </option> <option value="9"> Select </option> <option Value ="10"> </option> <option value="12"> </option> <! -- West End time --> <option value="-10"> West End </option> <option value="-9"> West End </option> <option value="-8"> West end </option> <option value="-8" Value ="-7"> </option> <option value="-6"> </option> <option value="-5"> </option> <option value="-4"> </option> < option value = "3" > west three < option > < / select > < / label > < / div >Copy the code

Select the time zone handler

Function onChangeTimeFunc(value) {clearInterval(timer); Const date = getLocalTime(Number(value)); // Set the pointer setpointer (date); // Start timer timer = setInterval(function () {const currentDate = getLocalTime(Number(value)); setPointers(currentDate); }, 1000); }Copy the code

Gets the current time for the selected time zone

Function getLocalTime(I) {const d = new Date(); // Const d = new Date(); // const d = new Date(); Const len = d.gettime (); // Get the number of seconds from January 1, 1970 const len = d.gettime (); // Offset between local time and GMT time const offset = d.gettimezoneoffset () * 60000; Const utcTime = len + offset; return new Date(utcTime + 3600000 * i); }Copy the code

We need to repackage the setPointers method we wrote earlier so that the time is not the current time, but the parameter passed in

// set pointer function setpointer (date) {let hour = date.gethours () % 12; let minute = date.getMinutes(); let second = date.getSeconds(); second++; if (second === 60) { second = 0; minute++; if (minute === 60) { minute = 0; hour++; if (hour === 13) { hour = 0; }}} / / a circle of 360 degrees, a circle of 60 seconds, every second is 360/60 = 6 degrees secondDiv. Style.css. Transform = "rotate (" + second * 6 +" deg) "; / / a circle of 360 degrees, a circle of 60 points, each of them is 360/60 = 6 minuteDiv. The style.css. Transform = "rotate (" + minute * 6 +" deg) "; // One circle is 360 degrees, one circle is 12 hours, 360/12=30 degrees per second // One hour is 30 degrees, one hour is 60 minutes, Transform = "rotate(" + (hour * 30 + minute * 0.5) + "; hourdiv.style. transform = "rotate(" + (hour * 30 + minute * 0.5) + "; }Copy the code

The default call is Beijing time

// Select onChangeTimeFunc(8) by default;Copy the code

The effect is shown in figure

Finally, I beautified it by adding a title to display a digital clock, as shown in the picture:

4 Complete Code

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> * { padding: 0; margin: 0; } #title { width: 200px; font-size: 30px; text-align: center; color: aquamarine; margin: 100px auto 10px; } #box { width: 200px; height: 200px; position: relative; border-radius: 50%; border: 5px solid black; margin: 0 auto; } #scale { width: 200px; height: 200px; position: absolute; } #scale div { width: 20px; height: 200px; position: absolute; left: 92px; } #box span { display: block; position: absolute; } #box div:nth-of-type(2) span, #box div:nth-of-type(3) span, #box div:nth-of-type(4) span, #box div:nth-of-type(5) span, #box div:nth-of-type(6) span, #box div:nth-of-type(7) span, #box div:nth-of-type(8) span, #box div:nth-of-type(9) span, #box div:nth-of-type(10) span{ width: 20px; text-align: center; } #hour { width: 4px; height: 50px; position: absolute; background-color: red; left: 97px; top: 50px; /* This property can change the center point of rotation */ transform-origin: bottom center; } #minute { width: 4px; height: 70px; position: absolute; background-color: cyan; left: 97px; top: 30px; /* This property can change the center point of rotation */ transform-origin: bottom center; } #second { width: 4px; height: 90px; position: absolute; background-color: pink; left: 97px; top: 10px; /* This property can change the center point of rotation */ transform-origin: bottom center; } #current_time_box, #select_box { width: 200px; margin: 0 auto; } #current_time_box { padding: 20px 0; text-align: center; } #current_time_box span { height: 22px; } #select_box select{ width: 100%; height: 30px; } < / style > < / head > < body > < div id = "title" > the world watches < / div > < div id = "box" > < div id = "scale" > < div > < span > 12 < / span > < / div > <div><span>1</span></div> <div><span>2</span></div> <div><span>3</span></div> <div><span>4</span></div> <div><span>5</span></div> <div><span>6</span></div> <div><span>7</span></div> <div><span>8</span></div> <div><span>9</span></div> <div><span>10</span></div> <div><span>11</span></div> </div> <div id="hour"></div> <div id="minute"></div> <div id="second"></div> </div> <div id="current_time_box"> <span id="current_time">--</span> </div> <div id="select_box"> <label> <select onchange="onChangeTimeFunc(value)"> <! -- Eastern time --> <option value="0"> Zero time zone </option> <option value="1"> Eastern one zone </option> <option value="2"> Eastern two zone </option> <option Value ="3"> </option> <option value="4"> </option> <option value="5"> </option> <option value="6"> <option value="7"> Select </option> <option value="8" selected="selected"> Select </option> <option value="9"> Select </option> <option Value ="10"> </option> <option value="12"> </option> <! -- West End time --> <option value="-10"> West End </option> <option value="-9"> West End </option> <option value="-8"> West end </option> <option value="-8" Value ="-7"> </option> <option value="-6"> </option> <option value="-5"> </option> <option value="-4"> </option> <option value="-3"> West zone </option> </select> </label> </div> <script SRC ="https://unpkg.com/dayjs"></script> <script type="text/javascript"> const scaleDivs = document.querySelectorAll("#scale div"); // let timer = null; // for (let I = 0; i < scaleDivs.length; ScaleDivs [I].style. Transform = "rotate(" + I * 30 + "deg)"; scaleDivs[I].transform = "rotate(" + I * 30 + "deg)"; / / solve the problem of scale value shows positive, it is ok to reverse back scaleDivs [I] firstChild. Style.css. Transform = "rotate (" I * 30 + + -" deg) "; } // Get seconds DIV const hourDiv = document.querySelector("#hour"); const minuteDiv = document.querySelector("#minute"); const secondDiv = document.querySelector("#second"); Const currentTimeSpan = document.querySelector("#current_time"); Function onChangeTimeFunc(value) {clearInterval(timer); currentTimeSpan.innerHTML = ''; Const date = getLocalTime(Number(value)); // Set the pointer setpointer (date); // Start timer timer = setInterval(function () {const currentDate = getLocalTime(Number(value)); setPointers(currentDate); }, 1000); } function getLocalTime(I) {const d = new Date(); // Const d = new Date(); Const len = d.gettime (); // Get the number of seconds from January 1, 1970 const len = d.gettime (); // Offset between local time and GMT time const offset = d.gettimezoneoffset () * 60000; Const utcTime = len + offset; return new Date(utcTime + 3600000 * i); } // set pointer function setpointer (date) {let hour = date.gethours () % 12; let minute = date.getMinutes(); let second = date.getSeconds(); second++; if (second === 60) { second = 0; minute++; if (minute === 60) { minute = 0; hour++; if (hour === 13) { hour = 0; }}} / / a circle of 360 degrees, a circle of 60 seconds, every second is 360/60 = 6 degrees secondDiv. Style.css. Transform = "rotate (" + second * 6 +" deg) "; / / a circle of 360 degrees, a circle of 60 points, each of them is 360/60 = 6 minuteDiv. The style.css. Transform = "rotate (" + minute * 6 +" deg) "; // One circle is 360 degrees, one circle is 12 hours, 360/12=30 degrees per second // One hour is 30 degrees, one hour is 60 minutes, Transform = "rotate(" + (hour * 30 + minute * 0.5) + "; hourdiv.style. transform = "rotate(" + (hour * 30 + minute * 0.5) + "; . / / assignment span currentTimeSpan innerHTML = dayjs (date). The format (' MM - DD YYYY - HH: MM: ss "); } // Select onChangeTimeFunc(8) by default; </script> </body> </html>Copy the code

The last

Today is Christmas Eve, I wish you peace and happiness!

Everybody, leave early and leave your footprints. Thank you