web-dev-qa-db-fra.com

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

Je joue avec l'API d'animation et j'aimerais créer une animation réutilisable, par exemple en glissant du contenu pour les vues de routeur de niveau supérieur. J'ai réussi à comprendre la syntaxe géniale des méta-données (ce qui est en fait plutôt cool une fois dépassée la folle idée d'utiliser des métadonnées) pour que la plupart des animations fonctionnent 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';
      ...
  }

Et puis assigner cela à mon élément de niveau supérieur dans le composant:

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

Cela fonctionne donc, mais comment puis-je le rendre réutilisable? Je ne veux pas coller cette méta-donnée sur chaque vue. Comme il s’agit de métadonnées, je ne sais pas comment vous pourriez rendre cela réutilisable.

50
Rick Strahl

Une solution possible consiste à placer le code du déclencheur d’animation dans un fichier séparé, à l’exporter sous la forme de variable const et à l’utiliser dans le composant 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';
    ...
}
85
ranakrunal9

C'est peut-être un peu tard, mais j'aimerais quand même mettre une réponse pour une version plus dynamique du déclencheur.

Placez le code du déclencheur d'animation dans un fichier séparé et exportez-le sous le nom 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')),
        ]);
}

oui, dans le composant 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 avec davantage de données d'entrée, par exemple en séparant les temps de transition, etc.

24
Alexander Paul

Exemple d'animation de routeur in Angular 4

Je viens juste de finir de m'occuper moi-même des animations de routeur en utilisant Angular 4, voici quelques exemples d'animations que j'ai créés pour une transition en fondu en entrée et une transition par glisser-déposer).

Départ ce post pour plus de détails et une démo en direct.

Animation angulaire 4 avec insertion/sortie

// 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)'
            }))
        ])
    ]);

4 angulaire Fondu dans l'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 {
}
2
Jason

Une solution appropriée consisterait à prendre en charge les animations dans les directives.

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

J'espère que cela sera bientôt résolu.

1
rcomblen

Avec une classe et vous pouvez prolongé,

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);
    }
}

Pour utilisation

    @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 ça peut vous aider

1
woniel123mx