AngularJS素材从左到右滑动CSS3动画

时间:2018-11-10 16:58:57

标签: angularjs css3 angular-material css-animations

我正在尝试将此AngularJS slide left / right example“翻译”为an AngularJS Material one.

后一个链接由以下代码段组成:

HTML代码:

<div ng-controller="ExampleController" ng-app="switchExample">
  <!--<select ng-model="slide" ng-options="item as item.name for item in slides">
  </select>-->
  <code>slide={{slide}}</code>
  <code>moveToLeft={{mtl}}</code>
  <md-button ng-click="prev()"><</md-button>
  <md-button ng-click="next()">></md-button>
  <div class="">
      <div class="ngSwitchItem" ng-if="slide.name == 'first'" ng-class="{'moveToLeft' : mtl}">
        <div class="firstPage page" md-swipe-left="selectPage(1)">
          first
        </div>
      </div>
      <div class="ngSwitchItem" ng-if="slide.name == 'second'" ng-class="{'moveToLeft' : mtl}">
        <div class="secondPage page" md-swipe-right="selectPage(0)" md-swipe-left="selectPage(2)">
        second
        </div>
      </div>
      <div class="ngSwitchItem" ng-if="slide.name == 'third'" ng-class="{'moveToLeft' : mtl}">
        <div class="thirdPage page" md-swipe-right="selectPage(1)" md-swipe-left="selectPage(3)">
        third
        </div>
      </div>
      <div class="ngSwitchItem" ng-if="slide.name == 'fourth'" ng-class="{'moveToLeft' : mtl}">
        <div class="fourthPage page" md-swipe-right="selectPage(2)">
        fourth
        </div>
      </div>
  </div>
</div>

JS代码

(function(angular) {
  'use strict';
angular.module('switchExample', ['ngMaterial', 'ngAnimate'])
  .controller('ExampleController', ['$scope', function($scope) {

    $scope.slides = [
      { index: 0, name: 'first' }, 
      { index: 1, name: 'second' }, 
      { index: 2, name: 'third' }, 
      { index: 3, name: 'fourth' }
    ];
    $scope.selectPage = selectPage;
    /**
    * Initialize with the first page opened
    */
    $scope.slide = $scope.slides[0];

    $scope.prev = () => {
      if ($scope.slide.index > 0) {
        selectPage($scope.slide.index - 1);
      }
    }

    $scope.next = () => {
      if ($scope.slide.index < 3) {
        selectPage($scope.slide.index + 1);
      }
    }

    /**
    * @name selectPage
    * @desc The function that includes the page of the indexSelected
    * @param indexSelected the index of the page to be included
    */
    function selectPage(indexSelected) {
        if ($scope.slides[indexSelected].index > $scope.slide.index) {
            $scope.mtl = false;
        } else {
            $scope.mtl = true;
        }
        $scope.slide = $scope.slides[indexSelected];
    }
  }]);
})(window.angular);

CSS代码

body {
    overflow-x: hidden;
}

.ngSwitchItem {
    position: absolute;
    top: 50px;
    bottom: 0;
    right: 0;
    left: 0;

    animation-duration: 10.30s;
    animation-timing-function: ease-in-out;
    -webkit-animation-duration: 10.30s;
    -webkit-animation-timing-function: ease-in-out;

}

.page {
    position: inherit;
    top: 0;
    right: inherit;
    bottom: inherit;
    left: inherit;
}

.firstPage {
    background-color: blue;
}

.secondPage {
    background-color: red;
}

.thirdPage {
    background-color: green;
}

.fourthPage {
    background-color: yellow;
}

/* When the page enters, slide it from the right */
.ngSwitchItem.ng-enter {
    animation-name: slideFromRight;
    -webkit-animation-name: slideFromRight;
}
/* When the page enters and moveToLeft is true, slide it from the left(out of the user view) to the right (left corner) */
.ngSwitchItem.moveToLeft.ng-enter {
    animation-name: slideFromLeft;
    -webkit-animation-name: slideFromLeft;
}
/* When the page leaves, slide it to left(out of the user view) from the left corner,
    in other words slide it from the left(out of the view) to the left corner but in reverse order */
.ngSwitchItem.ng-leave {
    animation-name: slideFromLeft;
    animation-direction: reverse;
    -webkit-animation-name: slideFromLeft;
    -webkit-animation-direction: reverse;
}
/* When the page leaves, slide it to the right(out of the user view) from the the left corner,
    in other words, slide it from the right but in reverse order  */
.ngSwitchItem.moveToLeft.ng-leave {
    animation-name: slideFromRight;
    animation-direction: reverse;
    -webkit-animation-name: slideFromRight;
    -webkit-animation-direction: reverse;
}

@keyframes slideFromRight {
    0% {
        transform: translateX(100%);
    }

    100% {
        transform: translateX(0);
    }
}

@keyframes slideFromLeft {
    0% {
        transform: translateX(-100%);
    }

    100% {
        transform: translateX(0);
    }
}

@-webkit-keyframes slideFromRight {
    0% {
        -webkit-transform: translateX(100%);
    }

    100% {
        -webkit-transform: translateX(0);
    }
}

@-webkit-keyframes slideFromLeft {
    0% {
        -webkit-transform: translateX(-100%);
    }

    100% {
        -webkit-transform: translateX(0);
    }
}

但是,当滑动方向改变时,第二个不像第一个那样。 例如:

  1. 我向左滑动第一张->向第二张幻灯片加载正确的动画
  2. 然后,我将第二张幻灯片向右滑动->假定第一张幻灯片从左侧开始出现,而第二张幻灯片开始向右侧消失。相反,如您所见,第二个开始向左消失,并且从右侧开始显示白色幻灯片。在某些时候,第一张幻灯片从内容的中间开始显示。

请注意,我故意延迟第二个示例中的动画,只是为了清楚地看到不需要的副作用模式。

1 个答案:

答案 0 :(得分:0)

实际上,经过几个小时的研究,我发现了问题的根源所在-看来,我必须在下一个刻度上移动范围变量更改,给时间ng-class进行更改以使其“神奇” 。

长话短说-使内容生效的原因如下:

$timeout(() => {
  $scope.slide = $scope.slides[indexSelected];
}, 0)

这里是the updated example,下面是代码段:

JS代码

(function(angular) {
  'use strict';
angular.module('switchExample', ['ngMaterial', 'ngAnimate'])
  .controller('ExampleController', ['$scope', '$timeout', function($scope, $timeout) {

    $scope.slides = [
      { index: 0, name: 'first' }, 
      { index: 1, name: 'second' }, 
      { index: 2, name: 'third' }, 
      { index: 3, name: 'fourth' }
    ];
    $scope.selectPage = selectPage;
    /**
    * Initialize with the first page opened
    */
    $scope.slide = $scope.slides[0];

    $scope.prev = () => {
      if ($scope.slide.index > 0) {
        selectPage($scope.slide.index - 1);
      }
    }

    $scope.next = () => {
      if ($scope.slide.index < 3) {
        selectPage($scope.slide.index + 1);
      }
    }

    /**
    * @name selectPage
    * @desc The function that includes the page of the indexSelected
    * @param indexSelected the index of the page to be included
    */
    function selectPage(indexSelected) {
        if ($scope.slides[indexSelected].index > $scope.slide.index) {
            $scope.mtl = false;
        } else {
            $scope.mtl = true;
        }
      // this will move a scope variable change to the next tick, 
      // hence will give time $scope.mtl to be handled by ng-class
      $timeout(() => {
        $scope.slide = $scope.slides[indexSelected];
      }, 0)

    }
  }]);
})(window.angular);