美文网首页
3D翻转焦点图

3D翻转焦点图

作者: TsingXu | 来源:发表于2016-08-20 14:44 被阅读0次

最终要达到的效果如下图:

先做一个小demo,慢慢的来实现最终的效果。
首先先实现如下图效果:

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");

获取行数和列数:

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<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)查看下数组的情况:

接下来设置按钮动作。点击展开,从最后一个 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;

}

改进:

  1. 要设置每个 li 元素显示的图片部分。
  2. 改变按钮点击事件的效果。

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<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);

}

补充另一个问题。如果需要给每个图片添加点击事件,那么以上的代码实现不了。

原因:
因为每一个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翻转焦点图效果就如文章开头那样。结束。

不积跬步无以至千里

相关文章

网友评论

      本文标题:3D翻转焦点图

      本文链接:https://www.haomeiwen.com/subject/jlristtx.html