AngularJS Материал Слайд слева направо CSS3 Анимация - PullRequest
0 голосов
/ 10 ноября 2018

Я пытаюсь "перевести" этот пример AngularJS влево / вправо в материал AngularJS.

Последняя ссылка состоит из следующих фрагментов кода:

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 голосов
/ 11 ноября 2018

На самом деле, спустя еще несколько часов исследования, я обнаружил, где проблема была скрыта - похоже, мне нужно перенести изменение переменной области действия для следующего тика, чтобы дать время ng-class изменить, чтобы сделать его "волшебным".

Короче говоря - добавление следующего - вот что заставило эту вещь работать:

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

Вот обновленный пример и фрагмент кода ниже:

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);
...