AngularJS Material 从左到右滑动 CSS3 动画

标签 angularjs css angular-material css-animations

我正在尝试“翻译”这个 AngularJS slide left / right examplean 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. 然后,我向右滑动第二张 --> 它应该是第一张幻灯片从左侧开始出现,而第二张幻灯片从右侧开始消失。相反,如您所见,第二个开始从左侧消失,从右侧显示一张白色幻灯片。在某些时候,第一张幻灯片从内容的中间开始出现。

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

最佳答案

实际上,经过几个小时的研究,我发现了问题所在 - 看来,我必须为下一个滴答移动范围变量更改,以便将时间 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);

关于AngularJS Material 从左到右滑动 CSS3 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53241272/

相关文章:

javascript - ui-router 解析在第一次加载时显示先前的解析结果,有时在重新加载时根本不显示

javascript - 如何解析函数并调用 Angular 中的其他函数

angular - Material Angular sidenav触发器调整大小

html - 标题图片不显示

javascript - 如何根据屏幕宽度将我的导航栏类更改为另一个导航栏类?

angular - 顺畅滑动的垫子 slider ,贴合滴答声

具有双倍滚动内容的 Angular Material Sidenav

angularjs - ng-scrollbar 不适用于 ng-repeat

javascript - 无法从 Angular $resource 获得响应

css - webpack + sass-loader : Invalid CSS after "...-width: $small)": expected "{", 是 ";"