Search
Close this search box.
,

Ionic Uso de ion-modal e ion-backdrop perzonalizado

En este tutorial, aprenderemos a usar el componente ion-modal en Ionic, junto con su complemento ion-backdrop para crear modales que se sobreponen a la interfaz principal, de forma estilizada y personalizada.

Contenido del Tutorial

  1. Introducción a ion-modal y ion-backdrop
  2. Configuración básica de un modal
  3. Personalización del modal con CSS (agregar degradado)
  4. Uso de ion-backdrop y cómo aplicarlo para un efecto visual
  5. Cómo abrir y cerrar el modal
  6. Interacción del usuario: botón de cierre y fondo reactivo
  7. Ejemplo completo en código

Paso 1: Comprender los Componentes ion-modal e ion-backdrop

  • ion-modal: Un modal es una ventana emergente que se muestra encima del contenido principal de la app. Ionic ofrece ion-modal como una forma fácil de implementar estas ventanas flotantes. Es ideal para mostrar información adicional sin cambiar de página, o para realizar acciones específicas sin salir de la vista actual.
  • ion-backdrop: Este componente crea un fondo oscuro detrás del modal o cualquier otro elemento superpuesto. Ayuda a desviar la atención del usuario hacia el modal, ya que el fondo se vuelve oscuro o difuminado. ion-backdrop también puede configurarse para cerrar el modal si se hace clic fuera de él.

Paso 2: Crear una Aplicación Básica en Ionic

Si aún no tienes una aplicación, comienza creando una nueva aplicación en Ionic. Abre tu terminal y escribe:

ionic start ModalExampleApp blank --type=angular
cd ModalExampleApp

Esto creará una nueva aplicación llamada «ModalExampleApp» con una plantilla en blanco.


Paso 3: Configurar ion-modal en la Página

  1. Dirígete a src/app/home/home.page.html y agrega el código para el modal.
  2. Coloca un botón en la página principal (home.page.html) que abrirá el modal. Agrega también el modal en sí:
   <ion-header>
     <ion-toolbar>
       <ion-title>Modal Example</ion-title>
     </ion-toolbar>
   </ion-header>

   <ion-content class="ion-padding">
     <!-- Botón que abrirá el modal -->
     <ion-button expand="full" (click)="openModal()">Abrir Modal</ion-button>

     <!-- Componente Modal -->
     <ion-modal #myModal>
       <ng-template>
         <ion-header>
           <ion-toolbar color="primary">
             <ion-title>Mi Modal</ion-title>
             <ion-buttons slot="end">
               <ion-button (click)="closeModal()">Cerrar</ion-button>
             </ion-buttons>
           </ion-toolbar>
         </ion-header>
         <ion-content>
           <p>Este es el contenido del modal.</p>
         </ion-content>
       </ng-template>
     </ion-modal>
   </ion-content>

Explicación del Código:

  • ion-button (click)="openModal()": Este botón dispara el método openModal() en el archivo de TypeScript para abrir el modal.
  • ion-modal: Aquí es donde creamos el componente ion-modal. El contenido del modal está en una plantilla <ng-template>, que se renderizará dentro del modal.
  • closeModal(): En el encabezado del modal, incluimos un botón para cerrarlo, que llama al método closeModal().

Paso 4: Agregar Funciones para Abrir y Cerrar el Modal en TypeScript

  1. Abre home.page.ts y crea los métodos openModal() y closeModal() para manejar la apertura y cierre del modal.
   import { Component } from '@angular/core';
   import { ModalController } from '@ionic/angular';

   @Component({
     selector: 'app-home',
     templateUrl: 'home.page.html',
     styleUrls: ['home.page.scss'],
   })
   export class HomePage {
     constructor(private modalController: ModalController) {}

     async openModal() {
       const modal = await this.modalController.create({
         component: ModalContentComponent,
         cssClass: 'my-custom-modal-css'
       });
       return await modal.present();
     }

     async closeModal() {
       await this.modalController.dismiss();
     }
   }

