Reputation: 597
FIDDLE
http://jsfiddle.net/zuhloobie/t9x723tq/10/
GOALS
(a) flip from blue to gray if entering hover and staying on hover
(b) flip from gray back to blue if hover is left
(c) if you enter hover and leave hover really quickly, run the full animation (blue to gray and back to blue)
These "sorta" work in my fiddle, but it's buggy...
2 BUGS/QUESTIONS
(1) If you enter hover from the left side of the div, it flips to back side and stays as intended, but it doesn't finish the animation and flip back to front after leaving hover. How to fix this?
(2) If you enter hover from the top, right, or bottom of the div, it does not flip to the back side, but it does run the entire animation after leaving hover. How to fix this?
JQUERY
$(document).ready(function(){
$(".bar").hover(function()
{
$(this).bind("mouseover mouseout transitionend webkitTransitionEnd oTransitionEnd", function() {
$(this).find(".vFlipper").css({"transition":".4s","transform-style":"preserve-3d","position":"relative"});
$(this).find(".vertical.vFlip .vFlipper").css({"transform":"rotateX(-180deg)","background-color":"#999999"});
});
},
function()
{
$(this).bind("mouseover mouseout transitionend webkitTransitionEnd oTransitionEnd", function() {
$(this).find(".vFlipper").css({"transition":".4s","transform-style":"preserve-3d","position":"relative"});
$(this).find(".vertical.vFlip .vFlipper").css({"transform":"rotateX(0deg)","background-color":"#4FAEDD"});
});
});
});
CSS
#container {width:80%; margin:0 auto;}
.bar {width:50%; margin:30px auto 0 30px; height:50px}
.bar ul {list-style:none;}
.bar > ul > li > a{display:block; padding:10px; text-decoration:none;}
.bar > ul > li > a:hover {text-decoration:none;}
.vFlip {perspective:140px; -webkit-perspective:140px; perspective-origin:center; -webkit-perspective-origin:center;}
.vertical.vFlip {position:relative;}
.vertical.vFlip .vFlipper {background-color:#4FAEDD;}
Thank you for any help.
Upvotes: 2
Views: 134
Reputation: 1565
Is this what you require http://jsfiddle.net/f4x4uzu1/2/
$(document).ready(function() {
var customAnimator = function(this_var) {
var myCustomAnimator = {};
myCustomAnimator.var_this = this_var;
myCustomAnimator.inside = false;
myCustomAnimator.onHoverIn = function() {
myCustomAnimator.inside = true;
$(this).find(".vFlipper").css({
"transition": ".4s",
"transform-style": "preserve-3d",
"position": "relative"
});
$(this).find(".vertical.vFlip .vFlipper").css({
"transform": "rotateX(-180deg)",
"background-color": "#999999"
});
$(this).one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',
function(e) {
if (myCustomAnimator.inside) {
console.info('handler attached');
$(this).one('mouseleave', myCustomAnimator.onHoverOutCallback);
} else {
console.info('calling callback directly');
myCustomAnimator.onHoverOutCallback();
}
});
};
myCustomAnimator.onHoverOut = function() {
myCustomAnimator.inside = false;
};
myCustomAnimator.onHoverOutCallback = function() {
console.info('call back called');
$(myCustomAnimator.var_this).find(".vFlipper").css({
"transition": ".4s",
"transform-style": "preserve-3d",
"position": "relative"
});
$(myCustomAnimator.var_this).find(".vertical.vFlip .vFlipper").css({
"transform": "rotateX(0deg)",
"background-color": "#4FAEDD"
});
};
return myCustomAnimator;
};
$(".bar").each(function() {
var myAnimator = customAnimator(this);
$(this).hover(myAnimator.onHoverIn, myAnimator.onHoverOut);
});
});
#container {
width: 80%;
margin: 0 0;
}
.bar {
width: 50%;
margin: 30px 0;
}
.bar ul {
list-style: none;
}
.bar > ul > li > a {
display: block;
text-decoration: none;
height: 40px;
}
.bar > ul > li > a:hover {
text-decoration: none;
}
.vFlip {
perspective: 140px;
-webkit-perspective: 140px;
perspective-origin: center;
-webkit-perspective-origin: center;
}
/*.vFlipper {transition:.4s; transform-style:preserve-3d; position:relative;}*/
.vertical.vFlip {
position: relative;
}
.vertical.vFlip .vFlipper {
background-color: #4FAEDD;
}
.vertical.vFlip:hover .vFlipper {
/*transform:rotateX(-180deg) scaleY(-1); background-color:#999999;*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="bar">
<ul>
<li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;"> </a>
</li>
</ul>
</div>
<div class="bar">
<ul>
<li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;"> </a>
</li>
</ul>
</div>
<div class="bar">
<ul>
<li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;"> </a>
</li>
</ul>
</div>
<div class="bar">
<ul>
<li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;"> </a>
</li>
</ul>
</div>
<div class="bar">
<ul>
<li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;"> </a>
</li>
</ul>
</div>
</div>
-
Upvotes: 1
Reputation:
Update: http://jsfiddle.net/t9x723tq/22/
Alright, this seems to be what you want. I chose to use a JavaScript library (TweenLite) instead of CSS, so that it is cleaner and more compatible. I also stripped the code that was irrelevant to the animation.
http://jsfiddle.net/t9x723tq/17/
//using TweenLite.set() takes care of all vendor-prefixes
TweenLite.set(".barWrapper", {
perspective: 500
});
TweenLite.set(".bar", {
transformStyle: "preserve-3d"
});
TweenLite.set(".back", {
rotationX: -180
});
TweenLite.set([".back", ".front"], {
backfaceVisibility: "hidden"
});
var mouseover = false;
var hovering = false;
$(".barWrapper").mouseover(
function() {
mouseover = true;
TweenLite.to($(this).find(".bar"), 0.5, {
rotationX: 180,
ease: Expo.easeOut,
onComplete: function() {
if (!mouseover)
TweenLite.to(this.target, 0.5, {
rotationX: 0,
ease: Expo.easeOut
});
else hovering = true;
}
});
}
);
$(".barWrapper").mouseleave(
function() {
mouseover = false;
if (hovering) {
hovering = false;
TweenLite.to($(this).find(".bar"), 0.5, {
rotationX: 0,
ease: Expo.easeOut
});
}
}
);
.barWrapper {
margin: 5px;
display: inline-block;
}
.bar {
width: 300px;
height: 50px;
position: relative;
}
.front {
width: 100%;
height: 100%;
position: absolute;
background-color: #4FAEDD;
}
.back {
width: 100%;
height: 100%;
position: absolute;
background-color: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/plugins/CSSPlugin.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/easing/EasePack.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenLite.min.js"></script>
<div id="container">
<div class="barWrapper">
<div class="bar">
<div class="front">Front</div>
<div class="back">Back</div>
</div>
</div>
<div class="barWrapper">
<div class="bar">
<div class="front">Front</div>
<div class="back">Back</div>
</div>
</div>
<div class="barWrapper">
<div class="bar">
<div class="front">Front</div>
<div class="back">Back</div>
</div>
</div>
<div class="barWrapper">
<div class="bar">
<div class="front">Front</div>
<div class="back">Back</div>
</div>
</div>
<div class="barWrapper">
<div class="bar">
<div class="front">Front</div>
<div class="back">Back</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 2823
You are binding multiple things to the same events.
JS:
$(document).ready(function () {
var inside = 0;
var transistion = 0;
$(".bar").bind("mouseover touchstart focus", function () {
$(this).find(".vFlipper").css({
"transition": ".4s",
"transform-style": "preserve-3d",
"position": "relative"
});
$(this).find(".vertical.vFlip .vFlipper").css({
"transform": "rotateX(-180deg)",
"background-color": "#999999"
});
inside = 1;
});
$(".bar").bind("mouseout touchend blur", function () {
inside = 0;
if (transistion == 1 && inside == 0){
$(this).find(".vFlipper").css({
"transition": ".4s",
"transform-style": "preserve-3d",
"position": "relative"
});
$(this).find(".vertical.vFlip .vFlipper").css({
"transform": "rotateX(0deg)",
"background-color": "#4FAEDD"
});
}
});
$(".bar").bind("transitionend webkitTransitionEnd oTransitionEnd", function () {
transistion = 1;
});
});
DEMO: JSFiddle
Upvotes: 0
Reputation: 829
Here's how I would do it with CSS3. I'm sorry if it doesn't work in all browsers, I checked only chrome: http://jsfiddle.net/dp4yxbL3/1/
body {
-webkit-perspective: 140px;
-moz-perspective: 140px;
perspective: 140px;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.flipContainer {
width:170px;
height:40px;
margin:10px;
}
.flip {
width:170px;
height:40px;
-webkit-perspective: 140px;
-moz-perspective: 140px;
perspective: 140px;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition:all .5s;
-moz-transition:all .5s;
-o-transition:all .5s;
transition:all .5s;
}
.flip div {
position:absolute;
top:0;
left:0;
width:170px;
height:40px;
line-height:40px;
padding:0 5px;
box-sizing:border-box;
-webkit-backface-visibility:hidden;
-moz-backface-visibility:hidden;
backface-visibility:hidden;
}
.front {
background:#ccc;
}
.back {
background:#4FAEDD;
-webkit-transform:rotateX(180deg);
-moz-transform:rotateX(180deg);
-ms-transform:rotateX(180deg);
-o-transform:rotateX(180deg);
transform:rotateX(180deg);
}
.flipContainer:hover .flip {
-webkit-transform:rotateX(180deg);
-moz-transform:rotateX(180deg);
-ms-transform:rotateX(180deg);
-o-transform:rotateX(180deg);
transform:rotateX(180deg);
}
<div class="flipContainer">
<div class="flip">
<div class="front">
maybe some front text?
</div>
<div class="back">
maybe some back text?
</div>
</div>
</div>
<div class="flipContainer">
<div class="flip">
<div class="front">
maybe some front text?
</div>
<div class="back">
maybe some back text?
</div>
</div>
</div>
<div class="flipContainer">
<div class="flip">
<div class="front">
maybe some front text?
</div>
<div class="back">
maybe some back text?
</div>
</div>
</div>
Upvotes: 0