Reputation: 317
how to make a smooth transition 3d rotate when mouse in or out from the box area, i got a code below but when my mouse out from the box area and enter to box from the other side, the element transition is not moving smoothly.
code : 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');
});});
Upvotes: 3
Views: 2174
Reputation: 1852
<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>
Upvotes: 0
Reputation: 357
If I understand right, OP's problem is that if you leave the jsfiddle's "result" panel with the mouse at one side, go around the div and enter it again from the other side, then the rotation would jump to the new position immediately without any transitions.
You had an error in the fiddle, the wrapper's ID was id="#wrapper"
in the html.
Edit: My second solution had some errors, the mousemove event can be triggered faster than the css transition ends and it caused the elements to jump back and forth in some browsers.
fiddle with JS only solution Here is my final solution.
I throttled
the mousemove event to fire less often. Then calculated a few steps between the new and old mouse positions and rendered the transforms with a delay until the mousemove event could fire again.
A way to throttling
an event is in this stackoverflow answer.
I made this before the JS one. The transition seems to be very smooth, but couldn't make it faster than 0.2s unless having the jumping issue.
I've added a default centered position to the 2 divs and they would return to that when you leave the viewport. While the mouse is above the viewport the transition is faster, so the rotation should be smooth even if the mousemove event isn't firing quite continuously.
Please note this has some bugs though, moving the mouse a bit faster can make the divs jump back and forth in Firefox.
CSS:
#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:
$(document).mouseleave(function (event) {
$one.removeAttr('style');
$two.removeAttr('style');
});
(I didn't include the vendor prefixes in the css. Also fix the wrapper's height to something you will need in the final product, the 90vh was better in the fiddle.)
If you don't like it that the divs return to the center:
CSS:
.mouse-enter #div1,
.mouse-enter #div2 {
transition: transform 0.2s linear, box-shadow 0.2s linear;
}
JS:
$(document).mouseenter(function (event) {
$('#wrapper').addClass('mouse-enter');
setTimeout(function(){ $('#wrapper').removeClass('mouse-enter'); }, 400);
});
You might want to save the last mouse position before mouseleave either as variables in js or as data attributes on #wrapper
. Then, on mouseenter calculate a few transform steps between the old and new positions and add those to the 2 divs in sequence. Might be a better solution with less possible bugs than my workarounds.
Upvotes: 2