今天看到一篇 CSS动画篇之炫酷时钟之时钟墙, 是由108个小的时钟,画出大的时钟,本来是一分钟旋转一次,现在改成每秒旋转一次。 上效果图:
这个效果图共有 6行 18列, 每一个格子都是由两个指针组成的小时钟。
实现思路:
时钟默认状态是这种情况
所以用不到的格子,显示的就是这种状态。 分和秒之间的“冒号”上下方就是这种。
组成数字所需要的基本元素:
只要控制好每个小时钟,按照一定的规律旋转即可。
代码实现:
HTML代码
<div class="display">
<div class="digit">
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
</div>
<div class="digit">
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
</div>
<div class="digit separator">
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
</div>
<div class="digit">
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
</div>
<div class="digit">
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
<div class="clock"></div>
</div>
</div>
CSS代码
html, body {
height: 100%;
}
body {
padding: 0;
margin: 0;
background-color: #333;
background: radial-gradient(#fff, #eee);
display: flex;
}
.display {
flex: 1;
display: grid;
grid-gap: 8px;
max-width: 85em;
grid-template-columns: 1fr;
padding: 2rem;
box-shadow: 0 4px 15px -1px rgba(0, 0, 0, 0.1);
margin: auto;
background-color: #f7f7f7;
background: linear-gradient(to bottom, #fff, #f5f5f5);
}
@media (min-width: 20em) {
.display {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 40em) {
.display {
grid-template-columns: repeat(2, 2fr) 1fr repeat(2, 2fr);
}
}
.digit {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 8px;
grid-row-gap: 4px;
}
.digit.separator {
display: none;
}
@media (min-width: 40em) {
.digit.separator {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
.clock {
border-radius: 50%;
padding-top: 100%;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
position: relative;
background-color: #fff;
}
.clock:nth-child(2n+1) {
transition-delay: 0.1s;
}
.clock:before, .clock:after {
content: "";
display: inline-block;
height: 45%;
width: 4px;
background-color: #444;
position: absolute;
left: 50%;
top: 8%;
margin-left: -2px;
transform-origin: 2px 100%;
transition: all 0.8s cubic-bezier(0.5, 0, 0.5, 1);
}
.clock.pos1:before {
transform: rotate(90deg);
}
.clock.pos2:before {
transform: rotate(180deg);
}
.clock.pos2:after {
transform: rotate(90deg);
}
.clock.pos3:before {
transform: rotate(180deg);
}
.clock.pos3:after {
transform: rotate(270deg);
}
.clock.pos4:before {
transform: rotate(270deg);
}
.clock.pos4:after {
transform: rotate(360deg);
}
.clock.pos5:before {
transform: rotate(360deg);
}
.clock.pos5:after {
transform: rotate(540deg);
}
.clock.pos6:before {
transform: rotate(450deg);
}
.clock.pos6:after {
transform: rotate(630deg);
}
JS代码
var groups = document.querySelectorAll('.digit')
function setNumber(group, number) {
var clocks = group.children;
var numbers = [
'266352355555555551451664',
'263013500550055024131664',
'266316352645526451631664',
'266316352645163526451664',
'232355555145163500550014',
'266352645163163526451664',
'266352645163523551451664',
'266316350055005500550014',
'266352355145523551451664',
'266352355145163500550014'
]
for(var i = 0; i < 24; i++) {
clocks[i].classList.value = 'clock pos' + numbers[number][i]
}
}
function setSeparator(group) {
var pos = '002314231400';
for(var i = 0; i<12; i++) {
group.children[i].classList.value = 'clock pos' + pos[i];
}
}
function pad(number, digits) {
number = parseInt(number, 10)
return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;
}
function writeTime() {
var now = new Date();
var hour = now.getHours().toString();
var minute = now.getMinutes().toString();
var second = now.getSeconds().toString();
// var number = pad(hour,2) + pad(minute, 2);
var number = pad(minute,2) + pad(second, 2);
setNumber(groups[0], number[0]);
setNumber(groups[1], number[1]);
setNumber(groups[3], number[2]);
setNumber(groups[4], number[3]);
}
function runEveryMinute(f) {
var now = new Date();
setTimeout(function(){
f();
setInterval(f, 1000);
}, 1000);
}
setTimeout(function() {
setSeparator(groups[2]);
runEveryMinute(writeTime);
writeTime();
}, 200);
拆解:
numbers数组放置了0-9这10个数字, 怎么组成的。
比如数字 0的效果图如下:
对比 这个图
就会得出:
所以numbers数组中0的编码就是:
'266352355555555551451664'
其他的数字同理。
方法 runEveryMinute() 是控制每秒还是每分钟去执行。
方法 writeTime() 是获取显示的时分秒,就是获取到底要显示的数字。
源代码是每分钟执行一次,各个小时钟旋转的都很慢, 所以还修改了CSS的代码:
/**修改前**/
transition: all 10s cubic-bezier(0.5, 0, 0.5, 1);
/**修改后**/
transition: all 0.8s cubic-bezier(0.5, 0, 0.5, 1);
想要每分钟动画的源代码,请留言。 也可以自行动手修改。