51 votes

Comment créer des animations réutilisables dans Angular 2 ?

Je joue avec l'API Animation, et j'aimerais créer une animation réutilisable, par exemple pour faire glisser du contenu dans des vues de routeur de niveau supérieur. J'ai réussi à passer à travers la syntaxe funky des métadonnées (qui est en fait assez cool une fois passée l'idée folle d'utiliser des métadonnées) pour obtenir des animations qui fonctionnent à peu près correctement.

   @Component({
      //moduleId: module.id,
      selector: 'album-display',
      templateUrl: './albumDisplay.html',
      animations: [
        trigger('slideIn', [
          state('*', style({
            transform: 'translateX(100%)',
          })),
          state('in', style({
            transform: 'translateX(0)',
          })),
          state('out',   style({
            transform: 'translateX(-100%)',
          })),
          transition('* => in', animate('600ms ease-in')),
          transition('in => out', animate('600ms ease-in'))
        ])
      ]
  })
  export class AlbumDisplay implements OnInit {
      slideInState = 'in';
      ...
  }

Puis je l'affecte à mon élément de premier niveau dans le composant :

  <div  class="container" [@slideIn]="slideInState">

Cela fonctionne donc, mais comment puis-je le rendre réutilisable ? Je ne veux pas coller ces métadonnées sur chaque vue. Puisqu'il s'agit de métadonnées, je ne vois pas très bien comment on pourrait les rendre réutilisables.

87voto

ranakrunal9 Points 9454

Une solution possible consiste à placer le code de déclenchement de l'animation dans un fichier séparé et à l'exporter en tant que const et l'utiliser dans le composant comme indiqué ci-dessous.

animations.ts

import { trigger, state, style, transition, animate } from '@angular/core';

export const slideIn = trigger('slideIn', [
  state('*', style({
    transform: 'translateX(100%)',
  })),
  state('in', style({
    transform: 'translateX(0)',
  })),
  state('out',   style({
    transform: 'translateX(-100%)',
  })),
  transition('* => in', animate('600ms ease-in')),
  transition('in => out', animate('600ms ease-in'))
]);

album-display.component.ts

import { slideIn } from './animations'; // path to your animations.ts file

@Component({
    //moduleId: module.id,
    selector: 'album-display',
    templateUrl: './albumDisplay.html',
    animations: [
      slideIn
    ]
})
export class AlbumDisplay implements OnInit {
    slideInState = 'in';
    ...
}

25voto

Alexander Paul Points 325

C'est peut-être un peu tard, mais j'aimerais tout de même que l'on réponde à une version plus dynamique du déclencheur.

Mettre le code de déclenchement de l'animation dans un fichier séparé et l'exporter en tant que function .

translate.ts

import { AnimationEntryMetadata, trigger, state, style, transition, animate } from '@angular/core';

export function TranslateX( name: string, x: string, duration: number ): AnimationEntryMetadata {
    return trigger( name, [
            state('false', style({ transform: 'translateX(0)' }) ),
            state('true',  style({ transform: 'translateX(' + x + ')' }) ),
            transition('0 => 1', animate( duration + 'ms ease-in')),
            transition('1 => 0', animate( duration + 'ms ease-out')),
        ]);
}

donc, dans la composante app.component.ts

import { TranslateX } from './translate';

@Component({
    ...
    templateUrl: './app.component.html',
    animations:   [ 
                    TranslateX( 'trigger1Title','-100%', 200 ),
                    TranslateX( 'trigger2Title','20vw', 700 )
                  ]
    ...
})

et dans le modèle app.component.html

...
<div [@trigger1Title]="token1"> ... </div>
<div [@trigger2Title]="token2"> ... </div>
...

Vous pouvez personnaliser le déclencheur en y ajoutant d'autres données, par exemple en séparant les temps de transition, etc.

2voto

Jason Points 144

Exemple d'animation de routeur dans Angular 4

Je viens de m'attaquer moi-même aux animations de routeurs en utilisant Angular 4. Voici quelques exemples d'animations que j'ai créées pour une transition de fondu et une transition de glissement.

Vérifier ce poste pour plus de détails et une démonstration en direct.

Angular 4 Slide in/out animation

