74 votes

Effet de glissement haut/bas avec ng-show et ng-animate

J'essaie d'utiliser ng-animate pour obtenir un comportement similaire à celui de JQuery. slideUp() y slideDown() . Seulement, je préfère utiliser ng-show

Je regarde le tutoriel ng-animate ici http://www.yearofmoo.com/2013/04/animation-in-angularjs.html ,

et je peux reproduire l'effet de fondu en entrée/sortie dans l'exemple fourni.

Comment pourrais-je modifier le css pour obtenir un comportement de glissement vers le haut/bas ? De plus, si possible, il est préférable que le fichier css ne connaisse pas la hauteur du composant en pixels. De cette façon, je peux réutiliser le css pour différents éléments.

1 votes

Je ne pense pas que vous serez en mesure de faire en sorte que ng-show gère les animations. Ce n'est pas son utilisation prévue. C'est à cela que sert ng-animate. Pourquoi voulez-vous utiliser spécifiquement ng-show ?

1 votes

Merci Jonathan. Je pense que vous vous trompez. L'exemple donné fait exactement cela : une combinaison de ng-show et de ng-animate (cherchez "Animating ngShow & ngHide"). Quoi qu'il en soit, ce que je veux, c'est simplement un effet pour afficher/cacher une division qui glisse vers le haut et vers le bas.

0 votes

Mon erreur, je n'ai pas fait usage de ng-animate. Il semble qu'ils fonctionnent en conjonction l'un avec l'autre.

87voto

Eric_WVGG Points 735

J'ai écrit une directive Angular qui fait slideToggle() sans jQuery.

https://github.com/EricWVGG/AngularSlideables

1 votes

Cela ressemble exactement à ce que je voulais. Merci !

0 votes

Merci beaucoup, c'est une excellente directive.

0 votes

Vous dites que la directive est sans jQuery, mais les méthodes duration easing css bind sont ceux de jQuery, non ? (je me trompe peut-être)

40voto

elthrasher Points 211

C'est en fait assez facile à faire. Tout ce que vous avez à faire est de changer le css.

Voici un exemple d'une animation en fondu très simple : http://jsfiddle.net/elthrasher/sNpjH/

Pour en faire une animation glissante, j'ai d'abord dû placer mon élément dans une boîte (c'est le conteneur de glissement), puis j'ai ajouté un autre élément pour remplacer celui qui partait, juste parce que je pensais que ce serait joli. Enlevez-le et l'exemple fonctionnera toujours.

J'ai changé l'animation css de 'fade' à 'slide' mais notez que ce sont les noms que je leur ai donnés. J'aurais pu écrire une css d'animation de diapositives nommée "fade" ou n'importe quoi d'autre d'ailleurs.

La partie importante est ce qui se trouve dans la css. Voici la css originale de 'fade' :

.fade-hide, .fade-show {
    -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
    -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
    -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
    transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
.fade-hide {
    opacity:1;
}
.fade-hide.fade-hide-active {
    opacity:0;
}
.fade-show {
    opacity:0;
}
.fade-show.fade-show-active {
    opacity:1;
}

Ce code fait passer l'opacité de l'élément de 0 (complètement transparent) à 1 (complètement opaque) et inversement. La solution consiste à ne pas toucher à l'opacité et à modifier plutôt le haut (ou la gauche, si vous voulez vous déplacer de gauche à droite).

.slide-hide, .slide-show {
    -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
    -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
    -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
    transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
}
.slide-hide {
    position: relative;
    top: 0;
}
.slide-hide.slide-hide-active {
    position: absolute;
    top: -100px;
}
.slide-show {
    position: absolute;
    top: 100px;
}
.slide-show.slide-show-active {
    position: relative;
    top: 0px;
}

Je passe également d'un positionnement relatif à un positionnement absolu afin qu'un seul des éléments occupe de l'espace dans le conteneur à la fois.

Voici le produit fini : http://jsfiddle.net/elthrasher/Uz2Dk/ . J'espère que cela vous aidera !

0 votes

C'était très utile. J'essaie de comprendre pourquoi la transition "cacher" est si soudaine dans votre bidule, @elthrasher.

1 votes

@ericpeters0n - c'est à cause de ce 0,5s à la fin de la ligne de transition. C'est le temps que cela prendra, une demi-seconde dans ce cas. Vous pouvez le régler comme vous le souhaitez. Essayez 5s ou 10s.

2 votes

Le comportement est un peu étrange. Parfois, le texte apparaît en haut et parfois en bas.

17voto

Amit Portnoy Points 563

Mise à jour pour Angular 1.2 et plus (v1.2.6 au moment de la rédaction de cet article) :

.stuff-to-show {
  position: relative;
  height: 100px;
  -webkit-transition: top linear 1.5s;
  transition: top linear 1.5s;
  top: 0;
}
.stuff-to-show.ng-hide {
  top: -100px;
}
.stuff-to-show.ng-hide-add,
.stuff-to-show.ng-hide-remove {
  display: block!important;
}

( plunker )

16 votes

N'animez pas la position supérieure avec css, c'est très lent et prend beaucoup de mémoire. Utilisez plutôt translate.

1 votes

Fonctionne également sur Angular 1.4. Testé et cela fonctionne comme un charme !

16voto

Luca Points 3312

Cela peut en fait peut se faire en CSS et avec un minimum de JS, simplement en ajoutant une classe CSS (ne définissez pas les styles directement en JS !) avec par exemple un ng-click événement. Le principe est que l'on ne peut pas animer height: 0; a height: auto; mais cela peut être contourné en animant l'élément max-height propriété. Le conteneur s'étendra à sa valeur "auto-height" lorsque .foo-open est défini - il n'est pas nécessaire de fixer la hauteur ou le positionnement.

.foo {
    max-height: 0;
}

.foo--open {
    max-height: 1000px; /* some arbitrary big value */
    transition: ...
}

voir ce violon de l'excellente Léa Verou

Comme une préoccupation soulevée dans les commentaires, notez que bien que cette animation fonctionne parfaitement avec un assouplissement linéaire, tout assouplissement exponentiel produira un comportement différent de ce qui pourrait être attendu - en raison du fait que la propriété animée est max-height y no height lui-même ; plus précisément, seul le height fraction de la courbe d'assouplissement de max-height s'affichera.

8voto

steampowered Points 2179

J'ai fini par abandonner le code pour mon autre réponse à cette question et de choisir cette réponse à la place.

Je pense que la meilleure façon de procéder est de ne pas utiliser ng-show y ng-animate du tout.

/* Executes jQuery slideDown and slideUp based on value of toggle-slidedown 
   attribute.  Set duration using slidedown-duration attribute.  Add the 
   toggle-required attribute to all contained form controls which are
   input, select, or textarea.  Defaults to hidden (up) if not specified
   in slidedown-init attribute.  */
fboApp.directive('toggleSlidedown', function(){
    return {
        restrict: 'A',
        link: function (scope, elem, attrs, ctrl) {
            if ('down' == attrs.slidedownInit){
                elem.css('display', '');
            } else {
                elem.css('display', 'none');
            }
            scope.$watch(attrs.toggleSlidedown, function (val) {
                var duration = _.isUndefined(attrs.slidedownDuration) ? 150 : attrs.slidedownDuration;
                if (val) {
                    elem.slideDown(duration);
                } else {
                    elem.slideUp(duration);
                }
            });
        }
    }
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X