效果
废话不多说,先上效果图:
这个小项目用到了jquery,目的是为了一些书写的简便
先贴上整体的框架的代码
<div class="clock">
<!-- 时 -->
<div class="flipper">
<div class="gear"></div>
<div class="gear"></div>
<div class="top">
<div class="text">00</div>
</div>
<div class="bottom">
<div class="text">00</div>
</div>
</div>
<!-- 分 -->
<div class="flipper">
<div class="gear"></div>
<div class="gear"></div>
<div class="top">
<div class="text">00</div>
</div>
<div class="bottom">
<div class="text">00</div>
</div>
</div>
<!-- 秒 -->
<div class="flipper">
<div class="gear"></div>
<div class="gear"></div>
<div class="top">
<div class="text">00</div>
</div>
<div class="bottom">
<div class="text">00</div>
</div>
</div>
</div>
复制代码
别看这么长一坨,其实就等同于只有一个显示小时的,其他的直接复制的(小声逼逼)
所需实现的功能
根据上面的效果图,大概能看出我们时钟显示所需要实现的功能
- 整体框架
- 时分秒两边的渐变块状物
- 实时显示时间
- 页面动态翻页效果(根据时间变化使页面翻转)
整体外围框架
最外围的大盒子:有渐变颜色显示(MP4转成jif格式导致画质变差了,但是还是能看出来渐变效果的)
这里我们该用什么去弄盒子边框渐变呢?
这不就是设置盒子的边框阴影嘛,只是弄了个渐变,整那么玄乎干嘛呢?
确实完全正确,用box-shadow就能解决
box-shadow: inset 0 -3px 6px 3px rgba(0, 0, 0, 0.2),
inset 0 4px 8px 3px rgba(0, 0, 0, 0.4),
0 2px 3px 1px rgba(255, 255, 255, 0.3),
0 -2px 4px 4px rgba(56, 56, 61, 0.5);
复制代码
最外围盒子的四个角还带了点弧度:
border-radius: var(--radius);//这里是设置了一个变量,增加了可维护性,到时候直接修改变量的值就狗了,就不需要到处找了
复制代码
整体框架就成了这样(此处忽略里面的6个蛋,这是div盒子里的初始值)
时分秒两边的渐变块状物
最外围的框架就这样搞定了,现在来看看时分秒的大盒子吧
样式是这样的
大家就会说了这不和最外围框架的框架差不多嘛
大致上是一样的,但是还是有些微妙的区别滴,仔细看,有没有一种向内凹的感觉,上下两边是翘出来的,这其实和盒子阴影差不多(小声逼逼)
.top, .bottom{
box-shadow: 0 6px 6px 1px rgba(0, 0, 0, 0.5),
0 2px 2px 1px rgba(255, 255, 255, 0.15);
border-top: 2px solid rgb(102, 103, 110);//边框
border-bottom: 2px solid #000;
}
复制代码
大致效果就成了这样
现在还缺少了各边的那啥(我也不知道该怎么称呼他们….)
我们来分析分析
- 有渐变的
- 有点立体效果(其实立体效果就是渐变搞的鬼)
- 外边框还有描边加粗
.gear{
position: absolute;
top: calc(var(--clockheight) / 3);
width: 12px;
height: calc(var(--clockheight) / 3);
background: linear-gradient(//渐变
to bottom,
#000000 0%,
#666666 17%,
#7f7f7f 52%,
#7f7f7f 52%,
#0c0c0c 53%,
#595959 87%,
#131313 100%
);
outline: 3px solid #000;//描边加粗
z-index: 99;
transform-style: preserve-3d;
transform: translateZ(10px);//向Z轴方向移10px
perspective: 0;
}
复制代码
现在看着就舒服多了
实时显示时间
先获取到容器中的初始值(就是那六个蛋)
myhour = $('.clock .flipper:nth-child(1) div:not(.new) .text')//找到时 这里运用了jquery
myminute = $('.clock .flipper:nth-child(2) div:not(.new) .text')//找到分
mysecond = $('.clock .flipper:nth-child(3) div:not(.new) .text') //找到秒
复制代码
获取时间这不是简简单单嘛,直接
var date = new Date();
复制代码
确实是这样然后就是将时间分成时分秒分别植入到各个部分了,然后还要思考啊,看着图,想呀想….
当时分秒显示的只有一位咋整咧只能01、02、03…这样的放呀,所以获取对应结构再植入相应数字根本行不通。我们就需要做一个简单的判断,判断它到底是个位数还是十位数
获取时间
var date = new Date(); //拿到当前时间
var seconds = date.getSeconds().toString(); //拿到second number不具备length属性
//将时间分离出来,分成时分秒
if(seconds.length == 1){ //如果不用toString()
seconds = '0' + seconds;
}
var minutes = date.getMinutes().toString();
if(minutes.length == 1){
minutes = '0' + minutes;
}
var hour = date.getHours();
if(hour > 12){
hour = hour -12;
}
if(hour == 0){
hour = 12;
}
hour = hour.toString(); //将hour转变为字符串
if(hour.length == 1){
hour = '0' + hour;
}
复制代码
这里是往dom里面设置时间的部分代码(setTime()函数的部分代码)
获取完时分秒后,现在就是考虑将他们植入到相应的位置了。
效果图上还有不停的翻页效果,当翻下来的时候呢,如果翻下来的那一页如果只有一层的话,不可能将时间变化显示显示的那么流畅的,所以我们需要给翻下来的页面植入div以便流畅的变化时间,到时候变化时只用改变相应的层级关系就流畅了
植入时间
//将时间植入到text里面去
function flipNumber(el,newnumber){//el代表flipper
var thisTop =el.find('.top').clone(); //在flipper中找top 多放一份top做动画效果 clone 克隆 原生JS el.getElemntByClassName('top').clone()与el.find('.top') 作用相同
var thisBottom =el.find('.bottom').clone();
thisTop.addClass('new'); //jquery JS中添加类名巨麻烦
thisBottom.addClass('new');
thisBottom.find('.text').text(newnumber);//将test里面的内容改成newnumber里面的内容
el.find('.top').after(thisTop) //找到top同级的thisTop盒子
el.find('.top.new').append(thisBottom)//在同时具有.top.new类名的盒子里添加thisBottom这个盒子
el.addClass('flipping')//给el(flipper)添加一个flipping类名
// el.find('.top.new').find('.text').text(newnumber);
el.find('.top:not(.new)').find('.text').text(newnumber);//找到top中没有new类名的top,然后再在top中将newnumber赋值给text
setTimeout(function () {
el.find('.bottom:not(.new)').find('.text').text(newnumber);
}, 500)// 下面的先不动翻页有时间,所以500ms才显示
}
复制代码
虽然看不出来这里添加盒子后的效果(莫急)
到这里我们就将大部分效果做完了。现在还剩下一个翻页效果还有个实时显示时间了
页面动态翻页效果(根据时间变化使页面翻转)
翻页
翻页咱用CSS中的动画效果来实现
@keyframes rotate {
0% {
/* rotate默认是Z轴 */
transform: rotateX(0deg) translateY(0px);
}
100% {
transform: rotateX(-180deg) translateY(-10px);
}
}
复制代码
实时显示时间
实时显示无非就是循环啦
setTimeout(function () {
setTime();
}, 500);
复制代码
仔细观察观察效果图,我们会发现下半部分是是有一定延迟变化的(虽然上面已经贴出了这一部分的代码,但是我就是还想贴一遍,就是这么任性)
el.find('.bottom:not(.new)').find('.text').text(newnumber);
}, 500)// 下面的先不动翻页有时间,所以500ms才显示
复制代码
现在就剩上半部分的时间显示了,我们上面提到过,如果翻页的那部分只有一个div是不可能将时间变化的那么流畅的,所以这部分一定是多个盒子,一个显示的是上半部分的时间,一个显示的是下半部分的时间,当翻转时,我们只需要改变他们之间的关系就够了(这里我设置的是透明度,所以我只需要改变透明度就ok了)
还是用的CSS动画
@keyframes rotatebottom{
0% {
opacity: 0;//透明度
}
49% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 1;
}
}
复制代码
最后就是考虑循环显示了(这里就是一个递归操作)咱不多说
setTimeout(function () {
setTime();//往dom里面设置时间
}, 500);
复制代码
最后这一步也是最关键的!!!!!
因为我们在植入时间的时候,创建了好几个div,在递归时如果不把这创建的div删除的话(就会创建无数个div),然后崩掉。
所以偶们需要删除掉创建的div
$(".flipper").removeClass("flipping");//找到flipper这个类名,移除掉类名
$(".flipper .new").remove();//找到flipper下的类名为new盒子,然后删除
复制代码
到这里咱就实现了展示的效果图了。
源码已上传至gitee,有需要的自行下载欧