在 Angular 4 中动画图像交换(在 AngularJS 中是 ng-animate-swap)
Posted
技术标签:
【中文标题】在 Angular 4 中动画图像交换(在 AngularJS 中是 ng-animate-swap)【英文标题】:Animate an image swap in Angular 4 (Was ng-animate-swap in AngularJS) 【发布时间】:2018-05-12 07:12:36 【问题描述】:我想在 Angular 4 应用程序中为图像交换设置动画。当控制器替换 img src 属性时,旧图像应该消失并出现新图像。
在 AngularJS 中,这可以通过使用 ng-animate-swap 更改不透明度来实现。但是,Angular 4 似乎不支持动画交换。如果没有交换触发器,如何实现这一点?
我尝试为 src 属性添加从 void 到 * 并返回的转换,但这不能按预期工作。第一张图片是动画的,后来交换发生时没有动画。
@Component(
selector: 'app-play-card',
template: '<div (click)="loadImg()"><img [@fade]="imgsrc" src=" imgsrc " /></div>',
styleUrls: ['./play-card.component.css'],
animations: [
trigger('fade', [
transition('void => *', [
style(opacity: 0.1),
animate(5000, style(opacity: 1))
]),
transition('* => void', [
style(opacity: 0.9),
animate(5000, style(opacity: 0))
])
])
]
)
【问题讨论】:
***.com/questions/64848450/… 【参考方案1】:这是我使用 Angular 动画状态的方法:
animations.ts
import trigger, style, animate, transition, state from '@angular/animations';
export const fade = [
trigger('fade', [
state('in', style( 'opacity': '1' )),
state('out', style( 'opacity': '0' )),
transition('* <=> *', [
animate(1000)
])
])
];
app.component.html
<img [@fade]="state" (@fade.done)="onDone($event)" [src]="imageSource" (click)="onClick()" />
我使用了(@fade.done)
,这是 Angular 动画的一个功能,允许您在动画完成后调用方法。
在这里,一旦第一个动画褪色到不透明度为 0,我更改了图像路径,并更改了动画状态,再次褪色并将不透明度值恢复为 1。
app.component.ts
export class AppComponent implements OnInit
choice = 2;
state = 'in';
counter = 0;
enableAnimation = false;
imageSource = '';
imgSrc1 = 'firstPath';
imgSrc2 = 'secondPath';
ngOnInit()
this.imageSource = this.imgSrc1;
onClick()
this.enableAnimation = true;
this.counter = 0;
this.toggleState();
toggleImg()
if (this.choice === 1)
this.imageSource = this.imgSrc1;
this.choice = 2;
else
this.imageSource = this.imgSrc2;
this.choice = 1;
onDone($event)
if (this.enableAnimation)
if (this.counter === 1)
this.toggleImg();
this.toggleState();
toggleState()
if (this.counter < 2)
this.state = this.state === 'in' ? 'out' : 'in';
this.counter++;
这显然是一个小动画的大量代码。
这是我为此制作的 StackBlitz 示例:https://stackblitz.com/edit/angular-anim-fade-img
【讨论】:
不幸的是,这个解决方案毕竟不实用。我的图像是通过慢速网络加载的,并且在淡出完成时不在缓存中。结果,当调用切换图像并开始淡入淡出阶段时,我会在短时间内继续看到旧图像。仅在明显延迟后,新图像加载完成并替换旧图像。淡入淡出在这一点上如火如荼。 您可以通过在文档中抓取“img”元素并等待“完成”来解决此问题。使用两个图像元素(而不是一个)。开始在背景中加载“切换”图像(将其不透明度保持为 0 直到它“完成”),然后您就可以真正启用淡入动画了!【参考方案2】:我确实尽可能地过滤掉,以免代码过载。 我希望代码足够简单,您可以集成它。
gallery.component.ts
:
import Component, Input from '@angular/core';
import trigger, style, animate, transition from '@angular/animations';
const animations = trigger('imgAnimation', [
transition(':enter', [
style( opacity: 0 ),
animate('500ms', style( opacity: 1 )),
]),
transition(':leave', [
animate('300ms', style( opacity: 0 ))
])
]);
@Component(
selector: 'app-gallery',
templateUrl: './gallery.component.html',
styleUrls: [],
animations: [animations]
)
export class GalleryComponent
@Input() images: string[];
index: number = 0;
imageIndex: number = 0;
onIncIndex(increment: number = 1)
this.index = (this.index + this.images.length + increment) % this.images.length;
this.imageIndex = null;
onDone()
this.imageIndex = this.index;
gallery.component.html
:
<picture>
<ng-container *ngFor="let img of images; index as i">
<img *ngIf="i === imageIndex"
@imgAnimation
(@imgAnimation.done)="onDone()"
[src]="img">
</ng-container>
</picture>
<div>
<button (click)="onIncIndex(-1)">Previous</button>
<button (click)="onIncIndex()">Next</button>
</div>
【讨论】:
【参考方案3】:如果您正在使用 2 张图片....您可以这样做..
<mat-icon>
<img
[@fadeIn]
*ngIf="myBool"
src="assets/svg-icons/back.svg"
/>
<img
[@fadeIn]
*ngIf="!myBool"
src="assets/svg-icons/close.svg"
/>
</mat-icon>
您将只想为进入状态设置动画,否则对于一个实例,两个图像将并排显示
trigger('fadeIn', [
transition(':enter', [style( opacity: 0 ), animate(160)]),
// transition(':leave', [animate(160, style( opacity: 0 ))]),
]),
您可以解决问题并将图像设为绝对,然后您可以为进入和离开状态设置动画(因为这次图像将相互重叠)
【讨论】:
以上是关于在 Angular 4 中动画图像交换(在 AngularJS 中是 ng-animate-swap)的主要内容,如果未能解决你的问题,请参考以下文章