Explicación del Código:

  • ModalController: Es un servicio de Ionic que controla la apertura y cierre de los modales.
  • create(): Este método crea el modal y permite configurarlo, como asociarlo a una clase CSS personalizada.
  • dismiss(): Cierra el modal.

Nota: Necesitamos crear el componente ModalContentComponent para que funcione correctamente. Vamos a configurarlo en el siguiente paso.


Paso 5: Crear el Componente del Contenido del Modal

  1. Genera un nuevo componente para el contenido del modal. En la terminal, escribe:
   ionic generate component ModalContent

Esto creará un nuevo componente llamado ModalContent en src/app/modal-content/.

  1. Edita el archivo modal-content.component.html con el contenido que quieras mostrar en el modal:
   <ion-header>
     <ion-toolbar color="secondary">
       <ion-title>Contenido del Modal</ion-title>
       <ion-buttons slot="end">
         <ion-button (click)="dismiss()">Cerrar</ion-button>
       </ion-buttons>
     </ion-toolbar>
   </ion-header>

   <ion-content class="ion-padding">
     <h2>¡Bienvenido al Modal!</h2>
     <p>Este es un contenido de ejemplo dentro del modal.</p>
   </ion-content>
  1. Agrega el método dismiss() en modal-content.component.ts para cerrar el modal:
   import { Component } from '@angular/core';
   import { ModalController } from '@ionic/angular';

   @Component({
     selector: 'app-modal-content',
     templateUrl: './modal-content.component.html',
     styleUrls: ['./modal-content.component.scss'],
   })
   export class ModalContentComponent {
     constructor(private modalController: ModalController) {}

     dismiss() {
       this.modalController.dismiss();
     }
   }

Explicación del Código:

  • dismiss(): Llama a ModalController.dismiss() para cerrar el modal. Así, el usuario puede cerrar el modal usando el botón «Cerrar» en el encabezado.

