如何在ngRepeat中实现双动画? (向下移动当前项目,从右侧淡入新项目)

时间:2022-07-07 19:14:48

I am trying to implement the following animation: a list of items should move down the right amount of space for a new item to be added on top (variable height), and then the new item should move in from the right.

我正在尝试实现以下动画:项目列表应向下移动适当的空间,以便在顶部添加新项目(可变高度),然后新项目应从右侧移入。

Here is what I got: http://plnkr.co/edit/V5rrbkZgkn72OJRlXEee?p=preview

这是我得到的:http://plnkr.co/edit/V5rrbkZgkn72OJRlXEee?p = preview

.list-item {
  width: 100%;
  display: table; 
}

.list-item.ng-enter,
.list-item.ng-leave
{
  -webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  position: relative;
}

.list-item.ng-enter.ng-enter-active,
.list-item.ng-leave {
  opacity: 1;
  right: 0;
}

.list-item.ng-leave.ng-leave-active,
.list-item.ng-enter {
  opacity: 0;
  right: -200px;
  height: 0px;
}

Problem is that the old list "jumps" instead of transitioning down. How do I fix this?

问题是旧列表“跳转”而不是向下转换。我该如何解决?

2 个解决方案

#1


1  

The animation classes applied on the added items will not be automatically added to the other items because no change happens to them, so ng-animate does not add any classes on them. Instead you could add a rule to the siblings of the currently animated one. Also update the positioning to absolute for the animated item, so that it does not push the other items down due to its current relative positioning.

应用于添加项目的动画类不会自动添加到其他项目,因为它们没有发生任何更改,因此ng-animate不会在其上添加任何类。相反,您可以向当前动画的兄弟姐妹添加规则。同时将动画项目的定位更新为绝对,以便它不会因其当前相对位置而将其他项目向下推。

Ex:-

.list-item.ng-enter,
.list-item.ng-leave{
  -webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  position:absolute;
}

.list-item.ng-enter ~ .list-item,
.list-item.ng-leave  ~ .list-item {
  -webkit-transform: translateY(15px);
   transform:translateY(15px);
   -webkit-transition:0.2s linear all ;
  transition: 0.2s linear all ;
}

var app = angular.module('plunker', [ "ngAnimate" ]);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  
  $scope.list = [
    { id: 0, name: "TEST" },
    { id: 1, name: "aajjaja" },
    { id: 2, name: "AAAA" },
    { id: 3, name: "VVVVV" }
    ];
    
  $scope.add = function() {
     $scope.list.unshift({ id: $scope.list.length, name: "NEW ITEM" });
  }
});
/* Put your css in here */

.list-item {
  width: 100%;
  display: table; 
 
}

.list-item.ng-enter,
.list-item.ng-leave
{
  -webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  position:absolute;
}
.list-item.ng-enter ~ .list-item,
.list-item.ng-leave  ~ .list-item {
  -webkit-transform: translateY(15px);
   transform:translateY(15px);
   -webkit-transition:0.2s linear all ;
  transition: 0.2s linear all ;
}
.list-item.ng-enter.ng-enter-active,
.list-item.ng-leave {
  opacity: 1;
  right: 0;
}

.list-item.ng-leave.ng-leave-active,
.list-item.ng-enter {
  opacity: 0;
  right: -200px;
  height: 0px;
}
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.26/angular.js" data-semver="1.2.26"></script>
    <script data-require="angular-animate@1.2.x" data-semver="1.2.26" src="http://code.angularjs.org/1.2.26/angular-animate.js"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>
    <button ng-click="add()">ADD</button>
    <br/><br/><br/>
    <div class="list-item" ng-repeat="item in list">{{ item.name }}</div>
    
  </body>

</html>

#2


1  

It seems the solution was to use keyframes.

似乎解决方案是使用关键帧。

.list-item.ng-enter {
  max-height: 0;
  opacity: 0;
  transform: translateX(100%);

  -webkit-animation: 
    openSpace 2s ease forwards, 
    moveIn 0.3s 0.2s ease forwards;
}

@-webkit-keyframes openSpace {
  to {
    max-height: 300px;
  }
}

@-webkit-keyframes moveIn {
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

#1


1  

The animation classes applied on the added items will not be automatically added to the other items because no change happens to them, so ng-animate does not add any classes on them. Instead you could add a rule to the siblings of the currently animated one. Also update the positioning to absolute for the animated item, so that it does not push the other items down due to its current relative positioning.

应用于添加项目的动画类不会自动添加到其他项目,因为它们没有发生任何更改,因此ng-animate不会在其上添加任何类。相反,您可以向当前动画的兄弟姐妹添加规则。同时将动画项目的定位更新为绝对,以便它不会因其当前相对位置而将其他项目向下推。

Ex:-

.list-item.ng-enter,
.list-item.ng-leave{
  -webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  position:absolute;
}

.list-item.ng-enter ~ .list-item,
.list-item.ng-leave  ~ .list-item {
  -webkit-transform: translateY(15px);
   transform:translateY(15px);
   -webkit-transition:0.2s linear all ;
  transition: 0.2s linear all ;
}

var app = angular.module('plunker', [ "ngAnimate" ]);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  
  $scope.list = [
    { id: 0, name: "TEST" },
    { id: 1, name: "aajjaja" },
    { id: 2, name: "AAAA" },
    { id: 3, name: "VVVVV" }
    ];
    
  $scope.add = function() {
     $scope.list.unshift({ id: $scope.list.length, name: "NEW ITEM" });
  }
});
/* Put your css in here */

.list-item {
  width: 100%;
  display: table; 
 
}

.list-item.ng-enter,
.list-item.ng-leave
{
  -webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  -o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
  position:absolute;
}
.list-item.ng-enter ~ .list-item,
.list-item.ng-leave  ~ .list-item {
  -webkit-transform: translateY(15px);
   transform:translateY(15px);
   -webkit-transition:0.2s linear all ;
  transition: 0.2s linear all ;
}
.list-item.ng-enter.ng-enter-active,
.list-item.ng-leave {
  opacity: 1;
  right: 0;
}

.list-item.ng-leave.ng-leave-active,
.list-item.ng-enter {
  opacity: 0;
  right: -200px;
  height: 0px;
}
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.26/angular.js" data-semver="1.2.26"></script>
    <script data-require="angular-animate@1.2.x" data-semver="1.2.26" src="http://code.angularjs.org/1.2.26/angular-animate.js"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>
    <button ng-click="add()">ADD</button>
    <br/><br/><br/>
    <div class="list-item" ng-repeat="item in list">{{ item.name }}</div>
    
  </body>

</html>

#2


1  

It seems the solution was to use keyframes.

似乎解决方案是使用关键帧。

.list-item.ng-enter {
  max-height: 0;
  opacity: 0;
  transform: translateX(100%);

  -webkit-animation: 
    openSpace 2s ease forwards, 
    moveIn 0.3s 0.2s ease forwards;
}

@-webkit-keyframes openSpace {
  to {
    max-height: 300px;
  }
}

@-webkit-keyframes moveIn {
  to {
    opacity: 1;
    transform: translateX(0);
  }
}