2016-09-13 5 views
31

Я играю с API-интерфейсом Animation, и я бы хотел создать многоразовую анимацию, например, скажем, скользящую по контенту для просмотров на верхнем уровне маршрутизатора. Мне удалось пройти через напуганный метаданный синтаксиса (который на самом деле довольно круто, когда вы преодолеваете сумасшедшую идею использования метаданных), чтобы заставить анимацию работать в основном.Как создать многоразовые анимации в 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'; 
     ... 
    } 

А потом назначая, что мой элемент верхнего уровня в компоненте:

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

Так что это работает, но как я могу сделать это для повторного использования? Я не хочу привязывать эти метаданные ко всем представлениям. Поскольку это метаданные, я не уверен, как вы могли бы сделать это многоразовым.

+0

Не забудьте ввести триггер: export const myTrigger: AnimationEntryMetadata = trigger (...... или вы получите ошибку сборки. – user2734839

ответ

58

Один из возможных способов - поместить анимационный триггерный код в отдельный файл и экспортировать его как переменную const и использовать ее в компоненте, как показано ниже.

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

альбом-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

Спасибо, что сработало отлично. После того, как изначально подумал WTF об этой фанковой мета-основе после создания нескольких, используя этот синтаксис, получается очень легко создавать анимации для компонентов. –

+0

Отлично работает. – Kwexi

+1

Это решение предотвратит использование AOT-компиляции:/ – VuuRWerK

0

Правильное решение будет иметь анимации, поддерживаемые в директивах.

Это не так, но есть вопрос для этого на Github ANGULAR в: https://github.com/angular/angular/issues/9947

Надеется, что он будет решен в ближайшее время.

1

С классом, и вы можете расширить,

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

Для использования

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

Я надеюсь, что способ может помочь вам

1

Router Animation Примера в Угловом 4

Я только что закончил работу с анимацией маршрутизации mys эльф, используя Angular 4, вот несколько примеров анимаций, которые я придумал для перехода в режим перехода и перехода в режиме ввода/вывода.

Отъезд this post для получения более подробной информации и живой демонстрации.

Угловое 4 слайдов в/из анимации

// 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 Проявление анимации

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

компонент с переходом прилагается

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

Хорошие примеры , Есть ли причина, по которой вы использовали абсолютное значение для перемещения вместо перевода, которое намного лучше оптимизировано? –

+0

@JJB Да, я использовал отрицательное правое положение, чтобы переместить форму, оставив фон на месте, чтобы исчезнуть, когда я попытался перевести его, он сдвигает форму и фон со страницы. Я не мог найти способ анимировать дочерние элементы в переходе ': leave', иначе я бы использовал отдельный div для фона и формы, где я мог бы использовать translate. Это единственный способ, которым я мог бы затухать в фоновом режиме и скользить в форме, используя только один элемент html. – Jason

16

Может быть, немного поздно, но я все равно хотел бы ответить на более динамическую версию триггера.

Поместите анимационный триггерный код в отдельный файл и экспортируйте его как 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')), 
     ]); 
} 

так, в компоненте app.component.ts

import { TranslateX } from './translate'; 

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

и в шаблоне app.component.html

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

Вы можете настроить триггер с большим количеством входных данных, например, отделить время перехода и т. Д.

+0

Это не сработает при использовании с компиляцией AOT – Dummy

+0

Ваше утверждение верное, только если для создания триггера используются классы, перечисления или внутренние вызовы для других функций. В настоящее время я работаю над Angular 4, TypeScript 2.4.2 и написано выше, все работает так, как я ожидаю. –

+0

Похоже, что это не сработает, если вы используете шаблонную строку (backticks) вместо традиционной конкатенации строк, используя знак плюса '+' – Dummy

Смежные вопросы