Paso 6: Personalizar el Estilo del Modal con Degradados en CSS

  1. Abre global.scss o modal-content.component.scss para aplicar estilos personalizados, como un fondo degradado, al modal.
  2. Agrega el siguiente código para un degradado de fondo en el modal:
   .my-custom-modal-css {
     --background: linear-gradient(135deg, #4e54c8, #8f94fb);
     color: white;
     border-radius: 12px;
     margin: 16px;
   }

   .my-custom-modal-css .ion-header {
     background-color: rgba(0, 0, 0, 0.1);
   }

   .my-custom-modal-css .ion-content {
     padding: 20px;
   }
  1. Explicación del Código:
  • --background: Aplica un fondo degradado a todo el modal.
  • border-radius y margin: Hacen que el modal tenga bordes redondeados y un margen para que no ocupe todo el ancho de la pantalla.

A continuacion, vamos a añadir algunas animaciones para que el modal tenga un toque más dinámico y atractivo al abrirse y cerrarse. Ionic permite configurar animaciones personalizadas en ion-modal mediante el uso de enterAnimation y leaveAnimation. Para eso veremos cómo aplicar animaciones de entrada y salida, y luego personalizaremos estas animaciones.


Animaciones Personalizadas para el ion-modal

Las animaciones ayudan a hacer que la experiencia de usuario sea más agradable y visualmente atractiva. Aquí explicaremos cómo añadir animaciones de entrada y salida a un ion-modal, desde opciones de movimiento hasta efectos de desvanecimiento.

1. Crear Funciones de Animación Personalizadas

Para definir las animaciones de entrada y salida, primero crearemos funciones personalizadas en el archivo home.page.ts.

A continuación, implementaremos animaciones para:

  • Deslizar el modal desde abajo (entrada)
  • Deslizar el modal hacia abajo (salida)

Veamos cómo hacerlo.

Paso 1: Definir la Animación de Entrada

Agrega el siguiente código en home.page.ts para configurar una animación de entrada que desliza el modal desde la parte inferior de la pantalla:

import { AnimationController, ModalController } from '@ionic/angular';
import { Component } from '@angular/core';
import { ModalContentComponent } from '../modal-content/modal-content.component';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  constructor(
    private modalController: ModalController,
    private animationCtrl: AnimationController
  ) {}

  async openModal() {
    const modal = await this.modalController.create({
      component: ModalContentComponent,
      cssClass: 'my-custom-modal-css',
      enterAnimation: this.enterAnimation,
      leaveAnimation: this.leaveAnimation,
    });
    return await modal.present();
  }

  enterAnimation(baseEl: HTMLElement) {
    const backdropAnimation = this.animationCtrl
      .create()
      .addElement(baseEl.querySelector('ion-backdrop')!)
      .fromTo('opacity', '0.01', 'var(--backdrop-opacity)');

    const wrapperAnimation = this.animationCtrl
      .create()
      .addElement(baseEl.querySelector('.modal-wrapper')!)
      .keyframes([
        { offset: 0, opacity: '0', transform: 'translateY(100%)' },
        { offset: 1, opacity: '1', transform: 'translateY(0)' },
      ]);

    return this.animationCtrl
      .create()
      .addElement(baseEl)
      .easing('ease-out')
      .duration(500)
      .addAnimation([backdropAnimation, wrapperAnimation]);
  }

  leaveAnimation(baseEl: HTMLElement) {
    const backdropAnimation = this.animationCtrl
      .create()
      .addElement(baseEl.querySelector('ion-backdrop')!)
      .fromTo('opacity', 'var(--backdrop-opacity)', '0');

    const wrapperAnimation = this.animationCtrl
      .create()
      .addElement(baseEl.querySelector('.modal-wrapper')!)
      .keyframes([
        { offset: 0, opacity: '1', transform: 'translateY(0)' },
        { offset: 1, opacity: '0', transform: 'translateY(100%)' },
      ]);

    return this.animationCtrl
      .create()
      .addElement(baseEl)
      .easing('ease-in')
      .duration(500)
      .addAnimation([backdropAnimation, wrapperAnimation]);
  }

  async closeModal() {
    await this.modalController.dismiss();
  }
}

Explicación del Código

  • enterAnimation: Define la animación de entrada. Desliza el modal desde la parte inferior de la pantalla con una duración de 500 ms.
  • leaveAnimation: Define la animación de salida. Desliza el modal hacia la parte inferior, aplicando el mismo tiempo de duración.
  • AnimationController: Es el controlador que maneja las animaciones en Ionic y permite combinar múltiples efectos, como el cambio de opacidad y el desplazamiento vertical.

2. Aplicar Animaciones de Desvanecimiento

Otra opción es agregar una animación de desvanecimiento, donde el modal aparecerá y desaparecerá suavemente en la pantalla.

Para ello, modifica las funciones de animación en home.page.ts de la siguiente manera:

enterAnimation(baseEl: HTMLElement) {
  return this.animationCtrl
    .create()
    .addElement(baseEl.querySelector('.modal-wrapper')!)
    .fromTo('opacity', '0', '1')
    .duration(400)
    .easing('ease-in');
}

leaveAnimation(baseEl: HTMLElement) {
  return this.animationCtrl
    .create()
    .addElement(baseEl.querySelector('.modal-wrapper')!)
    .fromTo('opacity', '1', '0')
    .duration(400)
    .easing('ease-out');
}

Esta configuración crea una transición suave de opacidad, con una duración de 400 ms tanto para la entrada como para la salida.


3. Combinar Animaciones de Desplazamiento y Desvanecimiento

Para un efecto más complejo, puedes combinar ambas animaciones para que el modal se deslice y se desvanezca al mismo tiempo.

Actualiza el código de animación en home.page.ts de esta forma:

enterAnimation(baseEl: HTMLElement) {
  return this.animationCtrl
    .create()
    .addElement(baseEl.querySelector('.modal-wrapper')!)
    .keyframes([
      { offset: 0, opacity: '0', transform: 'translateY(100%)' },
      { offset: 1, opacity: '1', transform: 'translateY(0)' },
    ])
    .duration(500)
    .easing('ease-out');
}

