简单CSS3+JQ实现图片的3D翻转

没想到刚开始没两天就突然断了。还是要时刻鞭策自己啊。

主要实现效果:鼠标从不同的方向进入图片,图片所在的正方体就会以此方向翻转,显示文字介绍。

效果如下图


此处的正方体只是形象的比喻方便理解。

如下图为计算机的坐标系,文字介绍所在块(后面简称B)与图片块(后面简称A)放于同一平面,但在Z轴上相差2px。

A与B被包在块C之中。


1. 图片旋转

当鼠标从上侧进入时,思路是先将后侧的B向上移动自身长度的距离,然后向上绕y轴向屏幕内侧旋转90度,得到A与B垂直的效果,即A仍在xoy平面,而B在yoz平面(具体什么样子,就不画图了。实在是画出来太难看了。)此时,若直接旋转C,就可以达到同时旋转A与B的效果,让C向下绕y轴向屏幕内侧旋转90度,B就会旋转到xoy平面,平行于屏幕,A就会旋转到yoz平面,垂直于屏幕。

当鼠标从其他三个方向进入时的思路与上侧进入的思路相类似,只是方向不同。

2. 鼠标进入方向的确定

当明确了A与B的旋转之后,就要考虑如何获取鼠标是从哪个方向进入的了。

首先,我们重新创建一个坐标轴,以图片即A的中心为坐标原点,如下图所示。


然后我们只需要知道鼠标当前的坐标在我们的新坐标系中的位置即可。

var width,//图片宽度
    height,//图片高度
    left,//图片在默认坐标系中的x偏移量
    top;//图片在默认坐标系中的y偏移量
x = e.pageX - left - width / 2;
y = e.pageY - top - height / 2;

知道了鼠标在新坐标系中的位置后,接下来就需要计算鼠标进入的方向了。

d=(Math.round(((Math.atan2(y,x)*(180/Math.PI))+180)/90)+3)%4;

