最終要達(dá)到的效果如下圖:
先做一個小demo撩嚼,慢慢的來實(shí)現(xiàn)最終的效果。
首先先實(shí)現(xiàn)如下圖效果:
html模板:
<input type="button" value="展開">
<input type="button" value="重置">
<ul class="list" id="list">
<li></li>
</ul>
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");
獲取行數(shù)和列數(shù):
var iRows = oList.offsetHeight/aLi[0].offsetHeight;
var iCols = aLi.length/iRows;
可以建立一個坐標(biāo),賦予 每個 li 元素 x 和 y 坐標(biāo)值。
編寫 setXy 函數(shù)(作用:返回一個存儲每個li元素及坐標(biāo)):
function setXy(objs,iRows,iCols){
var arr = [];
for(var i=0; i<iRows; i++){
var arr2 = [];
for(var j=0; j<iCols; j++){
objs[i*iCols+j].yIndex = j;
objs[i*iCols+j].xIndex = i;
arr2.push(objs[i*iCols+j]);
}
arr.push(arr2);
}
return arr;
}
用console.log(oXY)查看下數(shù)組的情況:
接下來設(shè)置按鈕動作。點(diǎn)擊展開岳遥,從最后一個 li 元素開始往前執(zhí)行變換。
aInput[0].onclick=function(){
tab(oXY,iRows-1,iCols-1,function(){
this.style.background="yellow";
},50,-1,-1);
}
其中的 tab函數(shù) 如下:
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);
}
}
函數(shù)中通過遞歸來實(shí)現(xiàn)循環(huán)每個 li 元素來執(zhí)行變換裕寨。
同理寒随,重置按鈕的動作為:
aInput[1].onclick=function(){
tab(oXY,0,0,function(){
this.style.background="red";
},50,1,1);
}
那么,這第一個簡單的demo結(jié)束帮坚。
第二個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;
}
改進(jìn):
- 要設(shè)置每個 li 元素顯示的圖片部分妻往。
- 改變按鈕點(diǎn)擊事件的效果。
setXy函數(shù)改進(jìn):
展開按鈕事件:
同理试和,重置按鈕事件:
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結(jié)束讯泣。
正式效果開始
html模板
css代碼
在之前的demo基礎(chǔ)上稍作修改;
獲取元素和行數(shù)列數(shù):
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;
設(shè)置每張圖片及每個 ul 元素的層級關(guān)系,并用一個數(shù)組來存儲坐標(biāo):
for(var i =0; i<aUl.length; i++){
var aLi = aUl[i].getElementsByTagName("li");
aUl[i].style.zIndex = aUl.length - i;
oXY.push(setXy(aLi,iRows,iCols));
}
通過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);
}
補(bǔ)充另一個問題好渠。如果需要給每個圖片添加點(diǎn)擊事件,那么以上的代碼實(shí)現(xiàn)不了节视。
原因:
因?yàn)槊恳粋€ul元素只是將opacity值改了才不顯示的拳锚,并沒有清除它的占位。
解決:
當(dāng)每張圖片結(jié)束的動畫后寻行,將visibility值改為hidden霍掺。
需要顯示時在改回來為visible。
添加了事件監(jiān)聽拌蜘,在最后一個li元素執(zhí)行完動畫后杆烁,執(zhí)行 end 函數(shù)。
其中简卧, end 函數(shù)如下:
function end(e){
//console.log(e,e.type,e.propertyName);
if(e.propertyName == "transform"){
this.parentNode.style.visibility="hidden";
}
}
3D翻轉(zhuǎn)焦點(diǎn)圖效果就如文章開頭那樣兔魂。結(jié)束。
不積跬步無以至千里