2016-09-13 22 views
31

Gram z interfejsem API animacji i chciałbym utworzyć animację wielokrotnego użytku, np. Przesuwając zawartość dla widoków routera najwyższego poziomu. Udało mi się przejść przez funky składni meta-danych (co jest całkiem fajne, gdy tylko minie szalony pomysł użycia metadanych), aby animacje działały.W jaki sposób utworzyć animacje wielokrotnego użytku w Angular 2

@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'; 
     ... 
    } 

A potem przypisanie że do mojego poziomu górnego elementu w komponencie:

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

Tak to działa, ale w jaki sposób mogę zrobić to wielokrotnego użytku? Nie chcę trzymać tych metadanych na każdym widoku. Ponieważ to są metadane, nie jestem pewien, w jaki sposób można to zrobić do ponownego użycia.

+0

Nie zapomnij wpisać wyzwalacza: export const myTrigger: AnimationEntryMetadata = trigger (...... albo otrzymasz błąd kompilacji – user2734839

Odpowiedz

58

Jednym z możliwych sposobów jest umieszczenie kodu wyzwalacza animacji w oddzielnym pliku i wyeksportowanie go jako zmiennej const i użycie go w komponencie jak poniżej.

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'; 
    ... 
} 
+0

Dziękuję, że zadziałało idealnie Po początkowym myśleniu WTF o tym funkowym meta Wdrożenie, po utworzeniu kilku przy użyciu tej składni, okazuje się bardzo łatwe do tworzenia animacji dla komponentów –

+0

Działa świetnie Nic ładniej zrobione – Kwexi

+1

To rozwiązanie uniemożliwi korzystanie z kompilacji AOT:/ – VuuRWerK

1

z klasą i można rozszerzyć,

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

Do stosowania

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

Mam nadzieję, że w ten sposób może pomóc

1

Router Animacja przykład w kątowe 4

Właśnie skończyłem radzić sobie z animacjami routera mys elf używa Angular 4, oto kilka przykładowych animacji, które wymyśliłem, by uzyskać efekt przejścia i przejścia między slajdami.

Aby uzyskać więcej informacji i wersję demonstracyjną na żywo, sprawdź numer this post.

kątowe 4 Przesuń w/animację

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

kątowe 4 Przenikanie animacji

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

Component przejścia przyłączone

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 { 
} 
+0

Dobre przykłady . Czy jest jakiś powód, dla którego użyłeś bezwzględnego do przenoszenia zamiast tłumaczyć, co jest o wiele lepiej zoptymalizowane? –

+0

@JJB Tak Użyłem ujemnej prawej pozycji, aby przenieść formularz, pozostawiając tło w miejscu, aby zanikać, kiedy próbowałem z tłumaczeniem, przesuwa formularz i tło ze strony. Nie mogłem znaleźć sposobu na animowanie elementów potomnych na przejściu ": zostaw", w przeciwnym razie użyłbym oddzielnego elementu div dla tła i formularza, w którym mogłem użyć translate. Jest to jedyny sposób, w jaki mógłbym znaleźć się w tle i przesuwać w formie używając tylko jednego elementu html. – Jason

16

Może to trochę za późno, ale nadal chciałbym podać odpowiedź na bardziej dynamiczną wersję spustu.

Umieść kod wyzwalacza animacji w osobnym pliku i wyeksportuj go jako 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')), 
     ]); 
} 

więc, w komponencie app.component.ts

import { TranslateX } from './translate'; 

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

w szablonie app.component.html

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

Możesz spersonalizować wyzwalacz za pomocą większej ilości danych wejściowych, na przykład oddzielając czasy przejścia i tak dalej.

+0

To się nie powiedzie, gdy jest używane z kompilacją AOT. – Dummy

+0

Twoje zdanie jest poprawne, tylko jeśli do zbudowania wyzwalacza używane są klasy, wyliczenia lub połączenia wewnętrzne z innymi funkcjami. Obecnie pracuję nad Angular 4, TypeScript 2.4.2 i napisałem jak wyżej, wszystko działa zgodnie z oczekiwaniami. –

+0

Wygląda na to, że nie powiedzie się, jeśli użyjesz ciągu szablonów (backticks) zamiast tradycyjnego łączenia ciągów znaków plus "+" – Dummy

Powiązane problemy