Math.atan2(y,x) //返回x轴到(x,y)的角度的弧度值
(Math.atan2(y,x)*(180/Math.PI) //将弧度值转换成角度
((Math.atan2(y,x)*(180/Math.PI))+180)//加180是为了将0度转换到x轴负半轴使角度看起来方便
((Math.atan2(y,x)*(180/Math.PI))+180)/90//除以90会得到一个0-4之间的浮点数
Math.round(((Math.atan2(y,x)*(180/Math.PI))+180)/90)//此操作将浮点数转换成正整数,此时还不能直接用,是因为此时的数字仍然表示的90度的范围,而不是某一方向
Math.round(((Math.atan2(y,x)*(180/Math.PI))+180)/90)%4//此操作将数字转换成了专指某一方向,0-左,1-上,2-右,3-下

解决了这个问题,剩下的就是简单的DOM操作了。下面附上源码。

1. demo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片翻转</title>
    <link rel="stylesheet" href="demo.css">
</head>
<body>
<div class="wrapper">
    <ul>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
        <li>
            <div class="picBox">
                <div class="show">
                    <img src="./img/pic1.png" alt="">
                </div>
                <div class="hide">
                    <h3>这是一段介绍</h3>
                </div>
            </div>
        </li>
    </ul>
</div>
<script src="jquery.js"></script>
<script src="demo.js"></script>
</body>
</html>

2. demo.css

*{
    margin: 0;
    padding: 0;
    list-style: none;
}
body{
    background-color: #f1e1ff;
}
.wrapper{
    margin: 80px auto;
    width: 900px;
}
.wrapper li{
    position: relative;
    display: inline-block;
    width: 180px;
    height: 180px;
    margin: 5px;
    perspective: 300px;
}
.picBox{
    transform-style: preserve-3d;
    animation: 200ms ease-out 0ms 1 normal forwards;
    transform-origin: 50% 50% -90px;
}
.picBox,
.hide,
.show{
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
}
.hide{
    background-color: #000;
    color: #fff;
    line-height: 180px;
    text-align: center;
    transform: translate3d(0,0,-1px);
}

/*top进入*/
.out-top .hide,
.in-top .hide{
    transform-origin: 0% 100%;
    transform: translate3d(0,-100%,0) rotate3d(1,0,0,90deg);
}
.in-top .picBox{
    animation-name: in-top;
}
.out-top .picBox{
    animation-name: out-top;
}
@keyframes in-top {
    form {transform: rotate3d(0,0,0,0deg)}
    to {transform: rotate3d(-1,0,0,90deg)}
}
@keyframes out-top {
    form {transform: rotate3d(-1,0,0,90deg)}
    to {transform: rotate3d(0,0,0,0deg)}
}

/*right进入*/
.out-right .hide,
.in-right .hide{
    transform-origin: 0% 0%;
    transform: translate3d(100%,0,0) rotate3d(0,1,0,90deg);
}
.in-right .picBox{
    animation-name: in-right;
}
.out-right .picBox{
    animation-name: out-right;
}
@keyframes in-right {
    form {transform: rotate3d(0,0,0,0deg)}
    to {transform: rotate3d(0,-1,0,90deg)}
}
@keyframes out-right {
    form {transform: rotate3d(0,-1,0,90deg)}
    to {transform: rotate3d(0,0,0,0deg)}
}

/*bottom进入*/
.out-bottom .hide,
.in-bottom .hide{
    transform-origin: 0% 0%;
    transform: translate3d(0,100%,0) rotate3d(-1,0,0,90deg);
}
.in-bottom .picBox{
    animation-name: in-bottom;
}
.out-bottom .picBox{
    animation-name: out-bottom;
}
@keyframes in-bottom {
    form {transform: rotate3d(0,0,0,0deg)}
    to {transform: rotate3d(1,0,0,90deg)}
}
@keyframes out-bottom {
    form {transform: rotate3d(1,0,0,90deg)}
    to {transform: rotate3d(0,0,0,0deg)}
}

/*left进入*/
.out-left .hide,
.in-left .hide{
    transform-origin: 100% 0%;
    transform: translate3d(-100%,0,0) rotate3d(0,-1,0,90deg);
}
.in-left .picBox{
    animation-name: in-left;
}
.out-left .picBox{
    animation-name: out-left;
}
@keyframes in-left {
    form {transform: rotate3d(0,0,0,0deg)}
    to {transform: rotate3d(0,1,0,90deg)}
}
@keyframes out-left {
    form {transform: rotate3d(0,1,0,90deg)}
    to {transform: rotate3d(0,0,0,0deg)}
}

3. demo.js

var oLi=$('li');
var arr=[];
//获取方向->获取进出->添加类名

//初始化
//获取li位置信息,宽高
init();
function init() {
    //将li转换成数组
    Array.prototype.slice.call(oLi,0).forEach(function (ele,index) {
        arr.push({
            w:ele.offsetWidth,
            h:ele.offsetHeight,
            l:ele.offsetLeft,
            t:ele.offsetTop
        })
        bindEvent(ele,index);
    })
}

function bindEvent(ele,index) {
    $(ele).on('mouseenter',function (e) {
        addClass(e,ele,'in',index);
    });
    $(ele).on('mouseleave',function (e) {
        addClass(e,ele,'out',index);
    })
}

function addClass(e,ele,state,index) {
    //获取进入的方向
    var d=getD(e,index);
    var str='';
    switch (d){
        case 0:
            str='-left';
            break;
        case 1:
            str='-top';
            break;
        case 2:
            str='-right';
            break;
        case 3:
            str='-bottom';
            break;
    }
    ele.className='';
    ele.classList.add(state+str);
}

function getD(e,index) {
    var w=arr[index].w,
        h=arr[index].h,
        l=arr[index].l,
        t=arr[index].t;
    x=e.pageX-l-w/2;
    y=e.pageY-t-h/2;
    //获取进入方向
    d=Math.round(((Math.atan2(y,x)*(180/Math.PI))+180)/90)%4;
    return d;
}

欢迎+Q:1759668379一起讨论。

(完)


猜你喜欢

转载自blog.csdn.net/jacoox/article/details/80274347