animaciones prueba
This commit is contained in:
parent
8fdba09449
commit
fb26d54079
108
src/app/README-ROUTE-ANIMATIONS.md
Normal file
108
src/app/README-ROUTE-ANIMATIONS.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# Animaciones de Ruta en PrimeNG Cronogramas
|
||||||
|
|
||||||
|
Esta documentación explica cómo se implementaron las animaciones durante la navegación entre rutas en la aplicación.
|
||||||
|
|
||||||
|
## Componentes Principales
|
||||||
|
|
||||||
|
La solución consta de tres partes principales:
|
||||||
|
|
||||||
|
1. **RouteAnimationsComponent**: Un componente contenedor para el router-outlet que aplica animaciones.
|
||||||
|
2. **CustomRouteReuseStrategy**: Una estrategia personalizada que fuerza la recreación de componentes.
|
||||||
|
3. **Configuración en app.config.ts**: Donde registramos la estrategia personalizada.
|
||||||
|
|
||||||
|
## Cómo Funciona
|
||||||
|
|
||||||
|
### 1. Componente de Animaciones de Ruta
|
||||||
|
|
||||||
|
El `RouteAnimationsComponent` envuelve el router-outlet estándar y aplica una clase de animación aleatoria cada vez que ocurre una navegación.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/app/components/route-animations/route-animations.component.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Este componente:
|
||||||
|
- Se suscribe a los eventos de navegación del router
|
||||||
|
- Elimina brevemente la clase de animación
|
||||||
|
- Aplica una nueva animación aleatoria
|
||||||
|
- Todo esto crea un efecto de "reinicio" de la animación en cada navegación
|
||||||
|
|
||||||
|
### 2. Estrategia de Reuso de Rutas
|
||||||
|
|
||||||
|
Angular por defecto reutiliza componentes cuando navega entre rutas similares para optimizar el rendimiento. Sin embargo, para nuestras animaciones, necesitamos que los componentes se recreen.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/app/utils/custom-route-reuse-strategy.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Esta clase implementa `RouteReuseStrategy` y:
|
||||||
|
- Evita almacenar o recuperar componentes desactivados
|
||||||
|
- Solo reutiliza componentes cuando son exactamente la misma ruta
|
||||||
|
- Fuerza la recreación del componente en cada navegación
|
||||||
|
|
||||||
|
### 3. Configuración en app.config.ts
|
||||||
|
|
||||||
|
Registramos nuestra estrategia personalizada en el archivo de configuración de la aplicación:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/app/app.config.ts
|
||||||
|
{
|
||||||
|
provide: RouteReuseStrategy,
|
||||||
|
useClass: CustomRouteReuseStrategy
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Integración con el Layout
|
||||||
|
|
||||||
|
En el layout principal, reemplazamos el router-outlet estándar con nuestro componente personalizado:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- src/app/components/layout/layout.component.html -->
|
||||||
|
<div class="page-content">
|
||||||
|
<app-route-animations></app-route-animations>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Animaciones Disponibles
|
||||||
|
|
||||||
|
Las animaciones que se aplican aleatoriamente incluyen:
|
||||||
|
- fadeIn
|
||||||
|
- fadeInDown
|
||||||
|
- fadeInUp
|
||||||
|
- slideInLeft
|
||||||
|
- slideInRight
|
||||||
|
- zoomIn
|
||||||
|
|
||||||
|
## Personalización
|
||||||
|
|
||||||
|
Para modificar las animaciones disponibles, edita el array `animations` en el `RouteAnimationsComponent`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
private animations: string[] = [
|
||||||
|
'animate__fadeIn',
|
||||||
|
'animate__fadeInDown',
|
||||||
|
// Añade o elimina animaciones aquí
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
Todas las animaciones disponibles vienen de [Animate.css](https://animate.style/), asegúrate de que el nombre que elijas comience con `animate__` y exista en la biblioteca.
|
||||||
|
|
||||||
|
## Ajustes de Rendimiento
|
||||||
|
|
||||||
|
Si notas problemas de rendimiento:
|
||||||
|
|
||||||
|
1. Puedes reducir la duración de las animaciones modificando:
|
||||||
|
```css
|
||||||
|
.animate__animated {
|
||||||
|
animation-duration: 0.6s; /* Ajusta a un valor menor */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Limita las animaciones a solo las más simples (como fade) en lugar de las más complejas (como bounce o flip).
|
||||||
|
|
||||||
|
## Depuración
|
||||||
|
|
||||||
|
Si las animaciones no funcionan:
|
||||||
|
|
||||||
|
1. Verifica que `animate.css` esté correctamente importado en tu `angular.json`
|
||||||
|
2. Asegúrate de que el componente `RouteAnimationsComponent` esté correctamente importado en el layout
|
||||||
|
3. Comprueba que la estrategia de reuso de rutas esté registrada en `app.config.ts`
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||||
import { provideRouter } from '@angular/router';
|
import { provideRouter, RouteReuseStrategy } from '@angular/router';
|
||||||
import { provideHttpClient, withFetch, withInterceptors } from '@angular/common/http';
|
import { provideHttpClient, withFetch, withInterceptors } from '@angular/common/http';
|
||||||
|
|
||||||
import { routes } from './app.routes';
|
import { routes } from './app.routes';
|
||||||
@ -7,6 +7,7 @@ import { provideAnimations } from '@angular/platform-browser/animations';
|
|||||||
import { providePrimeNG } from 'primeng/config';
|
import { providePrimeNG } from 'primeng/config';
|
||||||
import Aura from '@primeng/themes/aura';
|
import Aura from '@primeng/themes/aura';
|
||||||
import { authInterceptor } from './interceptors/auth.interceptor';
|
import { authInterceptor } from './interceptors/auth.interceptor';
|
||||||
|
import { CustomRouteReuseStrategy } from './utils/custom-route-reuse-strategy';
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [
|
providers: [
|
||||||
@ -21,6 +22,12 @@ export const appConfig: ApplicationConfig = {
|
|||||||
darkModeSelector: false || 'none'
|
darkModeSelector: false || 'none'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
// Añadir estrategia de reuso de rutas personalizada para forzar
|
||||||
|
// recreación de componentes en cada navegación
|
||||||
|
{
|
||||||
|
provide: RouteReuseStrategy,
|
||||||
|
useClass: CustomRouteReuseStrategy
|
||||||
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,9 +12,9 @@
|
|||||||
<!-- Top navbar -->
|
<!-- Top navbar -->
|
||||||
<app-navbar (sidebarToggle)="toggleSidebar()"></app-navbar>
|
<app-navbar (sidebarToggle)="toggleSidebar()"></app-navbar>
|
||||||
|
|
||||||
<!-- Page content -->
|
<!-- Page content with animations -->
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
<router-outlet></router-outlet>
|
<app-route-animations></app-route-animations>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
import { NavbarComponent } from '../navbar/navbar.component';
|
import { NavbarComponent } from '../navbar/navbar.component';
|
||||||
import { SidebarComponent } from '../sidebar/sidebar.component';
|
import { SidebarComponent } from '../sidebar/sidebar.component';
|
||||||
import { FooterComponent } from "../footer/footer.component";
|
import { FooterComponent } from "../footer/footer.component";
|
||||||
|
import { RouteAnimationsComponent } from '../route-animations/route-animations.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-layout',
|
selector: 'app-layout',
|
||||||
@ -12,8 +13,9 @@ import { FooterComponent } from "../footer/footer.component";
|
|||||||
RouterModule,
|
RouterModule,
|
||||||
NavbarComponent,
|
NavbarComponent,
|
||||||
SidebarComponent,
|
SidebarComponent,
|
||||||
FooterComponent
|
FooterComponent,
|
||||||
],
|
RouteAnimationsComponent
|
||||||
|
],
|
||||||
templateUrl: './layout.component.html',
|
templateUrl: './layout.component.html',
|
||||||
styleUrl: './layout.component.scss',
|
styleUrl: './layout.component.scss',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
|
|||||||
@ -0,0 +1,59 @@
|
|||||||
|
import { Component, OnDestroy } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Router, RouterOutlet, NavigationEnd, Event } from '@angular/router';
|
||||||
|
import { Subscription, filter } from 'rxjs';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-route-animations',
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule, RouterOutlet],
|
||||||
|
template: `
|
||||||
|
<div class="content-container" [class]="animationClass">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
styles: [`
|
||||||
|
.content-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate__animated {
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
}
|
||||||
|
`]
|
||||||
|
})
|
||||||
|
export class RouteAnimationsComponent implements OnDestroy {
|
||||||
|
// Clase de animación actual
|
||||||
|
animationClass: string = 'animate__animated animate__fadeIn ';
|
||||||
|
|
||||||
|
// Animaciones disponibles
|
||||||
|
private animations: string[] = [
|
||||||
|
'animate__fadeIn'
|
||||||
|
];
|
||||||
|
|
||||||
|
private routerSub: Subscription;
|
||||||
|
|
||||||
|
constructor(private router: Router) {
|
||||||
|
// Suscribirse a los eventos de navegación
|
||||||
|
this.routerSub = this.router.events
|
||||||
|
.pipe(filter((event: Event) => event instanceof NavigationEnd))
|
||||||
|
.subscribe(() => {
|
||||||
|
// Resetear la animación primero
|
||||||
|
this.animationClass = '';
|
||||||
|
|
||||||
|
// Aplicar una nueva animación después de un breve retraso
|
||||||
|
setTimeout(() => {
|
||||||
|
const randomIndex = Math.floor(Math.random() * this.animations.length);
|
||||||
|
this.animationClass = `animate__animated ${this.animations[randomIndex]} `;
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
// Cancelar suscripción para evitar memory leaks
|
||||||
|
if (this.routerSub) {
|
||||||
|
this.routerSub.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/app/utils/custom-route-reuse-strategy.ts
Normal file
42
src/app/utils/custom-route-reuse-strategy.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estrategia personalizada que evita la reutilización de rutas
|
||||||
|
* para asegurar que los componentes se vuelvan a crear en cada navegación
|
||||||
|
*/
|
||||||
|
export class CustomRouteReuseStrategy implements RouteReuseStrategy {
|
||||||
|
/**
|
||||||
|
* No almacenar ninguna ruta al desactivarse
|
||||||
|
*/
|
||||||
|
shouldDetach(route: ActivatedRouteSnapshot): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No hay rutas almacenadas, así que esto nunca se llama
|
||||||
|
*/
|
||||||
|
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No recuperar rutas almacenadas
|
||||||
|
*/
|
||||||
|
shouldAttach(route: ActivatedRouteSnapshot): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No hay rutas almacenadas, así que esto nunca se llama
|
||||||
|
*/
|
||||||
|
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No reutilizar rutas para forzar la recreación de componentes
|
||||||
|
*/
|
||||||
|
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
|
||||||
|
// Solo reutilizar si es la misma ruta exactamente (evita problemas con rutas anidadas)
|
||||||
|
return future.routeConfig === curr.routeConfig &&
|
||||||
|
JSON.stringify(future.params) === JSON.stringify(curr.params);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user