// import the required animation functions from the angular animations module
import { trigger, state, animate, transition, style } from '@angular/animations';
 
export const slideInOutAnimation =
    // trigger name for attaching this animation to an element using the [@triggerName] syntax
    trigger('slideInOutAnimation', [
 
        // end state styles for route container (host)
        state('*', style({
            // the view covers the whole screen with a semi tranparent background
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            backgroundColor: 'rgba(0, 0, 0, 0.8)'
        })),
 
        // route 'enter' transition
        transition(':enter', [
 
            // styles at start of transition
            style({
                // start with the content positioned off the right of the screen,
                // -400% is required instead of -100% because the negative position adds to the width of the element
                right: '-400%',
 
                // start with background opacity set to 0 (invisible)
                backgroundColor: 'rgba(0, 0, 0, 0)'
            }),
 
            // animation and styles at end of transition
            animate('.5s ease-in-out', style({
                // transition the right position to 0 which slides the content into view
                right: 0,
 
                // transition the background opacity to 0.8 to fade it in
                backgroundColor: 'rgba(0, 0, 0, 0.8)'
            }))
        ]),
 
        // route 'leave' transition
        transition(':leave', [
            // animation and styles at end of transition
            animate('.5s ease-in-out', style({
                // transition the right position to -400% which slides the content out of view
                right: '-400%',
 
                // transition the background opacity to 0 to fade it out
                backgroundColor: 'rgba(0, 0, 0, 0)'
            }))
        ])
    ]);

Angular 4 Fade in animation

// import the required animation functions from the angular animations module
import { trigger, state, animate, transition, style } from '@angular/animations';
 
export const fadeInAnimation =
    // trigger name for attaching this animation to an element using the [@triggerName] syntax
    trigger('fadeInAnimation', [
 
        // route 'enter' transition
        transition(':enter', [
 
            // css styles at start of transition
            style({ opacity: 0 }),
 
            // animation and styles at end of transition
            animate('.3s', style({ opacity: 1 }))
        ]),
    ]);

Composant avec transition attachée

import { Component } from '@angular/core';
 
// import fade in animation
import { fadeInAnimation } from '../_animations/index';
 
@Component({
    moduleId: module.id.toString(),
    templateUrl: 'home.component.html',
 
    // make fade in animation available to this component
    animations: [fadeInAnimation],
 
    // attach the fade in animation to the host (root) element of this component
    host: { '[@fadeInAnimation]': '' }
})
 
export class HomeComponent {
}

1voto

rcomblen Points 1463

La bonne solution consisterait à prendre en charge les animations dans les directives.

Ce n'est pas le cas, mais il y a une question à ce sujet sur le Github d'Angular : https://github.com/angular/angular/issues/9947

J'espère que le problème sera bientôt résolu.

1voto

woniel123mx Points 11

Avec une classe et vous pouvez étendre,

import { trigger, style, state, animate, transition, AnimationMetadata } from "@angular/core";
export class MyAwesomeAnimations {

    /**
     * 
     * @param nameTrigger Name of triggers
     * @param setNewsStates add states for animations
     * @param setNewTransitions add transitions for states
     */
    SetTrigger(nameTrigger: string, setNewsStates?: AnimationMetadata[], setNewTransitions?: AnimationMetadata[]): any {
        let metaData: AnimationMetadata[] = [
            state('*', style({
                transform: 'translateX(100%)',
            })),
            state('in', style({
                transform: 'translateX(0)',
            })),
            state('out', style({
                transform: 'translateX(-100%)',
            })),
            transition('* => in', animate('600ms ease-in')),
            transition('in => out', animate('600ms ease-in'))
        ];
        if (setNewsStates)
            metaData.concat(setNewsStates);
        if (setNewTransitions)
            metaData.concat(setNewTransitions);

        return trigger(nameTrigger, metaData);
    }
}

A utiliser

    @Component({
        selector: "orden-detail-component",
        animations: [new MyAwesomeAnimations().SetTrigger("slideIn")],
        template:"<div  class="container" [@slideIn]="slideInState">"
    })
    export class OrdenDetailComponent {
       slideInState = 'in';
    }

J'espère que ce moyen pourra vous aider

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