如何制作光滑的rotate3d鼠标悬停?

时间:2015-10-13 10:54:26

标签: javascript css css3

当鼠标进出盒子区域时,如何进行平滑过渡3d旋转,我得到了下面的代码,但当我的鼠标从盒子区域出来并从另一侧进入盒子时,元素过渡不动顺利进行。

代码:fiddle

$(document).ready(function () {
var $one = $('#div1'),
    $two = $('#div2'),
    browserPrefix = "",
    usrAg = navigator.userAgent;
if(usrAg.indexOf("Chrome") > -1 || usrAg.indexOf("Safari") > -1) {
    browserPrefix = "-webkit-";
} else if (usrAg.indexOf("Opera") > -1) {
    browserPrefix = "-o";
} else if (usrAg.indexOf("Firefox") > -1) {
    browserPrefix = "-moz-";
} else if (usrAg.indexOf("MSIE") > -1) {
    browserPrefix = "-ms-";
}

$(document).mousemove(function (event) {
    var cx = Math.ceil(window.innerWidth / 2.0),
        cy = Math.ceil(window.innerHeight / 2.0),
        dx = event.pageX - cx,
        dy = event.pageY - cy,
        tiltx = (dy / cy),
        tilty = - (dx / cx),
        radius = Math.sqrt(Math.pow(tiltx, 2) + Math.pow(tilty, 2)),
        degree = (radius * 15);

        shadx = degree*tiltx;   /*horizontal shadow*/
        shady = degree*tilty;   /*vertical shadow*/

    $one.css(browserPrefix + 'transform', 'rotate3d(' + tiltx + ', ' + tilty + ', 0, ' + degree + 'deg)');
    $two.css(browserPrefix + 'transform', 'rotate3d(' + tiltx + ', ' + tilty + ', 0, ' + degree + 'deg)');



    if(dx>cx) /*without that horizontal values are reversed*/
        $('#div1, #div2').css('box-shadow', + (-shady) + 'px ' + (-shadx) +'px 5px #3D352A');
    else $('#div1, #div2').css('box-shadow', + shady + 'px ' + (-shadx) +'px 5px #3D352A');
});});

2 个答案:

答案 0 :(得分:2)

如果我理解正确,OP的问题在于,如果你离开jsfiddle" s"结果"将鼠标放在一侧的面板,绕过div并从另一侧再次输入,然后旋转将立即跳转到新位置而不进行任何过渡。

你在小提琴中出错,包装的ID在html中是id="#wrapper"

编辑:我的第二个解决方案有一些错误,可以比css转换结束时更快地触发mousemove事件,这会导致元素在某些浏览器中来回跳转。

fiddle with JS only solution这是我的最终解决方案。

throttled mousemove事件不常发射。然后计算新旧鼠标位置之间的几个步骤,并延迟渲染变换,直到mousemove事件再次触发为止。

stackoverflow answerthrottling事件#wrapper { width: 100%; height: 90vh; } #wrapper:hover #div1, #wrapper:hover #div2 { transition: transform 0.05s linear, box-shadow 0.05s linear; } #div1, #div2 { transform: rotate3d(0,0,0,0deg); box-shadow: 0 0 5px #3D352A; transition: transform 0.3s linear, box-shadow 0.3s linear; }

我在JS之前做过这个。过渡似乎非常顺利,但除非出现跳跃问题,否则不能超过0.2秒。

fiddle with solution 3

fiddle with solution 1

我已经为2个div添加了默认居中位置,当您离开视口时它们会返回到该位置。当鼠标位于视口上方时,转换速度更快,因此即使mousemove事件不是连续发射,旋转也应该是平滑的。

请注意这有一些错误,快速移动鼠标可以让div在Firefox中来回跳转。

CSS:

$(document).mouseleave(function (event) {
    $one.removeAttr('style');
    $two.removeAttr('style');
});

JS:

.mouse-enter #div1,
.mouse-enter #div2 {
    transition: transform 0.2s linear, box-shadow 0.2s linear;
}

(我没有在css中包含供应商前缀。还要将包装器的高度修复为最终产品中需要的东西,90vh在小提琴中更好。)

如果你不喜欢div返回中心:

fiddle with solution 2

CSS:

$(document).mouseenter(function (event) {
    $('#wrapper').addClass('mouse-enter');
    setTimeout(function(){ $('#wrapper').removeClass('mouse-enter'); }, 400);
});

JS:

#wrapper

您可能希望将mouseleave之前的最后一个鼠标位置保存为js中的变量或false上的数据属性。然后,在mouseenter上计算旧位置和新位置之间的一些转换步骤,并按顺序将它们添加到2个div中。可能是一个比我的解决方案更少可能的错误的更好的解决方案。

答案 1 :(得分:0)

   <div></div>
      <style>
div {
     width: 200px;
     height: 100px;
     background-color: yellow;
     transition: all 1s;
         }

div:hover{
       -moz-transform: rotate(7deg); 
     -o-transform: rotate(7deg); 
    -webkit-transform: rotate(7deg); 
    transform: rotate(180deg);
         }
    </style>