[英]Angular.js animations
我有一个ng-repeat
的块,定义如下:
<div ng-show="isPageSelected(item.page)" class="block" ng-repeat="item in data">
...
</div>
目前,我可以通过单击某些元素在这些块之间切换。 它可以通过ng-show="isPageSelected(item.page)"
,你可能已经猜到了。 这一切都很好,但他们正在立即切换,我想添加一个动画,一个简单的淡入/淡出将做。
因此,不再选择的块应该淡出,当它消失时,新的块应该淡入。当我使用ngAnimate
它们会淡入并同时淡出。 我需要第一个块完全消失并隐藏display: none;
当它完成时,下一个块应该出现并淡入。使用jQuery时这是一个相当简单的任务,但是我如何使用Angular.js优雅地完成它?
我强烈怀疑Angular.js对于具有复杂动画的网站来说不是一个好的选择。
编辑:为了简化我的问题,我需要做的就是
由于我需要在动画后更改模型,因此可能无法通过纯CSS来实现。 我知道在angular中触发特定元素动画的唯一方法是创建一个指令,将一个范围变量传递给指令,在指令中为该变量创建观察者,然后从控制器更改变量:
<div animation="page"></div>
app.directive('animation', function(){
return {
scope: { page: '=animation' },
link: function(scope, element){
scope.$watch('page', function(newVal){
...
});
}
};
});
我想它会起作用,但为此创建一个指令似乎真的很臃肿。 另外,只有在动画完成后,我$scope.page
用这种方法更改$scope.page
? 添加另一个范围变量只是为了触发动画,并在动画完成后以某种方式更改$scope.page
? 使用ngFx
模块可以做到这ngFx
,但它所需的代码量非常荒谬。 在这一点上,我认为将jQuery动画添加到控制器将是一个更好的解决方法。
编辑:这就是jQuery动画的样子:
$scope.changePage = function(page) {
$('.block').animate({opacity: 0}, 500, function(){
$scope.page.id = page;
$scope.$apply();
$(this).animate({opacity: 1}, 500);
});
};
它工作得很好,并不像指令的方式那么冗长,但我必须使用CSS选择器,这只是感觉非常“不整齐”。 你们在处理动画时会使用类似的东西吗?
编辑:使用ngFx
有点类似的方法:
<div ng-hide="switchPageAnimation"
class="block fx-fade-normal fx-speed-300 fx-trigger">
在控制器中:
$scope.switchPageAnimation = false;
$scope.changePage = function(page) {
if($scope.page.id === page || $scope.switchPageAnimation) return;
$scope.switchPageAnimation = true;
$scope.$on('fade-normal:enter', function(){
$scope.page.id = page;
$scope.switchPageAnimation = false;
});
};
我没有使用CSS选择器,但它看起来很糟糕。 我必须为动画定义范围变量,然后检查动画是否已经在运行。 我觉得我错过了一些非常明显的东西。
也许这会对你有所帮助,在你的情况下等待动画完成是没有必要的。 如果您的页面具有css位置:绝对并且位于具有position:relative的容器中,那么它们共享相同的位置,并且在动画时不会一个在另一个下面显示。 使用此设置,您可以交叉淡化或延迟显示动画
过渡延迟:
.container1{
position: relative;
height:400px;
}
.block1{
position:absolute;
}
.block1.ng-hide-add-active {
display: block!important;
-webkit-transition: 2s linear all;
transition: 2s linear all;
}
.block1.ng-hide-remove-active {
display: block!important;
-webkit-transition: 2s linear all;
transition: 2s linear all;
-webkit-transition-delay: 2s;
transition-delay: 2s;
}
.block1.ng-hide {
opacity: 0;
}
编辑:如果你使用ng-repeat而不是ng-show中的过滤器来显示这样的选定页面
<div class="block1" ng-repeat="item in data | filter:isPageSelected">
然后从dom和angular add类添加和删除页面ng-enter,ng-enter-active和ng-leave ng-leave-active
但动画可以定义类似看小提琴: http : //jsfiddle.net/o944epzy/
实际上,您必须使用CSS来显示和隐藏ng-repeat中的元素; 当你使用ngAnimate时,不要忘记将它注入你的模块中。
.module('myModule', [ 'ngAnimate', ...
当您添加/删除重复数据源中的元素时,请执行此操作。 Angular将添加和删除类ng-enter, ng-leave
。 这是一个关于ngAnimate动画的好教程。
在您自己的情况下,您想要更改页面。 我建议您有太多项目可以同时显示所有内容。
您可以在范围中声明两个变量:
$scope.elemByPage = 5;
$scope.page = 0;
$scope.nbPages = ...; // I let you do the maths ;)
在您的模板中,您可以这样做:
<div class="my-repeat-item" data-ng-repeat="item in data | pager:page:elemByPage">
{{item.xxx}}
</div>
此模板仅显示页面编号和每页元素数量所需的项目。 寻呼机是一个简单的过滤器,它可以解决问题
.filter('pager',[function(){
return function(items, page, nbElemByPage) {
if(!nbElemByPage || nbElemByPage < 1) {
return items;
}
var nbPages = Math.floor(items.length/nbElemByPage);
if(nbPages<1) {
return items;
}
var startIndex = page*nbElemByPage;
return items.splice(startIndex, nbElemByPage);
};
}])
现在您只需使用按钮即可浏览您的项目
<button data-ng-click="page = page - 1"/>Prev page</button>
<button data-ng-click="page = page - 1"/>Next page</button>
要完成你想在新项目上添加淡入淡出的动画,所以在你的css中声明这些类跟随你的项目类(这里是my-repeat-item
)
.my-repeat-item.ng-enter {
transition: 0.6s ease all;
opacity:0;
}
.my-repeat-item.ng-enter.ng-enter-active {
opacity:1;
}
你可以做,当项目被替换去除同样的事情, enter
与leave
。
希望它能回答你的问题。
实际上,您必须使用CSS来显示和隐藏ng-repeat中的元素; 当你使用ngAnimate时,不要忘记将它注入你的模块中。
您可以将所需的过渡添加到要显示/隐藏的元素的CSS类中:
animate-show.ng-hide-add.ng-hide-add-active,
.animate-show.ng-hide-remove.ng-hide-remove-active {
-webkit-transition: all linear 0.5s;
transition: all linear 0.5s;
}
点击此处查看: https : //docs.angularjs.org/api/ng/directive/ngShow#example
事实上,使用CSS是“正确”的方式,即使它可能感觉没有角度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.