AngularJS - ngMouseenter & ngMouseleave expanding image menu

625 views Asked by At

I have this PLUNKER - http://embed.plnkr.co/ti6X3rzoBwqmle4b06FI/preview

I'm trying to create an expanding image menu like the jQuery Kwicks plugin - http://devsmash.com/projects/kwicks/2.2.x/examples/responsive, but am attempting to do it the Angular way (no jQuery dependency).

My structure inludes a ul with a repeating li:

<ul 
  class="accordion_wrap"  
  data-image-accordion-parent="{{mouseParentState}}" 
  data-child-count="{{imageAccordionItemsCount}}"

  data-ng-mouseenter="mouseEnterParent($event)"
  data-ng-mouseleave="mouseLeaveParent($event)"
>
  <li 
    data-ng-repeat="item in imageAccordionItems" 
    style="background-image: url('{{item.iaSrc}}');" 
    class="accordion_panel {{item.iaClass}}" 
    title="{{item.iaTitle}}" 

    data-parent-state="{{mouseParentState}}" 
    data-image-accordion-item="{{mouseItemState}}-{{mouseParentState}}" 
    index="{{item.iaIndex}}" 

    data-ng-mouseenter="mouseEnterItem($event)" 
    data-ng-mouseleave="mouseLeaveItem($event)"
  >  
  </li>

Then my directives, I have broken them up into a "parent" and "child"; imageAccordionParent and imageAccordionItem.

Parent directive code (mostly used to $animate.addClass(element, 'item_equal'), to make all items same width when mouseleave event fires on the parent:

  return {
     scope: true,
     link: function(scope, element, attrs) {
  },
  controller: function($scope) {
     $scope.mouseParentState = false;
     $scope.mouseLeaveParent = function(e) {
        $scope.mouseParentState = false;
     }
     $scope.mouseEnterParent = function(e) {
        $scope.mouseParentState = true;
     }
  }

Child directive code:

return {
  scope: true,
  restrict: "A",
  link: function(scope, element, attrs) {
    var first = false;
    if (!first) {
      $animate.addClass(element, 'item_equal');
      first = true;
    }

  attrs.$observe('imageAccordionItem', function(newVal) {

    element.removeClass('item_over');
    element.removeClass('item_out');
    element.removeClass('item_equal');

    if (scope.mouseParentState) {
      console.log("Parent Over");
      if (newVal == 'item-mouse-enter-true') {
        $animate.addClass(element, 'item_over');
        $animate.removeClass(element, 'item_out');
        $animate.removeClass(element, 'item_equal');
      }
      if (newVal == 'item-mouse-leave-true') {
        $animate.addClass(element, 'item_out');
        $animate.removeClass(element, 'item_over');
        $animate.removeClass(element, 'item_equal');
      }
    } else {
      console.log("Parent Leave");
      $animate.removeClass(element, 'item_over');
      $animate.removeClass(element, 'item_out');
      $animate.addClass(element, 'item_equal');
    }
  })
},
controller: function($scope, $element, $animate) {
  $scope.mouseItemState = 'item-mouse-leave';
  $scope.mouseEnterItem = function(e) {
    $scope.mouseItemState = 'item-mouse-enter';
    //console.log("over item");
  }
  $scope.mouseLeaveItem = function(e) {
    $scope.mouseItemState = 'item-mouse-leave';
    //console.log("leave item");
  }
}

Essentially the menu works (sort of), but when mousing over the items quickly I have noticed that:

  • The last image gets cut off and pushed to the bottom, i assume this is happening because the animations aren't syncing correctly (if that is even possible in Angular)
  • ng-animate class doesn't get removed on some or all of the elements, I assume this is happening as to many animations are attempting to fire at once and cancelling out one another.

In addition, I am using:

  • TweenMax
  • UI Router
  • FutureState resolve (ui-router-extras)
  • ngAnimate

Here's the PLUNKER again - http://embed.plnkr.co/ti6X3rzoBwqmle4b06FI/preview

Any ideas on how to make this work better?

0

There are 0 answers