feat: add animation for opening and closing OverlayComponent and optimize code
This commit is contained in:
parent
a013402e23
commit
19f1a2de5a
3 changed files with 74 additions and 35 deletions
|
|
@ -1,5 +1,8 @@
|
|||
@if (overlayData) {
|
||||
<div class="overlay">
|
||||
<div
|
||||
class="overlay"
|
||||
[class.show]="shouldShowOverlay"
|
||||
[class.closing]="isClosingAnimation"
|
||||
>
|
||||
<div class="overlay-content">
|
||||
@if (overlayType === "taskOverlay") {
|
||||
<app-task-overlay
|
||||
|
|
@ -18,7 +21,7 @@
|
|||
[overlayType]="overlayType"
|
||||
(closeDialogEmitter)="onCloseOverlay($event)"
|
||||
></app-task-edit-overlay>
|
||||
} @if (overlayType === "dialog") {
|
||||
} @if (overlayType === "dialogOverlay") {
|
||||
<app-dialog-overlay
|
||||
[overlayData]="overlayData"
|
||||
[overlayType]="overlayType"
|
||||
|
|
@ -33,4 +36,3 @@
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
.overlay {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
|
@ -7,20 +10,38 @@
|
|||
width: 100vw;
|
||||
height: 100vh;
|
||||
backdrop-filter: blur(5px);
|
||||
background-color: rgba($color: #000000, $alpha: 0.2);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
pointer-events: none;
|
||||
transition: opacity 0.3s ease, backdrop-filter 0.3s ease;
|
||||
z-index: 999;
|
||||
opacity: 0;
|
||||
|
||||
&.show {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
|
||||
& > .overlay-content {
|
||||
transform: scale(1) translateY(0);
|
||||
opacity: 1;
|
||||
transition: transform 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55),
|
||||
opacity 0.4s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.overlay-mobile {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 999;
|
||||
&.closing {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
& > .overlay-content {
|
||||
transform: scale(0.95) translateY(20px);
|
||||
opacity: 0;
|
||||
transition: transform 0.4s ease-in, opacity 0.4s ease-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overlay-content {
|
||||
transform: scale(0.95) translateY(20px);
|
||||
opacity: 0;
|
||||
transition: transform 0.4s ease-out, opacity 0.4s ease-out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,21 +22,31 @@ import { Subject, takeUntil } from 'rxjs';
|
|||
styleUrl: './overlay.component.scss',
|
||||
})
|
||||
export class OverlayComponent implements OnInit, OnDestroy {
|
||||
overlayType: any;
|
||||
overlayData: any;
|
||||
overlayType:
|
||||
| 'taskOverlay'
|
||||
| 'taskOverlayEdit'
|
||||
| 'newTaskOverlay'
|
||||
| 'dialogOverlay'
|
||||
| 'contactOverlay'
|
||||
| null = null;
|
||||
overlayData: any = null;
|
||||
shouldShowOverlay = false;
|
||||
isClosingAnimation = false;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(private overlayService: OverlayService, private router: Router) {}
|
||||
|
||||
/**
|
||||
* Angular lifecycle hook that is called after the component's view has been fully initialized.
|
||||
* Invokes `checkOverlayData` to subscribe to overlay data changes and update the component's state accordingly.
|
||||
* Checks the overlay data observable from the OverlayService and subscribes to it.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.checkOverlayData();
|
||||
this.listenToOverlayChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event to stop listening to the overlay data observable and unsubscribes from it.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
|
|
@ -44,40 +54,46 @@ export class OverlayComponent implements OnInit, OnDestroy {
|
|||
|
||||
/**
|
||||
* Subscribes to the overlay data observable from the OverlayService.
|
||||
* Updates the component's `overlayType` and `overlayData` properties
|
||||
* whenever new overlay data is emitted.
|
||||
* Updates the overlay type and data when new data is received.
|
||||
* Sets the overlay as visible with a slight delay if data is present.
|
||||
* Marks the overlay as closing and invisible if no data is present.
|
||||
*/
|
||||
checkOverlayData() {
|
||||
listenToOverlayChanges() {
|
||||
this.overlayService.overlayData$
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((data) => {
|
||||
if (data) {
|
||||
this.overlayType = data.overlay;
|
||||
this.overlayData = data.data;
|
||||
this.isClosingAnimation = false;
|
||||
requestAnimationFrame(() => {
|
||||
this.shouldShowOverlay = true;
|
||||
});
|
||||
} else {
|
||||
this.isClosingAnimation = true;
|
||||
this.shouldShowOverlay = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event to close the overlay and set the overlay type/data to the provided string.
|
||||
* If the overlay type is 'dialog', navigates to the login route.
|
||||
* @param emitter The string to be emitted, which will also be set as the overlay data.
|
||||
* Closes the overlay by clearing the overlay data from the service.
|
||||
* @param {boolean} close Indicates the close event.
|
||||
*/
|
||||
onCloseOverlay(emitter: boolean) {
|
||||
this.overlayData = emitter;
|
||||
onCloseOverlay(close: boolean) {
|
||||
this.overlayData = close;
|
||||
this.overlayService.clearOverlayData();
|
||||
}
|
||||
|
||||
@HostListener('document:click', ['$event'])
|
||||
/**
|
||||
* Closes the contact edit overlay if the user clicks on the overlay background.
|
||||
*
|
||||
* @param event The MouseEvent triggered by a click action.
|
||||
* If the event target is the overlay itself, the overlay is closed.
|
||||
* @param {MouseEvent} event The event object passed from the document click event.
|
||||
*/
|
||||
checkOpenContactEdit(event: MouseEvent) {
|
||||
onDocumentClick(event: MouseEvent) {
|
||||
const targetElement = event.target as HTMLElement;
|
||||
|
||||
if (targetElement === document.querySelector('.overlay')) {
|
||||
if (targetElement && targetElement.classList.contains('overlay')) {
|
||||
this.onCloseOverlay(false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue