This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!
Using native JS, to achieve the compass clock effect
Implementation effect
Implementation approach
- Place the numbers in a circle
- Get the current time and rotate the ring to the horizontal position by an Angle
- Brightens the current time
The idea is simple, but there are a lot of details to consider along the way
The implementation process
Parse a few important parts
- Building HTML framework
Because the number is too large, using JS dynamic generation of numbers
<div class="clock">
<div class=" temp year">
<span></span>
</div>
<div class="temp month"></div>
<div class="temp day"></div>
<div class="temp hour"></div>
<div class="temp minute"></div>
<div class="temp second"></div>
</div>
Copy the code
- Js generating numbers
This is the function I used to generate date and time numbers, and passing 5 arguments is a bit much
The first argument, num, is the end of the loop passed in
The second parameter date: pass in the tag to be generated where, i.e., who put the tag
The third parameter, target, is passed in the unit, time, minute, second, etc
The fourth argument, bool: passed in whether, specifies whether to fill in zeros
The fifth argument origin: pass in its starting point
Due to the performance cost of using DOM operations, there is a lot of adding of DOM nodes, and if you use a simple for loop to generate nodes, you will have to modify the DOM structure several times
To improve performance, you can create a documentFragment that acts as a temporary container and is added to the parent node one last time
function create(num,date,target,bool,origin) {
var fragment = document.createDocumentFragment();
for(var i = origin; i < num ; i ++) {
var j = i;
if(bool){
j = j > 9 ? j : '0' + j;
}
var span = document.createElement('span');
span.appendChild(document.createTextNode(j + target));
fragment.appendChild(span);
}
date.appendChild(fragment);
}
Copy the code
- Show the dial, which generates the circular effect
All the span boxes were positioned together by positioning, the boxes were opened by transfromX as the radius, and the boxes were evenly scattered by rotating each box at an Angle
function rot(target,distance) {
var rotBox = target.children;
for(var i = 0; i < rotBox.length ; i ++ ){ rotBox[i].style.transform ='rotate(' + (360 / rotBox.length ) * i + 'deg)' + 'translateX(' + distance + ') '; }}Copy the code
- Since the page takes time to load, the JS code will not execute immediately and the page will have a blank phase, so add an immediate execute function to render the page as soon as it loads
The implementation code
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: rgb(8.8.8);
color: rgb(92.91.91);
font-size: 18px;
}
.clock {
position: absolute;
left:50%;
top:50%;
width: 1000px;
height: 1000px;
transform: translate(-50%, -50%);
}
.temp {
position: absolute;
top: 0;
width: 1000px;
height: 1000px;
transition: all .5s;
}
/* Position all the spans together */
.temp span{
position: absolute;
left: 50%;
top: 50%;
width: 40px;
height: 20px;
margin-top: -10px;
margin-left: -20px;
}
span {
display: block;
}
/* The current time changes color */
.now {
color: white;
text-shadow: 0 0 10px white;
}
/* Let the year center */
.year span {
font-size: 24px;
width: 90px;
margin-left: -35px;
margin-top: -15px;
}
</style>
</head>
<body>
<div class="clock">
<div class=" temp year">
<span></span>
</div>
<div class="temp month"></div>
<div class="temp day"></div>
<div class="temp hour"></div>
<div class="temp minute"></div>
<div class="temp second"></div>
</div>
<script>
/* Get the element */
/* Create */ with js because the number is too large
var year = document.querySelector('.year');
var month = document.querySelector('.month');
var day = document.querySelector('.day');
var hour = document.querySelector('.hour');
var minute = document.querySelector('.minute');
var second = document.querySelector('.second');
var yearSpan = year.querySelector('span');
/* Create time the penultimate parameter to determine whether to fill in zero */
create(13,month,'month'.false.1);
create(31,day,'day'.false.1);
create(24,hour,'when'.true.0);
create(60,minute,'points'.true.0);
create(60,second,'秒'.true.0);
/* Execute */ immediately
(timer())
/* Get the current time */
setInterval(timer,1000);
/* In a circle */
rot(second,'400px');
rot(minute,'320px');
rot(hour,'240px');
rot(day,'160px');
rot(month,'100px');
/ * * / function
/* Display the dial function */
function rot(target,distance) {
var rotBox = target.children;
for(var i = 0; i < rotBox.length ; i ++ ){ rotBox[i].style.transform ='rotate(' + (360 / rotBox.length ) * i + 'deg)' + 'translateX(' + distance + ') '; }}/* Create too many elements, use the document fragmentation method */
function create(num,date,target,bool,origin) {
var fragment = document.createDocumentFragment();
for(var i = origin; i < num ; i ++) {
var j = i;
if(bool){
j = j > 9 ? j : '0' + j;
}
var span = document.createElement('span');
span.appendChild(document.createTextNode(j + target));
fragment.appendChild(span);
}
date.appendChild(fragment);
}
/* Get time */
function timer() {
var time = new Date(a);var nowYear = time.getFullYear();
var nowMonth = time.getMonth() + 1;
var nowDay = time.getDate();
var nowHour = time.getHours();
var nowMinute = time.getMinutes();
var nowSecond = time.getSeconds();
/* The year is */
yearSpan.innerHTML = nowYear + 'years';
yearSpan.className = 'now';
Rotate the * / / *
var rotateH = nowHour * 15 ;
var rotateM = nowMinute * 6;
var rotateS = nowSecond * 6;
var rotateD = (nowDay - 1) * 12;
var rotateMo = (nowMonth - 1 ) * 30;
second.style.transform = 'rotate(' + (- rotateS) + 'deg' + ') ';
minute.style.transform = 'rotate(' + (- rotateM) + 'deg' + ') ';
hour.style.transform = 'rotate(' + (- rotateH) + 'deg' + ') ';
day.style.transform = 'rotate(' + (- rotateD) + 'deg' + ') ';
month.style.transform = 'rotate(' + (- rotateMo) + 'deg' + ') ';
/* Change the current time style */
clearClass(month)
clearClass(day);
clearClass(hour);
clearClass(minute);
clearClass(second);
month.children[nowMonth - 1].className = 'now';
day.children[nowDay - 1].className = 'now';
hour.children[nowHour].className = 'now';
minute.children[nowMinute].className = 'now';
second.children[nowSecond].className = 'now';
}
/* Clear the style function */
function clearClass(target) {
for(var i = 0; i < target.children.length; i++ ) { target.children[i].className =' '; }}</script>
</body>
</html>
Copy the code