Skip to content

Commit

Permalink
fix(carousel): first image slides in for crossfade transition, animat…
Browse files Browse the repository at this point in the history
…ions refactor, closes #213 - thanks @baloo32
  • Loading branch information
xidedix committed Feb 6, 2025
1 parent b628ed1 commit ba6864a
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 144 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import { AfterContentChecked, AfterContentInit, Component, contentChildren, inject, signal } from '@angular/core';

import { fadeAnimation, slideAnimation } from '../carousel.animation';
import {
AfterContentChecked,
AfterContentInit,
Component,
computed,
contentChildren,
inject,
signal
} from '@angular/core';
import { CarouselItemComponent } from '../carousel-item/carousel-item.component';
import { CarouselState } from '../carousel-state';
import { carouselPlay } from '../carousel.animation';

@Component({
selector: 'c-carousel-inner',
templateUrl: './carousel-inner.component.html',
styleUrls: ['./carousel-inner.component.scss'],
animations: [slideAnimation, fadeAnimation],
animations: [carouselPlay],
template: '<ng-content />',
host: {
'[class.carousel-inner]': 'true'
class: 'carousel-inner',
'[@carouselPlay]': 'slideType()',
'[@.disabled]': '!animate()'
}
})
export class CarouselInnerComponent implements AfterContentInit, AfterContentChecked {
Expand All @@ -19,7 +28,11 @@ export class CarouselInnerComponent implements AfterContentInit, AfterContentChe
readonly activeIndex = signal<number | undefined>(undefined);
readonly animate = signal<boolean>(true);
readonly slide = signal({ left: true });
readonly transition = signal('slide');
readonly transition = signal('crossfade');

readonly slideType = computed(() => {
return { left: this.slide().left, type: this.transition() };
});

readonly contentItems = contentChildren(CarouselItemComponent);
readonly #prevContentItems = signal<CarouselItemComponent[]>([]);
Expand Down
258 changes: 126 additions & 132 deletions projects/coreui-angular/src/lib/carousel/carousel.animation.ts
Original file line number Diff line number Diff line change
@@ -1,142 +1,136 @@
import {
animate,
group,
query,
state,
style,
transition,
trigger,
} from '@angular/animations';
import { animate, animation, group, query, state, style, transition, trigger, useAnimation } from '@angular/animations';

export function toLeft(fromState: any, toState: any): boolean {
return toState.left === true;
export function toSlideLeft(fromState: any, toState: any): boolean {
return toState.left === true && toState.type === 'slide';
}
export function toRight(fromState: any, toState: any): boolean {
return toState.left === false;

export function toSlideRight(fromState: any, toState: any): boolean {
return toState.left === false && toState.type === 'slide';
}

export function toFadeLeft(fromState: any, toState: any): boolean {
return toState.left === true && toState.type !== 'slide';
}

export function toFadeRight(fromState: any, toState: any): boolean {
return toState.left === false && toState.type !== 'slide';
}

export const slideAnimation = trigger('slideAnimation', [
state(
'*',
style({ transform: 'translateX(0)', display: 'block', opacity: 1 })
),
transition(
toLeft,
group([
query(
':leave',
[
animate(
'0.6s ease-in-out',
style({
transform: 'translateX(-100%)',
})
),
],
{ optional: true }
),
query(
':enter',
[
export const slideAnimationLeft = animation(
group([
query(
':leave',
[
animate(
'0.6s ease-in-out',
style({
transform: 'translateX(100%)',
}),
animate('0.6s ease-in-out', style('*')),
],
{ optional: true }
),
])
),
transition(
toRight,
group([
query(
':enter',
[
transform: 'translateX(-100%)'
})
)
],
{ optional: true }
),
query(
':enter',
[
style({
transform: 'translateX(100%)'
}),
animate('0.6s ease-in-out', style('*'))
],
{ optional: true }
)
])
);

export const slideAnimationRight = animation(
group([
query(
':enter',
[
style({
transform: 'translateX(-100%)'
}),
animate('0.6s ease-in-out', style('*'))
],
{ optional: true }
),
query(
':leave',
[
animate(
'0.6s ease-in-out',
style({
transform: 'translateX(-100%)',
}),
animate('0.6s ease-in-out', style('*')),
],
{ optional: true }
),
query(
':leave',
[
animate(
'0.6s ease-in-out',
style({
transform: 'translateX(100%)',
})
),
],
{ optional: true }
),
])
),
]);
transform: 'translateX(100%)'
})
)
],
{ optional: true }
)
])
);

export const fadeAnimation = trigger('fadeAnimation', [
state(
'*',
style({ zIndex: 1, opacity: 1 })
),
transition(
toLeft,
group([
query(
':leave',
[
animate(
'0.6s ease-in-out',
style({
zIndex: 0,
opacity: 0,
})
),
],
{ optional: true }
),
query(
':enter',
[
export const fadeAnimationLeft = animation(
group([
query(
':leave',
[
animate(
'0.9s ease-in-out',
style({
zIndex: 1,
opacity: 1
}),
animate('0.6s ease-in-out', style('*')),
],
{ optional: true }
),
])
),
transition(
toRight,
group([
query(
':enter',
[
zIndex: 0,
opacity: 0
})
)
],
{ optional: true }
),
query(
':enter',
[
style({
zIndex: 1,
opacity: 1
}),
animate('0.6s ease-in-out', style('*'))
],
{ optional: true }
)
])
);
export const fadeAnimationRight = animation(
group([
query(
':enter',
[
style({
zIndex: 1,
opacity: 1
}),
animate('0.6s ease-in-out', style('*'))
],
{ optional: true }
),
query(
':leave',
[
animate(
'0.9s ease-in-out',
style({
zIndex: 1,
opacity: 1
}),
animate('0.6s ease-in-out', style('*')),
],
{ optional: true }
),
query(
':leave',
[
animate(
'0.6s ease-in-out',
style({
zIndex: 0,
opacity: 0,
})
),
],
{ optional: true }
),
])
),
zIndex: 0,
opacity: 0
})
)
],
{ optional: true }
)
])
);

export const carouselPlay = trigger('carouselPlay', [
state('*', style({ transform: 'translateX(0)', display: 'block', opacity: 1 })),
transition(toFadeLeft, useAnimation(fadeAnimationLeft)),
transition(toFadeRight, useAnimation(fadeAnimationRight)),
transition(toSlideLeft, useAnimation(slideAnimationLeft)),
transition(toSlideRight, useAnimation(slideAnimationRight))
]);
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { CarouselConfig } from '../carousel.config';
exportAs: 'cCarousel',
host: {
class: 'carousel slide',
'[class.carousel-fade]': 'transition() === "crossfade"'
'[class.carousel-fade]': 'transition() === "crossfade" && animate()'
}
})
export class CarouselComponent implements OnInit, OnDestroy, AfterContentInit {
Expand Down Expand Up @@ -148,7 +148,11 @@ export class CarouselComponent implements OnInit, OnDestroy, AfterContentInit {

ngAfterContentInit(): void {
this.intersectionServiceSubscribe();
this.#carouselState.state = { activeItemIndex: this.activeIndex(), animate: this.animate() };
this.#carouselState.state = {
activeItemIndex: this.activeIndex(),
animate: this.animate(),
transition: this.transition()
};
this.setListeners();
this.swipeSubscribe();
}
Expand Down

0 comments on commit ba6864a

Please sign in to comment.