chris
chris

Reputation: 597

css jquery animation doesn't run fully - 2 weird bugs

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

Answers (4)

Nithish Thomas
Nithish Thomas

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;">&nbsp;</a>

      </li>
    </ul>
  </div>
  <div class="bar">
    <ul>
      <li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;">&nbsp;</a>

      </li>
    </ul>
  </div>
  <div class="bar">
    <ul>
      <li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;">&nbsp;</a>

      </li>
    </ul>
  </div>
  <div class="bar">
    <ul>
      <li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;">&nbsp;</a>

      </li>
    </ul>
  </div>
  <div class="bar">
    <ul>
      <li class="vertical vFlip" ontouchstart="this.classList.toggle('hover');"> <a class="vFlipper" href="#" onclick="return false;">&nbsp;</a>

      </li>
    </ul>
  </div>
</div>

-

Upvotes: 1

user2570380
user2570380

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

hopkins-matt
hopkins-matt

Reputation: 2823

You are binding multiple things to the same events.

Updated

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

Alex
Alex

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

Related Questions