Why is the animation playing for both instances of the carousel component when interacting with just one call (e.g. clicking next or prev)?
carousel.component.ts
@Component({
selector: 'app-carousel',
standalone: true,
templateUrl: './carousel.component.html',
imports:[ CommonModule ],
styleUrls: ['./carousel.component.scss'],
animations: [ CarouselAnimation ]
})
export class CarouselComponent {
@Input() items: string[] = [];
@Input() itemsPerSlide: number = 0;
@Input() carouselName:string = "";
currentIndex: number = 0;
hasNextItems: boolean = true;
get groupedItems(): string[][] {
const result: string[][] = [];
for (let i = 0; i < this.items.length; i += this.itemsPerSlide) {
result.push(this.items.slice(i, i + this.itemsPerSlide));
}
return result;
}
next() {
const nextIndex = (this.currentIndex + 1) % this.groupedItems.length;
this.hasNextItems = this.groupedItems[nextIndex].length > 0;
if (this.hasNextItems) {
this.currentIndex = nextIndex;
}
}
prev() {
const prevIndex = (this.currentIndex - 1 + this.groupedItems.length) % this.groupedItems.length;
const prevItemsPerSlide = this.groupedItems[prevIndex].length;
if (prevItemsPerSlide > 0) {
this.hasNextItems = true;
this.currentIndex = (this.currentIndex - 1 + this.groupedItems.length) % this.groupedItems.length;
}
}
}
carousel.component.html
<div id="UniqueDynamicCarousel" class="carousel slide carousel-fade" data-ride="carousel">
<div class="carousel-inner">
<div *ngFor="let itemGroup of groupedItems; let i = index" [class.active]="i === currentIndex" class="carousel-item" [@carouselFade]>
<div class="d-flex justify-content-around">
<div *ngFor="let item of itemGroup" class="carousel-inner-item">
<img class="d-block w-100" [src]="item" alt="Slide {{i + 1}}">
</div>
</div>
</div>
</div>
<a class="carousel-prev" href="#UniqueDynamicCarousel" role="button" data-slide="prev" (click)="prev()">
<div class="icon-container">
<i class="fa fa-solid fa-arrow-left"></i>
</div>
</a>
<a class="carousel-next" href="#UniqueDynamicCarousel" role="button" data-slide="next" (click)="next()">
<div class="icon-container">
<i class="fa fa-solid fa-arrow-right"></i>
</div>
</a>
</div>
animations.ts
export const CarouselAnimation = [
trigger('carouselFade', [
transition(':enter', [
style({ opacity: 0 }),
animate('300ms ease-in', style({ opacity: 1 }))
]),
transition(':leave', [
animate('300ms ease-out', style({ opacity: 0 }))
])
])
]
Usage
<h2>Carousel</h2>
<app-carousel [items]="carouselItems" [itemsPerSlide]="3" [carouselName]="'Carousel'"></app-carousel>
<h2>Carousel2</h2>
<app-carousel [items]="carouselItems2" [itemsPerSlide]="3" [carouselName]="'Carousel2'"></app-carousel>
carousel item arrays:
carouselItems: string[] = [
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
];
carouselItems2: string[] = [
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
'https://via.placeholder.com/800x400',
];
- Changed the trigger name to be unique.
- Assigned a unique id to the carousel.
- Attempted code duplication as a workaround.