Angular 2 - 如何在指令上设置动画?
Angular 2 - How to set animations on a Directive?
我有一个 Directive
我可以放置检查相关元素当前滚动位置的元素。
看起来像这样:
@Directive({
selector: '[my-scroll-animation]'
})
每当位置满足某个阈值时,我希望该元素使用动画出现在屏幕上。我知道对于 Component
我可以附加一个 animations
属性 以及 host
属性 中的一些设置来激活动画。
我想要这样的东西:
import { myScrollAnimation } from './animations';
@Directive({
selector: '[my-scroll-animation]'
animations: [myScrollAnimation] // <- not possible?
})
如何在指令中实现这一点?
使用:Angular 4.0.0-rc.4
正如我在你问题的评论部分中提到的那样。
您可以在父组件中配置动画。
然后指令在满足阈值时在其主机上添加一个class。
在你的指令中,你可以有这样的东西:
@Input() classThatTriggersAnimation = "do-animation";
@HostBinding('[@nameOfAnimation]') animationTrigger = "";
// when logic is true
this.animationTrigger = this.classThatTriggersAnimation;
这是 open issue(今天 - 28/08/17)在 Angular 的 git 存储库中。请对这个问题进行投票,以向开发人员施加压力以更快地发布此问题。
我使用了一些基于 this 对 benshabatnoam 的回答中提到的问题的回应的解决方法。
指令实际上只是没有模板的组件。您可以使用属性选择器(例如:[selector]
)创建一个与指令相同的组件,并制作模板:<ng-content></ng-content>
.
因此,您可以像这样创建一个 'foux-directive' 组件:
@Component({
selector: '[fadeInAnimation]',
animations: [
trigger('fadeIn', [
transition(':enter', [
style({opacity:'0'}),
animate(200, style({opacity:'1'}))
])
])
],
template: `<ng-content></ng-content>`,
})
export class FadeInDirective {
@HostBinding('@fadeIn') trigger = '';
}
并像使用任何指令一样使用它:
<div fadeInAnimation> something I want to animate </div>
Angular 4.2 带来了大量的动画改进。其中之一是 AnimationBuilder,它允许以编程方式构建动画。
您只需在指令中注入 AnimationBuilder,即可将任何 AnimationMetadata 转换为工作动画。
@Directive({
selector: '[zetFadeInOut]',
})
export class FadeInOutDirective {
player: AnimationPlayer;
@Input()
set show(show: boolean) {
if (this.player) {
this.player.destroy();
}
const metadata = show ? this.fadeIn() : this.fadeOut();
const factory = this.builder.build(metadata);
const player = factory.create(this.el.nativeElement);
player.play();
}
constructor(private builder: AnimationBuilder, private el: ElementRef) {}
private fadeIn(): AnimationMetadata[] {
return [
style({ opacity: 0 }),
animate('400ms ease-in', style({ opacity: 1 })),
];
}
private fadeOut(): AnimationMetadata[] {
return [
style({ opacity: '*' }),
animate('400ms ease-in', style({ opacity: 0 })),
];
}
}
我们开始吧。适合小动画。
我直接用AnimationPlayer + AnimationBuilder => No need to artificially toggle a state forth + back to trigger the animation. Inspired by and further reduced from this snippet.
import { Directive, Input, HostListener } from '@angular/core';
import { ElementRef } from '@angular/core';
import {
AnimationPlayer,
AnimationBuilder
} from '@angular/animations';
@Directive({
selector: '[clickAnimation]',
})
export class ClickAnimationDirective {
private player: AnimationPlayer;
@Input() clickAnimation: any;
@HostListener('click', ['$event'])
onClick() {
// sanitize just in case
if (this.player) { this.player.destroy(); }
const factory = this.builder.build(this.clickAnimation);
const player = factory.create(this.el.nativeElement);
// ensure back-to-original
player.onDone(() => { player.reset(); });
player.play();
}
constructor(private builder: AnimationBuilder, private el: ElementRef) { }
}
在您的模板中:
<app-button
[clickAnimation]="trafficLight"
...
在你的组件中 class:
public trafficLight: AnimationMetadata[] = [
style({ borderColor: 'red' }),
animate('400ms ease-in', style({ borderColor: 'yellow' })),
animate('400ms ease-in', style({ borderColor: 'cyan' })),
//alternative way to ensure back to original
// animate('400ms ease-in', style({ borderColor: '*' })),
];
我有一个 Directive
我可以放置检查相关元素当前滚动位置的元素。
看起来像这样:
@Directive({
selector: '[my-scroll-animation]'
})
每当位置满足某个阈值时,我希望该元素使用动画出现在屏幕上。我知道对于 Component
我可以附加一个 animations
属性 以及 host
属性 中的一些设置来激活动画。
我想要这样的东西:
import { myScrollAnimation } from './animations';
@Directive({
selector: '[my-scroll-animation]'
animations: [myScrollAnimation] // <- not possible?
})
如何在指令中实现这一点?
使用:Angular 4.0.0-rc.4
正如我在你问题的评论部分中提到的那样。
您可以在父组件中配置动画。 然后指令在满足阈值时在其主机上添加一个class。
在你的指令中,你可以有这样的东西:
@Input() classThatTriggersAnimation = "do-animation";
@HostBinding('[@nameOfAnimation]') animationTrigger = "";
// when logic is true
this.animationTrigger = this.classThatTriggersAnimation;
这是 open issue(今天 - 28/08/17)在 Angular 的 git 存储库中。请对这个问题进行投票,以向开发人员施加压力以更快地发布此问题。
我使用了一些基于 this 对 benshabatnoam 的回答中提到的问题的回应的解决方法。
指令实际上只是没有模板的组件。您可以使用属性选择器(例如:[selector]
)创建一个与指令相同的组件,并制作模板:<ng-content></ng-content>
.
因此,您可以像这样创建一个 'foux-directive' 组件:
@Component({
selector: '[fadeInAnimation]',
animations: [
trigger('fadeIn', [
transition(':enter', [
style({opacity:'0'}),
animate(200, style({opacity:'1'}))
])
])
],
template: `<ng-content></ng-content>`,
})
export class FadeInDirective {
@HostBinding('@fadeIn') trigger = '';
}
并像使用任何指令一样使用它:
<div fadeInAnimation> something I want to animate </div>
Angular 4.2 带来了大量的动画改进。其中之一是 AnimationBuilder,它允许以编程方式构建动画。
您只需在指令中注入 AnimationBuilder,即可将任何 AnimationMetadata 转换为工作动画。
@Directive({
selector: '[zetFadeInOut]',
})
export class FadeInOutDirective {
player: AnimationPlayer;
@Input()
set show(show: boolean) {
if (this.player) {
this.player.destroy();
}
const metadata = show ? this.fadeIn() : this.fadeOut();
const factory = this.builder.build(metadata);
const player = factory.create(this.el.nativeElement);
player.play();
}
constructor(private builder: AnimationBuilder, private el: ElementRef) {}
private fadeIn(): AnimationMetadata[] {
return [
style({ opacity: 0 }),
animate('400ms ease-in', style({ opacity: 1 })),
];
}
private fadeOut(): AnimationMetadata[] {
return [
style({ opacity: '*' }),
animate('400ms ease-in', style({ opacity: 0 })),
];
}
}
我们开始吧。适合小动画。
我直接用AnimationPlayer + AnimationBuilder => No need to artificially toggle a state forth + back to trigger the animation. Inspired by and further reduced from this snippet.
import { Directive, Input, HostListener } from '@angular/core';
import { ElementRef } from '@angular/core';
import {
AnimationPlayer,
AnimationBuilder
} from '@angular/animations';
@Directive({
selector: '[clickAnimation]',
})
export class ClickAnimationDirective {
private player: AnimationPlayer;
@Input() clickAnimation: any;
@HostListener('click', ['$event'])
onClick() {
// sanitize just in case
if (this.player) { this.player.destroy(); }
const factory = this.builder.build(this.clickAnimation);
const player = factory.create(this.el.nativeElement);
// ensure back-to-original
player.onDone(() => { player.reset(); });
player.play();
}
constructor(private builder: AnimationBuilder, private el: ElementRef) { }
}
在您的模板中:
<app-button
[clickAnimation]="trafficLight"
...
在你的组件中 class:
public trafficLight: AnimationMetadata[] = [
style({ borderColor: 'red' }),
animate('400ms ease-in', style({ borderColor: 'yellow' })),
animate('400ms ease-in', style({ borderColor: 'cyan' })),
//alternative way to ensure back to original
// animate('400ms ease-in', style({ borderColor: '*' })),
];