J'essaie de créer un effet de fondu croisé dans Angular mais les images continuent de pulser au lieu de se fondre les unes dans les autres. Comment puis-je y remédier?
animations.ts
export class AppComponent implements OnInit {
heroImageArray = [
"https://drscdn.500px.org/photo/277987267/q%3D80_m%3D2000/v2?webp=true&sig=082269b7b07ec17da1847d5c20cffee3a3a91af1f474eb3fd908eba828d5327c",
"https://drscdn.500px.org/photo/253947845/q%3D80_h%3D450/v2?webp=true&sig=c645b242f19581b17df5bc68d54ee4e5a3c2f5b1ddd41791683ed9c03c455151"
];
heroActiveImage: string =
"https://drscdn.500px.org/photo/277987267/q%3D80_m%3D2000/v2?webp=true&sig=082269b7b07ec17da1847d5c20cffee3a3a91af1f474eb3fd908eba828d5327c";
state = AnimationState.IN;
ngOnInit() {
this.toggleImg();
}
toggleImg() {
let count = 0;
setInterval(() => {
if (count === this.heroImageArray.length) {
count = 0;
}
this.heroActiveImage = this.heroImageArray[count];
count++;
}, 3000);
}
onDone() {
this.toggleState();
}
toggleState() {
this.state =
this.state === AnimationState.IN ? AnimationState.OUT : AnimationState.IN;
}
}
app.component.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(500)
])
])
];
export enum AnimationState {
IN = 'in',
OUT = 'out'
}
Stackblitz ici: https://stackblitz.com/edit/angular-anim-fade-img-gga34g
3 Réponses :
L'image doit être modifiée lorsque l'état est OUT, sinon elle va scintiller. J'ai bifurqué et mis à jour votre stackblitz , les changements sont dans les animations (l'animation a été effectuée à 1500 ms au lieu de 500 ms), et j'ai changé la première image en deuxième image du tableau (pour qu'elle ne scintille pas sur la même image.
edit: Je pense qu'il serait également préférable de changer l'image sur l'événement this.state === AnimationState.OUT lorsque this.state === AnimationState.OUT (vous savez donc que vous this.state === AnimationState.OUT lorsque l'image est effacée)
Cela semble encore un peu bogué lorsque l'image entre dans la première image. Comment puis-je réparer cela?
comme je l'ai dit, vous devriez changer l'image lorsque le fondu est terminé, consultez mon stackblitz mis à jour @methuselah
Merci cela fonctionne très bien, y a-t-il un moyen de ralentir la transition d'animation entre les photos
Il y avait quelques changements à effectuer mais en gros, j'ai changé la valeur passée à animate() de 500 à 2000 (pas de soucis, avec les changements maintenant, vous pouvez simplement ajuster le temps de transition que vous voulez en changeant la valeur passée à la fonction d'animation) , j'ai également déplacé le bloc de code pour changer l'image en fonction toggleState et réorganiser les chaînes dans heroImageArray (c'était pour éviter l'erreur que vous avez mentionnée à propos de la première image).
Ici vous avez le code https://stackblitz.com/edit/angular-anim-fade-img-yupxe1?file=app%2Fapp.component.ts
Remarque: pour ralentir ou accélérer la transition, il suffit de changer la valeur passée à la fonction d' animate .
Merci pour cela, comment régler la durée pendant laquelle l'image reste à l'écran?
Je comprends que vous voulez un délai après l'entrée de l'image. Dans ce cas, vous pouvez passer une chaîne à la fonction d'animation, comme cette animate("2s 1s") (soit 2 secondes de transition et 1 de retard). Vous devez également modifier l'appel de la fonction de transition car le délai s'appliquera pour in => out comme pour out => in créant un délai d'espace vide de 2 secondes. Vous devez avoir 2 appels de transition, la première transition("in => out", animate("2s 2s")) (cela définira le temps que l'image reste à 2 secondes. J'ai mis à jour le code, vous pouvez le vérifier pour info) et une seconde transition("out => in", animate("2s 0.5s")) .
Merci pour ce commentaire, @EliezerVerasVargas, je ne sais pas comment mettre en pause les animations -J'ai utilisé un marteau pour casser des noix, eh bien, vraiment une minuterie rxjs- :)
lorsque vous avez un éventail d'images, vous pouvez avoir une image et faire
onFade(event: any) {
if (event.fromState)
this.count = (this.count + 1) % this.imageArray.length;
this.toogle = !this.toogle;
}
onFade2(event: any) {
this.toogle2 = !this.toogle2;
if (event.fromState)
this.count2 = (this.count2 + 1) % this.imageArray.length;
}
ou avoir deux images (l'une sur l'autre) et faire
animations: [
trigger("fade", [
transition("false=>true", [
style({ opacity: 0 }),
animate("2500ms 2000ms", style({ opacity: 1 }))
])
]),
trigger("fade2", [
transition("false=>true", [
style({ opacity: 0 }),
animate("2500ms", style({ opacity: 1 }))
]),
transition("true=>false", [animate("2500ms 2000ms", style({ opacity: 0 }))])
])
]
J'ai mis les deux animations
onFade(event: any) {
timer(2000).subscribe(() => {
if (event.fromState)
this.count = (this.count + 1) % this.imageArray.length;
this.toogle = !this.toogle;
});
}
onFade2(event: any) {
if (!event.fromState) {
timer(2000).subscribe(() => {
this.toogle2 = !this.toogle2;
});
} else {
this.toogle2 = !this.toogle2;
if (event.fromState)
this.count2 = (this.count2 + 1) % this.imageArray.length;
}
}
(voir que "fondu" ne fait qu'un fondu). Si vous avez un tableau d'images - je suggère que, si vous faites un stackblitz, vous pouvez utiliser Lorem picsum comme à la place votre serveur ou un autre
<div style="position:relative">
<img [@fade]="toogle" style="position:absolute;z-index:10"
(@fade.done)="onFade($event)"
[src]="imageArray[count%imageArray.length]">
<img [src]="imageArray[(count+imageArray.length-1)%imageArray.length]">
</div>
Vous pouvez avoir un html comme
<img [@fade2]="toogle2"
(@fade2.done)="onFade2($event)"
[src]="imageArray[count2%imageArray.length]">
ou, si vous utilisez deux images
imageArray = [
"https://picsum.photos/200/300?random=1",
"https://picsum.photos/200/300?random=2",
....
];
Les fonctions onFade et onFade2 utilisent l'opérateur rxjs 'timer' pour maintenir les images visibles pendant le temps que vous choisissez
animations: [
trigger("fade", [
transition("false=>true", [
style({ opacity: 0 }),
animate("2500ms", style({ opacity: 1 }))
])
]),
trigger("fade2", [
transition("false=>true", [
style({ opacity: 0 }),
animate("2500ms", style({ opacity: 1 }))
]),
transition("true=>false", [animate("2500ms", style({ opacity: 0 }))])
])
]
Vous pouvez voir le stackblitz
Mis à jour grâce au commentaire d'Eliezer Vegas, j'ai pu améliorer le code afin de "mettre en pause" l'animation:
fade out --interchange the images --fade out --iterchange the images...
Et
fade out--change the image--fade in--fade-out--change the image--fade in-...