最终要达到的效果如下图:
先做一个小demo,慢慢的来实现最终的效果。
首先先实现如下图效果:
html模板:
css:
body,ul{ margin: 0; padding: 0; }
li{ list-style: none; }
.list{ width: 600px; height: 420px; margin: 50px auto; }
.list li{ width: 58px; height: 58px; border: 1px solid #fff;
float: left; background: red; }
获取对象:
var oList = document.getElementById("list");
var aLi = oList.getElementsByTagName("li");
var aInput = document.getElementsByTagName("input");
获取行数和列数:
var iRows = oList.offsetHeight/aLi[0].offsetHeight;
var iCols = aLi.length/iRows;
可以建立一个坐标,赋予 每个 li 元素 x 和 y 坐标值。
编写 setXy 函数(作用:返回一个存储每个li元素及坐标):
function setXy(objs,iRows,iCols){
var arr = [];
for(var i=0; i
用console.log(oXY)查看下数组的情况:
接下来设置按钮动作。点击展开,从最后一个 li 元素开始往前执行变换。
aInput[0].onclick=function(){
tab(oXY,iRows-1,iCols-1,function(){
this.style.background="yellow";
},50,-1,-1);
}
其中的 tab函数 如下:
function tab(arr,x,y,fn,iDelay,iSpeedX,iSpeedY){
if(!arr[x] || !arr[x][y]){
return;
}
if(fn){
fn.call(arr[x][y]);
clearTimeout(arr[x][y].timer);
arr[x][y].timer = setTimeout(function(){
tab(arr,x+iSpeedX,y,fn,iDelay,iSpeedX,iSpeedY)
tab(arr,x,y+iSpeedY,fn,iDelay,iSpeedX,iSpeedY)
},iDelay);
}
}
函数中通过递归来实现循环每个 li 元素来执行变换。
同理,重置按钮的动作为:
aInput[1].onclick=function(){
tab(oXY,0,0,function(){
this.style.background="red";
},50,1,1);
}
那么,这第一个简单的demo结束。
第二个demo
css:
body,ul{ margin: 0; padding: 0; }
li{ list-style: none; }
.list{ width: 570px; height: 420px; margin: 50px auto;
-webkit-perspective:500px; -webkit-transform-style: preserve-3d;}
.list li{ width: 55px; height: 58px; border: 1px solid rgba(0,0,0,0);
float: left; background: url(images/1.jpg) no-repeat;
background-origin: border-box;
transition:0.5s background, 0.5s border,0.5s box-shadow,
2s 0.3s -webkit-transform,2s 0.3s opacity;
}
改进:
- 要设置每个 li 元素显示的图片部分。
- 改变按钮点击事件的效果。
setXy函数改进:
展开按钮事件:
同理,重置按钮事件:
aInput[1].onclick=function(){
tab(oXY,0,0,function(){
with(this.style){
transition="0.5s background,1s border,1s box-shadow,2s -webkit-transform,2s opacity";
borderColor = "rgba(0,0,0,0)";
boxShadow = "0 0 0 blue";
WebkitTransform = "translate(0,0) rotateX(0deg) rotateY(0deg)";
opacity = 1;
}
},50,1,1);
}
效果如下:
第二个demo结束。
正式效果开始
html模板
css代码
在之前的demo基础上稍作修改;
获取元素和行数列数:
var oList = document.getElementById("wrap");
var aUl = oList.getElementsByTagName("ul");
var aInput = document.getElementsByTagName("input");
var iRows = oList.offsetHeight/aUl[0].children[0].offsetHeight;
var iCols = aUl[0].children.length/iRows;
设置每张图片及每个 ul 元素的层级关系,并用一个数组来存储坐标:
for(var i =0; i
通过console.log(oXY)查看下:
修改按钮事件来切换图片。
同理,另一个按钮事件:
aInput[0].onclick=function(){
if(inow <= 0){
return;
}
inow--;
aUl[inow].style.visibility="visible";
aUl[inow].children[0].removeEventListener("webkitTransitionEnd",end,false);
tab(oXY[inow],0,0,function(){
with(this.style){
transition="0.5s background,1s border,1s box-shadow,1s -webkit-transform,1s opacity";
borderColor = "rgba(0,0,0,0)";
boxShadow = "0 0 0 blue";
WebkitTransform = "translate(0,0) rotateX(0deg) rotateY(0deg)";
opacity = 1;
}
},50,1,1);
}
补充另一个问题。如果需要给每个图片添加点击事件,那么以上的代码实现不了。
原因:
因为每一个ul元素只是将opacity值改了才不显示的,并没有清除它的占位。
解决:
当每张图片结束的动画后,将visibility值改为hidden。
需要显示时在改回来为visible。
添加了事件监听,在最后一个li元素执行完动画后,执行 end 函数。
其中, end 函数如下:
function end(e){
//console.log(e,e.type,e.propertyName);
if(e.propertyName == "transform"){
this.parentNode.style.visibility="hidden";
}
}
3D翻转焦点图效果就如文章开头那样。结束。
不积跬步无以至千里