leaveAnimation(baseEl: HTMLElement) {
  return this.animationCtrl
    .create()
    .addElement(baseEl.querySelector('.modal-wrapper')!)
    .keyframes([
      { offset: 0, opacity: '1', transform: 'translateY(0)' },
      { offset: 1, opacity: '0', transform: 'translateY(100%)' },
    ])
    .duration(500)
    .easing('ease-in');
}

Explicación de las Keyframes

  • offset: Define el punto en el que ocurre la animación. 0 es el inicio y 1 es el final.
  • transform: translateY(100%): Hace que el modal comience fuera de la pantalla (hacia abajo) y luego se mueva hacia su posición inicial.
  • opacity: Comienza desde 0 (invisible) y va hacia 1 (visible), para un efecto de desvanecimiento.

4. Estilizar el ion-backdrop y Configurar su Interacción

Para mejorar el aspecto de ion-backdrop y hacerlo parte integral de la experiencia visual del modal, agrega estos estilos personalizados.

  1. Abre global.scss y añade estilos para que el fondo oscuro tenga un efecto de opacidad más sutil y agradable:
   ion-backdrop {
     --backdrop-opacity: 0.4;
   }

Este ajuste hace que el fondo oscuro detrás del modal sea un poco más claro, permitiendo que el contenido de la pantalla principal sea visible, pero sin distraer del modal.

  1. Permitir Cerrar el Modal al Tocar el Fondo En la configuración de openModal, podemos permitir que el usuario cierre el modal haciendo clic fuera de él:
   async openModal() {
     const modal = await this.modalController.create({
       component: ModalContentComponent,
       cssClass: 'my-custom-modal-css',
       enterAnimation: this.enterAnimation,
       leaveAnimation: this.leaveAnimation,
       backdropDismiss: true, // Habilita el cierre al tocar fuera del modal
     });
     return await modal.present();
   }
  • backdropDismiss: true: Configura el modal para cerrarse automáticamente si el usuario toca el ion-backdrop, lo cual es útil para mejorar la experiencia de usuario.

Ejemplo Completo del Código en home.page.ts

Aquí tienes el código completo con las animaciones de entrada y salida, el uso de backdropDismiss, y la personalización del fondo.

import { AnimationController, ModalController } from '@ionic/angular';
import { Component } from '@angular/core';
import { ModalContentComponent } from '../modal-content/modal-content.component';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  constructor(
    private modalController: ModalController,
    private animationCtrl: AnimationController
  ) {}

  async openModal() {
    const modal = await this.modalController.create({
      component: ModalContentComponent,
      cssClass: 'my-custom-modal-css',
      enterAnimation: this.enterAnimation,
      leaveAnimation: this.leaveAnimation,
      backdropDismiss: true,
    });
    return await modal.present();
  }

  enterAnimation(baseEl: HTMLElement) {
    return this.animationCtrl
      .create()
      .addElement(baseEl.querySelector('.modal-wrapper')!)
      .keyframes([
        { offset: 0, opacity: '0', transform: 'translate

Y(100%)' },
        { offset: 1, opacity: '1', transform: 'translateY(0)' },
      ])
      .duration(500)
      .easing('ease-out');
  }

  leaveAnimation(baseEl: HTMLElement) {
    return this.animationCtrl
      .create()
      .addElement(baseEl.querySelector('.modal-wrapper')!)
      .keyframes([
        { offset: 0, opacity: '1', transform: 'translateY(0)' },
        { offset: 1, opacity: '0', transform: 'translateY(100%)' },
      ])
      .duration(500)
      .easing('ease-in');
  }
}

¡Y eso es todo! Ahora tienes un modal con animaciones personalizadas de entrada y salida, junto con opciones de personalización para el fondo y el cierre mediante el fondo táctil.

Comparte:
Contactanos

Posts Populares

Scroll al inicio