I’m participating in nuggets Creators Camp # 4, click here to learn more and learn together!
Ihope_top.gize. IO /my-demo/dem…
This article has been published to the public account: Baili Qingshan
preface
A few days ago, I found a small case I learned when I started to learn the front end. I use CSS to draw a rotating dial. I don’t know if everyone has written it, as shown in the picture below
Share this little case for you today, and the effect of the original case is completely implemented with CSS, because the clock rotation have rules to follow, just set a timing animation, I in order to simplify the code, and can get the current time, so use js optimization, because the case is very small, so I don’t have frame, the original start directly, Since this simple article is aimed at beginners, it will be explained in more detail
The development of
Initialize the
The first step is to find a folder, create index.html, then introduce a style. CSS and initialize some styles
The dial to make
Now let’s make the dial
panel
The first part is the panel. We only use one node for the HTML part of the panel, and use CSS for the rest
<div id="watch">
<! - dial - >
<div class="frame-face"></div>
</div>
Copy the code
First we give the dial a basic style to determine the basic structure, then add some gradients and shadows to create a little bit of stereo
#watch .frame-face {
position: relative;
width: 30em;
height: 30em;
margin: 2em auto;
border-radius: 15em;
background: -webkit-linear-gradient(top, #f9f9f9.# 666);
background: -moz-linear-gradient(top, #f9f9f9.# 666);
background: linear-gradient(top, #f9f9f9.# 666);
box-shadow: 0.5 em 0.5 em 4em rgba(0.0.0.0.8);
}
Copy the code
Then we used pseudo-class elements to draw a radial gradient to create a sense of hierarchy and make the dial more three-dimensional
#watch .frame-face:before {
content: ' ';
width: 29.4 em;
height: 29.4 em;
border-radius: 14.7 em;
position: absolute;
top:.3em;
left:.3em;
background: -webkit-radial-gradient(ellipse at center, rgba(246.248.249.1) 0%.rgba(229.235.238.1) 65%.rgba(205.212.217.1) 66%.rgba(245.247.249.1) 100%);
background: -moz-radial-gradient(ellipse at center, rgba(246.248.249.1) 0%.rgba(229.235.238.1) 65%.rgba(205.212.217.1) 66%.rgba(245.247.249.1) 100%);
background: radial-gradient(ellipse at center, rgba(246.248.249.1) 0%.rgba(229.235.238.1) 65%.rgba(205.212.217.1) 66%.rgba(245.247.249.1) 100%);
}
Copy the code
This still doesn’t look good, so let’s add a pseudo-class to make the main panel of the dials look more realistic through the contrast effects of shadows and gradients
#watch .frame-face:after {
content: ' ';
width: 28em;
height: 28em;
border-radius: 14.2 em;
position: absolute;
top:.9em;
left:.9em;
box-shadow: inset rgba(0.0.0.2).2em .2em 1em;
border:.1em solid rgba(0.0.0.2);
background: -webkit-linear-gradient(top, #fff.#ccc);
background: -moz-linear-gradient(top, #fff.#ccc);
background: linear-gradient(top, #fff.#ccc);
}
Copy the code
calibration
There are small scale points around the dial, so that we can know the specific time, here we set 60 scale points for the dial, dom node we first write a scale point container, because there are too many scale points, we will use JS generation later
<! - scale - >
<ul id="minute-marks"></ul>
Copy the code
Let’s do a basic style
#minute-marks li {
display: block;
width: 0.2 em;
height: 0.6 em;
background: # 929394;
position: absolute;
top: 50%;
left: 50%;
margin: -0.4 em 0 0 -0.1 em;
}
Copy the code
Here, we adjust the position of each scale point by transform to achieve the corresponding effect. The scale of the hour point is more prominent than the others, so we need to find the scale of the hour point and add a prominent effect to it
window.onload = function () {
// Generates a scale
let markWrap = document.getElementById('minute-marks')
for (let index = 0; index < 60; index++) {
let markItem = document.createElement('li')
markItem.style.cssText = "transform:rotate(" + index * 6 + "Deg) translateY em (12.7)";
if (index % 5= =0) {
markItem.style.width = "0.3 em";
markItem.style.height = "1em";
}
markWrap.appendChild(markItem)
}
}
Copy the code
Here we can also consider adding some graduated digital marks
<ul id="digits">
<li>3</li>
<li>6</li>
<li>9</li>
<li>12</li>
</ul>
Copy the code
#digits {
width: 30em;
height: 30em;
border-radius: 15em;
position: absolute;
top: 0;
left: 50%;
margin-left: -15em;
}
#digits li {
font-size: 1.6 em;
display: block;
width: 1.6 em;
height: 1.6 em;
position: absolute;
top: 50%;
left: 50%;
line-height: 1.6 em;
text-align: center;
margin: -.8em 0 0 -.8em;
font-weight: bold;
}
#digits li:nth-child(1) {
transform: translate(7em.0)}#digits li:nth-child(2) {
transform: translate(0.7em)}#digits li:nth-child(3) {
transform: translate(-7em.0)}#digits li:nth-child(4) {
transform: translate(0, -7em)}Copy the code
Here we will directly add the center point of the axis where the pointer rotates
#digits:before {
content:' ';
width:1.6 em;
height:1.6 em;
border-radius:.8em;
position:absolute;
top:50%; left:50%;
margin: -.8em 0 0 -.8em;
background:# 121314;
}
#digits:after {
content:' ';
width:4em;
height:4em;
border-radius:2.2 em;
position:absolute;
top:50%; left:50%;
margin: -2.1 em 0 0 -2.1 em;
border:.1em solid #c6c6c6;
background:-webkit-radial-gradient(ellipse at center, rgba(200.200.200.0), rgba(190.190.190.1) 90%.rgba(130.130.130.1) 100%);
background:-moz-radial-gradient(ellipse at center, rgba(200.200.200.0), rgba(190.190.190.1) 90%.rgba(130.130.130.1) 100%);
background:radial-gradient(ellipse at center, rgba(200.200.200.0), rgba(190.190.190.1) 90%.rgba(130.130.130.1) 100%);
}
Copy the code
Pointer to the development
Next we carry on the development of dial pointer
Here we prepare three DOM, namely hour hand, minute hand and second hand
<! - pointer -- -- >
<div class="hours-hand"></div>
<div class="minutes-hand"></div>
<div class="seconds-hand"></div>
Copy the code
In the same development
The main part of the hour hand is divided into a pin and a tip. The pin has a rectangle, and the tip can be composed of a semicircle and a triangle
#watch .hours-hand {
width:.8em;
height:7em;
border-radius:0 0 .9em .9em;
background:# 232425;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -.8em -.4em;
box-shadow:# 232425 0 0 2px;
transform-origin:0.4 em 6.2 em;
transform:rotate(-25deg);
}
#watch .hours-hand:before {
content:' ';
background:inherit;
width:1.8 em;
height:.8em;
border-radius:0 0 .8em .8em;
box-shadow:# 232425 0 0 1px;
position:absolute;
top: -.7em; left: -.5em;
}
#watch .hours-hand:after {
content:' ';
width:0; height:0;
border:.9em solid # 232425;
border-width:0 .9em 2.4 em .9em;
border-left-color:transparent;
border-right-color:transparent;
position:absolute;
top: -3.1 em; left: -.5em;
}
Copy the code
Note that the transform-origin property is used to set the rotate reference point for the dom. The dom will rotate at this point, or at its own center if not
Minute hand development
To make a distinction, let’s give a different style for each pointer, a rectangle for the minute hand
#watch .minutes-hand {
width:.8em;
height:12.5 em;
border-radius:.5em;
background:# 343536;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -1.5 em -.4em;
box-shadow:# 343536 0 0 2px;
transform-origin:0.4 em 11em;
}
Copy the code
The second hand development
The second hand is made up of three parts, a rounded rectangle at the tail, a circle that overlaps the center point, and a long tip, which can also be made with rounded corners
/ * the second hand * /
#watch .seconds-hand {
width:.2em;
height:14em;
border-radius:.1em .1em 0 0/10em 10em 0 0;
background:#c00;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -2em -.1em;
box-shadow:rgba(0.0.0.8) 0 0 .2em;
transform-origin:0.1 em 12em;
}
#watch .seconds-hand:after {
content:' ';
width:1.4 em;
height:1.4 em;
border-radius:.7em;
background:inherit;
position:absolute;
left: -.65em; bottom:1.35 em;
}
#watch .seconds-hand:before {
content:' ';
width:.8em;
height:3em;
border-radius:.2em .2em .4em .4em/.2em .2em 2em 2em;
box-shadow:rgba(0.0.0.8) 0 0 .2em;
background:inherit;
position:absolute;
left: -.35em; bottom: -3em;
}
Copy the code
Let the needle spin
We have developed the basic styles of the dial and pointer, and now we are going to let the needle rotate. When we write CSS, we already know that the position of the pointer is rotated by a certain Angle by the transform, so we need to move the pointer regularly by changing the Angle
setInterval(function () {
var time = new Date(a);var hour = time.getHours()
var minute = time.getMinutes();
var second = time.getSeconds();
var hournum;
if (hour > 12) {
hournum = ((hour - 12) + minute / 60) * 30;
} else {
hournum = (hour + minute / 60 * 100) * 30;
}
var minnum = (minute + second / 60) * 6 + second / 60;
var sennum = second * 6;
document.getElementsByClassName("hours-hand") [0].style.transform = "rotate(" + hournum + "deg)"
document.getElementsByClassName("minutes-hand") [0].style.transform = "rotate(" + minnum + "deg)"
document.getElementsByClassName("seconds-hand") [0].style.transform = "rotate(" + sennum + "deg)"
}, 1000);
Copy the code
And you’re done
Digital table development
The hands are also very intuitive, but they are always not as intuitive and accurate as the numbers, so we can add a digital dial. Digital dial is more simple, we get the current minute seconds, regular refresh is good, here needs the host column dial on the level, can not cover the pointer
<! -- Digital dial -->
<div class="digital-wrap">
<ul class="digit-hours"></ul>
<ul class="digit-minutes"></ul>
<ul class="digit-seconds"></ul>
</div>
Copy the code
#watch .digital-wrap {
width:9em;
height:3em;
border:.1em solid # 222;
border-radius:.2em;
position:absolute;
top:50%; left:50%;
margin:3em 0 0 -4.5 em;
overflow:hidden;
background:#4c4c4c;
background:-webkit-linear-gradient(top, #4c4c4c.#0f0f0f);
background:-moz-linear-gradient(top, #4c4c4c.#0f0f0f);
background:-ms-linear-gradient(top, #4c4c4c.#0f0f0f);
background:-o-linear-gradient(top, #4c4c4c.#0f0f0f);
background:linear-gradient(to bottom, #4c4c4c.#0f0f0f);
}
#watch .digital-wrap ul {
float:left;
width:2.9 em;
height:3em;
border-right:.1em solid # 000;
color:#ddd;
font-family:Consolas, monaco, monospace;
text-align: center;
line-height: 3em;
}
#watch .digital-wrap ul:last-child {width: 3em; border:none }
Copy the code
// attach the pointer above to rotate js
if(hour<10){
hour="0"+parseInt(hour);
}
if(minute<10){
minute="0"+parseInt(minute);
}
if(second<10){
second="0"+parseInt(second);
}
document.getElementsByClassName("digit-hours") [0].innerHTML=hour;
document.getElementsByClassName("digit-minutes") [0].innerHTML=minute;
document.getElementsByClassName("digit-seconds") [0].innerHTML=second;
Copy the code
And you’re done.