翻页时钟的实现
今天在掘金上看到一篇实现翻页时钟的文章,看完后收获很大。作者Mr_兔子先生,链接:https://juejin.cn/post/6844904003889790983。
他的思路是利用伪类元素实现,这样减少了HTML的结构
<div class="flip" id="flip">
<div class="digital front" data-number="0"></div>
<div class="digital back" data-number="1"></div>
</div>
具体样式如下:
/* 最外层样式 */
.flip {
margin: 50px auto;
position: relative;
width: 60px;
height: 100px;
line-height: 100px;
border: solid 1px #000;
border-radius: 10px;
background-color: #fff;
font-size: 66px;
color: #fff;
box-shadow: 0 0 6px rgba(0, 0, 0, .5);
box-sizing: border-box;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
}
/* 设置前后伪元素通用样式 */
.flip .digital::before,
.flip .digital::after {
content: attr(data-number);
position: absolute;
left: 0;
right: 0;
background: #000;
overflow: hidden;
}
/* 设置上部分位置和盒子圆角,添加中间间隔线 */
.flip .digital::before {
top: 0;
bottom: 50%;
border-radius: 10px 10px 0 0;
border-bottom: solid 1px #666;
}
/* 设置下部分位置和盒子圆角 */
.flip .digital::after {
top: 50%;
bottom: 0;
border-radius: 0 0 10px 10px;
line-height: 0;
}
实现后的效果:

原先作者是给0-9的css样式添加content,这里我在html上添加了data-number属性进行了改进,然后在css用了attr()可以引用,这样减少了代码量。关于attr的用法可以在MDN上查阅。
然后是添加动画效果。

这里我直接拿作者的图来展示层级关系。
比如是向下翻,0到1, 那么0的上部分层级要高于1的下部分
不设置z-index的话值默认为auto,和父级同层,所以可以不设置也可以。
/*向下翻*/
.flip.down .front:before {
z-index: 3;
}
.flip.down .back:after {
z-index: 2;
transform-origin: 50% 0%;
transform: perspective(160px) rotateX(180deg);
}
给需要翻滚的伪元素添加层级,并且以上一张的中心为旋转点,将下部分翻转,perspective属性我暂时还没搞懂。
然后添加动画效果
.flip.down.go .front:before {
transform-origin: 50% 100%;
animation: frontFlipDown 0.6s ease-in-out both;
}
.flip.down.go .back:after {
animation: backFlipDown 0.6s ease-in-out both;
}
@keyframes frontFlipDown {
0% {
transform: perspective(160px) rotateX(0deg);
}
100% {
transform: perspective(160px) rotateX(-180deg);
}
}
@keyframes backFlipDown {
0% {
transform: perspective(160px) rotateX(180deg);
}
100% {
transform: perspective(160px) rotateX(0deg);
z-index: 3;
}
}
然后给#flip添加go的class,就可以看到向下翻页的效果。
除了修改z-index也可以使用backface-visibility: hidden;来隐藏上半部纸片。
.flip.down.go .front:before {
transform-origin: 50% 100%;
animation: frontFlipDown 0.6s ease-in-out both;
+ backface-visibility: hidden;
}
添加JS逻辑
<script>
var flip = document.getElementById('flip')
var backNode = document.querySelector('.back')
var frontNode = document.querySelector('.front')
var btn1 = document.getElementById('btn1')
btn1.onclick = flipUp
var count = 0
var isFlipping = false
function flipUp() {
if (isFlipping) {
return false
}
frontNode.setAttribute('data-number', count)
var nextCount = count >= 9 ? 0 : (count + 1)
backNode.setAttribute('data-number', nextCount)
flip.setAttribute('class', 'flip down go')
isFlipping = true
setTimeout(function() {
// 去掉go
flip.setAttribute('class', 'flip down')
// 将翻转态设置为false
isFlipping = false
// 设置前牌文字为+1后的数字
frontNode.setAttribute('data-number', nextCount)
// 更新当前文字
count = nextCount
}, 1000)
}
</script>

浙公网安备 33010602011771号