Skip to content

Latest commit

 

History

History
85 lines (68 loc) · 2.84 KB

File metadata and controls

85 lines (68 loc) · 2.84 KB
import { Component, ElementRef, ViewChild, OnInit } from '@angular/core';
import { IonHeader, IonToolbar, IonTitle, IonContent, IonButton, IonModal, IonLabel } from '@ionic/angular/standalone';
import type { ModalDragEventDetail } from '@ionic/angular/standalone';

@Component({
  selector: 'app-example',
  templateUrl: 'example.component.html',
  standalone: true,
  imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonButton, IonModal, IonLabel],
})
export class ExampleComponent implements OnInit {
  @ViewChild('modal', { static: true }) modal!: IonModal;
  @ViewChild('appPage', { static: true }) appPage!: ElementRef<HTMLDivElement>;

  presentingElement: HTMLElement | undefined;

  private readonly DARKEST_PERCENT = 50;
  private readonly BRIGHTNESS_RANGE = 100 - this.DARKEST_PERCENT;

  ngOnInit() {
    this.presentingElement = this.appPage.nativeElement;
  }

  onModalWillPresent() {
    const appEl = this.appPage.nativeElement;

    appEl.style.transition = 'filter 0.4s ease';
    // Set to max darkness immediately
    appEl.style.setProperty('filter', `brightness(${this.DARKEST_PERCENT}%)`, 'important');
  }

  onDragStart() {
    const appEl = this.appPage.nativeElement;

    // Ensure transitions are off during the active drag
    appEl.style.transition = 'none';
  }

  onDragMove(event: CustomEvent<ModalDragEventDetail>) {
    // `progress` is a value from 1 (top) to 0 (bottom)
    const { progress } = event.detail;

    const appEl = this.appPage.nativeElement;
    /**
     * Calculate the current brightness based on how far the user has
     * dragged.
     *
     * When dragging up, the background should become darker,
     * and when dragging down, it should become lighter.
     */
    const brightnessValue = 100 - progress * this.BRIGHTNESS_RANGE;

    // Update the brightness in real-time as the user drags
    appEl.style.setProperty('filter', `brightness(${brightnessValue}%)`, 'important');
  }

  onDragEnd(event: CustomEvent<ModalDragEventDetail>) {
    // `progress` is a value from 1 (top) to 0 (bottom)
    const { progress } = event.detail;

    const appEl = this.appPage.nativeElement;
    /**
     * Snap the background brightness based on the user's drag intent.
     * Progress > 0.4 implies an intent to open (snap dark),
     * while < 0.4 implies a dismissal (snap bright).
     */
    const brightnessValue = progress > 0.4 ? this.DARKEST_PERCENT : 100;

    // Reset to max darkness on snap-back for a nice visual effect
    appEl.style.setProperty('filter', `brightness(${brightnessValue}%)`, 'important');

    // Re-enable transition for a smooth snap-back
    appEl.style.transition = 'filter 0.4s ease';
  }

  onModalWillDismiss() {
    const appEl = this.appPage.nativeElement;

    // Clean up styles when the modal is dismissed
    appEl.style.removeProperty('filter');
    appEl.style.removeProperty('transition');
  }
}