jQuery方向感知悬停与CSS3过渡

时间:2016-01-20 12:29:17

标签: javascript jquery css css3 css-transitions

我正在努力让方向感知悬停和css过渡正常工作。基本上我想要一个具有正面和背面的元素网格,并且在悬停时有一个css过渡来翻转该元素以显示背面。

转换示例(没有方向感知):fiddle

正如您所看到的,无论您的鼠标以哪种方式进入元素,它总是会翻转。我想让它以鼠标进/出的方式翻转。

示例:

Mouse in from bottom Mouse in from right

这是我对方向感知的尝试:fiddle

我正在使用jQuery添加与鼠标进/出方向相关的类。

.hover-in-top {}
.hover-in-right {}
.hover-in-bottom {}
.hover-in-left {}

.hover-out-top {}
.hover-out-right {}
.hover-out-bottom {}
.hover-out-left {}

正如你从方向感知的例子中看到的那样,它有点有用,但是有一些重大的故障,我无法理解。 (我一直在思考这个问题,而我的大脑刚刚崩溃了。)

无论如何,我希望这是有道理的。感谢。

2 个答案:

答案 0 :(得分:1)

我认为解决问题的最佳方法是不使用CSS转换。

您可以使用jQuery' animate轻松实现它,利用jQuery动画队列来保持所有动画同步。

我修改了您的示例,以便在JavaScript中设置转换动画。

Code example

答案 1 :(得分:1)

我对你的问题有部分解决方案。

但我需要将一些转换更改为动画

$('.box-container .box').each(function() {
    $(this).on('mouseenter mouseleave', function(e) {
        var $this = $(this),
            width = $this.width(),
            height = $this.height();

        var x = (e.pageX - $this.offset().left - (width / 2)) * (width > height ? (height / width) : 1),
            y = (e.pageY - $this.offset().top - (height / 2)) * (height > width ? (width / height) : 1);

        // top = 0, right = 1, bottom = 2, left = 3
        var dir_num = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4,
            directions = ['top', 'right', 'bottom', 'left'];

        // If mouse enter
        if (e.type === 'mouseenter') {
            // Remove all hover out classes
            $this.removeClass(function(index, css) {
                return (css.match(/(^|\s)hover-out-\S+/g) || []).join(' ');
            });

            // Add in direction class
            $this.addClass('hover-in-' + directions[dir_num]);
        }


        // If mouse leave
        if (e.type === 'mouseleave') {
            // Remove all hover in classes
            $this.removeClass(function(index, css) {
                return (css.match(/(^|\s)hover-in-\S+/g) || []).join(' ');
            });

            // Add out direction class
            $this.addClass('hover-out-' + directions[dir_num]);
        }
    });
});
* {
    box-sizing: border-box;
}

.box-container {
    padding: 20px;
    width: 600px;
}
.box-container:after {
    content: '';
    display: block;
    clear: both;
}
.box-container .box {
    float: left;
    width: 50%;
    height: 200px;
    position: relative;
    perspective: 600px;
    border: 1px solid transparent;
}
.box-container .box .front, .box-container .box .back {
    float: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    backface-visibility: hidden;
    transition: all 1s ease-in-out;
    color: white;
    font-size: 60px;
}
.box-container .box .front {
    background: blue;
    transform: rotateX(0) rotateY(0);
    z-index: 900;
}
.box-container .box .back {
    background: red;
    z-index: 800;
}
.box-container .box:hover .front {
    z-index: 900;
}
.box-container .box:hover .back {
    z-index: 1000;
    transform: rotateX(180) rotateY(0);
}

.box-container .box.hover-in-top .front,
.box-container .box.hover-out-bottom .back {
    transform: rotateX(-179deg) rotateY(0);
}
.box-container .box.hover-in-top .back,
.box-container .box.hover-out-bottom .front {
    animation: Xminus 1s ease-in-out;
}
@keyframes Xminus {
    from {transform: rotateX(179deg) rotateY(0);}
    to   {transform: rotateX(  0deg) rotateY(0);}
}

.box-container .box.hover-in-bottom .front,
.box-container .box.hover-out-top .back {
    transform: rotateX(179deg);
}
.box-container .box.hover-in-bottom .back,
.box-container .box.hover-out-top .front {
    animation: Xplus 1s ease-in-out;
}
@keyframes Xplus {
    from {transform: rotateX(-179deg) rotateY(0);}
    to   {transform: rotateX(   0deg) rotateY(0);}
}

.box-container .box.hover-in-right .front,
.box-container .box.hover-out-left .back {
    transform: rotateY(-179deg);
}
.box-container .box.hover-in-right .back,
.box-container .box.hover-out-left .front {
    animation: Yminus 1s ease-in-out;
}
@keyframes Yminus {
    from {transform: rotateX(0deg) rotateY(179deg);}
    to   {transform: rotateX(0deg) rotateY(  0deg);}
}

.box-container .box.hover-in-left .front,
.box-container .box.hover-out-right .back {
    transform: rotateY(179deg);
}

.box-container .box.hover-in-left .back,
.box-container .box.hover-out-right .front {
    animation: Yplus 1s ease-in-out;
}
@keyframes Yplus {
    from {transform: rotateX(0deg) rotateY(-179deg);}
    to   {transform: rotateX(0deg) rotateY(  0deg);}
}
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box-container">
    <div class="box">
        <div class="front">FRONT</div>
        <div class="back">BACK</div>
    </div>
    <div class="box">
        <div class="front">FRONT</div>
        <div class="back">BACK</div>
    </div>
    <div class="box">
        <div class="front">FRONT</div>
        <div class="back">BACK</div>
    </div>
    <div class="box">
        <div class="front">FRONT</div>
        <div class="back">BACK</div>
    </div>
</div>

动画问题,如果你在动画结束前离开div,动画就会中断

但是,如果移动缓慢,并保持在div上直到动画结束,这将正常工作。

我希望有人找到更好的解决方案