У меня возникли проблемы с поиском некоторых базовых инструментов анимации AngularJS 1.4 + CSS.
У меня есть список, где новые элементы всегда входят вверху и выходят внизу, когда максимальное количество элементов достигнуто (5 в примере ниже).
Следующий код успешно выполняет анимацию затухания для этого сценария:
angular.module("testApp", ["ngAnimate"])
.controller("testCtrl", function($scope) {
var lastId = 0;
$scope.items = [];
$scope.add = function() {
if (!$scope.newValue) { return; }
$scope.items.unshift({id: ++lastId, name:$scope.newValue});
$scope.newValue = '';
while ($scope.items.length > 5) {
$scope.items.pop();
}
};
});
.list-item.ng-enter {
transition: all 0.4s ease-out;
opacity: 0;
}
.list-item.ng-enter.ng-enter-active {
opacity: 1;
}
.list-item.ng-leave {
transition: all 0.4s ease-out;
opacity: 1;
}
.list-item.ng-leave.ng-leave-active {
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular-animate.min.js"></script>
<form ng-app="testApp" ng-controller="testCtrl">
<div>
<input type="text" ng-model="newValue" />
<button ng-click="add()">Add</button>
</div>
<table>
<tr class="list-item" ng-repeat="item in items track by item.id">
<td>{{item.name}}</td>
</tr>
</table>
</form>
Однако угасать не совсем то, что мне нужно. Я хочу, чтобы добавленные предметы расширялись по высоте, как если бы они скользили сверху, выходящие предметы уменьшались в высоту, как будто выпадали снизу, а удерживаемые предметы сдвигались вниз, чтобы перейти на новые позиции. Но я не уверен, как это достичь.
Я попытался использовать свойство height
вместо opacity
, но это не работает очень хорошо. Также обратите внимание, что я бы предпочел не указывать высоту явно для конечного результата, но пусть это автоматически зашифровывается шрифтом, как обычно. (Что может быть частью моей проблемы.)
Изменение высоты - это, безусловно, мой предпочтительный метод, но, вероятно, было бы хорошо, если бы это был чистый слайд, когда введенные элементы затухали, а уходящие элементы также исчезали. Однако в обоих случаях важно, чтобы он не изменял размер родительского элемента или любых окружающих элементов на странице (за исключением случаев, когда не удалялся элемент, когда список сначала растет, конечно).
(Обычно только один элемент вводится и уходит за раз, но могут быть случаи, когда два элемента входят и/или уходят. Было бы неплохо, если бы анимация могла задерживаться соответствующим образом, чтобы они выглядели скользкими в последовательности, как вы ожидайте, но я в порядке, когда не делаю этого, если это слишком сложно.)
Также стоит отметить, что в предыдущей итерации страницы я использовал анимацию jQuery "slideUp" для удаления элементов и "slideDown" для их добавления - в этом порядке, так как я также вручную вставлял/удалял элементы (это было предварительно Угловое). Он работал довольно хорошо, и я пытаюсь воспроизвести этот эффект, хотя я не уверен, поддерживает ли анимация CSS (или ng-repeat) управление таким порядком анимации.
Хорошо, после нескольких экспериментов код, кажется, работает.
Ключевые изменения:
<li>
вместо этого работает лучше.overflow-y: hidden
в дополнение к анимации max-height
требуется overflow-y: hidden
.
angular.module("testApp", ["ngAnimate"])
.controller("testCtrl", function($scope) {
var lastId = 0;
$scope.items = [];
$scope.add = function() {
if (!$scope.newValue) { return; }
$scope.items.unshift({id: ++lastId, name:$scope.newValue});
$scope.newValue = '';
while ($scope.items.length > 5) {
$scope.items.pop();
}
};
});
.list-item.ng-enter {
transition: all 0.5s linear;
max-height: 0;
overflow-y: hidden;
}
.list-item.ng-enter.ng-enter-active {
max-height: 20px;
}
.list-item.ng-leave {
transition: all 0.5s linear;
max-height: 20px;
overflow-y: hidden;
}
.list-item.ng-leave.ng-leave-active {
max-height: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular-animate.min.js"></script>
<form ng-app="testApp" ng-controller="testCtrl">
<div>
<input type="text" ng-model="newValue" />
<button ng-click="add()">Add</button>
</div>
<ul>
<li class="list-item" ng-repeat="item in items track by item.id">
{{item.name}}
</li>
</ul>
</form>