昨天做了一道运用CSS3和JS完成的3D折纸效果的功能,今天来总结一下:
惯例,先上效果图。
从图上可以看出当我点击按钮的时候,导航有一个从里到外的一个展开过程。同理,当我再次点击的时候同样也会有一个由外到里的收缩过程。就感觉有一种折叠起来的效果。
下面就是我敲的代码。
CSS:
<style>
*{
margin: 0;
}
@-webkit-keyframes open{
0%{
-webkit-transform: rotateX(-120deg);
}
25%{
-webkit-transform: rotateX(30deg);
}
50%{
-webkit-transform: rotateX(-15deg);
}
75%{
-webkit-transform: rotateX(8deg);
}
100%{
-webkit-transform: rotateX(0deg);
}
}
@-webkit-keyframes close{
0%{
-webkit-transform: rotateX(0deg);
}
100%{
-webkit-transform: rotateX(-120deg);
}
}
#wrap{
width: 160px;
margin: 30px auto;
position: relative;
-webkit-perspective: 800px;
}
#wrap h2{
height: 40px;
background: red;
color: #fff;
text-align: center;
position: relative;
z-index: 10;
}
#wrap div{
position: absolute;
top: 32px;
width: 100%;
left: 0;
-webkit-transform-style: preserve-3d;
-webkit-transform-origin:top;
-webkit-transform: rotateX(-120deg);
z-index: 1;
}
#wrap span{
display: block;
height: 30px;
background: greenyellow;
color: #fff;
box-shadow:inset 0 0 0 20px rgba(0,0,0,1);
transition: 1s;
}
#wrap>div{
top: 40px;
}
#wrap .show{
-webkit-animation: 1.2s open;
-webkit-transform: rotateX(0deg);
}
#wrap .hide{
-webkit-animation: 0.8s close;
-webkit-transform: rotateX(-120deg);
}
#wrap .show>span{
box-shadow:inset 0 0 0 20px rgba(0,0,0,0);
}
</style>
HTML:
<button id="btn">按钮</button>
<div id="wrap">
<h2>我是标题</h2>
<div>
<span>选项1</span>
<div>
<span>
选项2
</span>
<div>
<span>
选项3
</span>
<div>
<span>
选项4
</span>
<div>
<span>选项5</span>
<div>
<span>选项6</span>
<div>
<span>选项7</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
这里的HTML布局我采用了盒子套盒子的方式,因为这样更简单。
JS:
<script>
var oBtn = document.getElementById("btn")
var oWrap = document.getElementById("wrap")
var aDiv = oWrap.getElementsByTagName("div")
var delay = 200
var oTimer = null
var onOff = true
var i = 0
oBtn.onclick = function(){
if(oTimer){
return
}
if(onOff){
i = 0
oTimer = setInterval(function(){
aDiv[i].className = "show"
i++
if(i==aDiv.length){
clearInterval(oTimer)
oTimer = null
onOff = false
}
},delay)
}else {
i = aDiv.length-1
oTimer = setInterval(function(){
aDiv[i].className = "hide"
i--
if(i<0){
clearInterval(oTimer)
oTimer = null
onOff = true
}
},delay)
}
}
</script>
javascript代码中,第一个判断条件是为了反止重复点击按钮,如果当前的定时器正在执行,就返回。
第二个判断条件中 i=0 是因为setInterval会产生异步。后果是当你点击按钮,导航展开后,无法再收回去。