mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 17:42:15 +08:00
fix(modal): sheet animation works correctly if breakpoints value does not include 1 (#23927)
This commit is contained in:
@ -26,15 +26,14 @@ export const createSheetEnterAnimation = (opts: ModalAnimationOptions) => {
|
||||
}
|
||||
|
||||
export const createSheetLeaveAnimation = (opts: ModalAnimationOptions) => {
|
||||
const { currentBreakpoint, backdropBreakpoint, sortedBreakpoints } = opts;
|
||||
const { currentBreakpoint, backdropBreakpoint } = opts;
|
||||
|
||||
/**
|
||||
* Backdrop does not always fade in from 0 to 1 if backdropBreakpoint
|
||||
* is defined, so we need to account for that offset by figuring out
|
||||
* what the current backdrop value should be.
|
||||
*/
|
||||
const maxBreakpoint = sortedBreakpoints![sortedBreakpoints.length - 1];
|
||||
const backdropValue = `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(currentBreakpoint!, maxBreakpoint, backdropBreakpoint!)})`;
|
||||
const backdropValue = `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(currentBreakpoint!, backdropBreakpoint!)})`;
|
||||
const defaultBackdrop = [
|
||||
{ offset: 0, opacity: backdropValue },
|
||||
{ offset: 1, opacity: 0 }
|
||||
|
@ -130,8 +130,8 @@ export const createSheetGesture = (
|
||||
]);
|
||||
|
||||
backdropAnimation.keyframes([
|
||||
{ offset: 0, opacity: `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(1 - offset, maxBreakpoint, backdropBreakpoint)})` },
|
||||
{ offset: 1, opacity: `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(closest, maxBreakpoint, backdropBreakpoint)})` }
|
||||
{ offset: 0, opacity: `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(1 - offset, backdropBreakpoint)})` },
|
||||
{ offset: 1, opacity: `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(closest, backdropBreakpoint)})` }
|
||||
]);
|
||||
|
||||
animation.progressStep(0);
|
||||
|
@ -28,5 +28,4 @@ export interface ModalAnimationOptions {
|
||||
presentingEl?: HTMLElement;
|
||||
currentBreakpoint?: number;
|
||||
backdropBreakpoint?: number;
|
||||
sortedBreakpoints: number[];
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
private currentBreakpoint?: number;
|
||||
private wrapperEl?: HTMLElement;
|
||||
private backdropEl?: HTMLIonBackdropElement;
|
||||
private sortedBreakpoints: number[] = [];
|
||||
|
||||
private inline = false;
|
||||
private workingDelegate?: FrameworkDelegate;
|
||||
@ -421,7 +420,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
|
||||
ani.progressStart(true, 1);
|
||||
|
||||
const sortedBreakpoints = this.sortedBreakpoints = (this.breakpoints?.sort((a, b) => a - b)) || [];
|
||||
const sortedBreakpoints = (this.breakpoints?.sort((a, b) => a - b)) || [];
|
||||
|
||||
this.gesture = createSheetGesture(
|
||||
this.el,
|
||||
@ -481,7 +480,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
|
||||
const enteringAnimation = activeAnimations.get(this) || [];
|
||||
|
||||
this.currentTransition = dismiss(this, data, role, 'modalLeave', iosLeaveAnimation, mdLeaveAnimation, { presentingEl: this.presentingElement, currentBreakpoint: this.currentBreakpoint || this.initialBreakpoint, sortedBreakpoints: this.sortedBreakpoints, backdropBreakpoint: this.backdropBreakpoint });
|
||||
this.currentTransition = dismiss(this, data, role, 'modalLeave', iosLeaveAnimation, mdLeaveAnimation, { presentingEl: this.presentingElement, currentBreakpoint: this.currentBreakpoint || this.initialBreakpoint, backdropBreakpoint: this.backdropBreakpoint });
|
||||
|
||||
const dismissed = await this.currentTransition;
|
||||
|
||||
|
@ -87,6 +87,7 @@
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button id="sheet-modal" onclick="presentModal()">Present Sheet Modal</ion-button>
|
||||
<ion-button id="custom-breakpoint-modal" onclick="presentModal({ initialBreakpoint: 0.5, breakpoints: [0, 0.5, 1] })">Present Sheet Modal (Custom Breakpoints)</ion-button>
|
||||
<ion-button id="custom-breakpoint-modal" onclick="presentModal({ initialBreakpoint: 0.5, breakpoints: [0, 0.5, 0.75] })">Present Sheet Modal (Max breakpoint is not 1)</ion-button>
|
||||
<ion-button id="custom-backdrop-modal" onclick="presentModal({ backdropBreakpoint: 0.5 })">Present Sheet Modal (Custom Backdrop Breakpoint)</ion-button>
|
||||
<ion-button id="custom-height-modal" onclick="presentModal({ cssClass: 'custom-height' })">Present Sheet Modal (Custom Height)</ion-button>
|
||||
<ion-button id="custom-handle-modal" onclick="presentModal({ cssClass: 'custom-handle' })">Present Sheet Modal (Custom Handle)</ion-button>
|
||||
|
@ -6,7 +6,7 @@
|
||||
* not begin to fade in until after
|
||||
* the 0 breakpoint.
|
||||
*/
|
||||
export const getBackdropValueForSheet = (x: number, maxBreakpoint: number, backdropBreakpoint: number) => {
|
||||
export const getBackdropValueForSheet = (x: number, backdropBreakpoint: number) => {
|
||||
|
||||
/**
|
||||
* We will use these points:
|
||||
@ -15,13 +15,17 @@ export const getBackdropValueForSheet = (x: number, maxBreakpoint: number, backd
|
||||
* We know that at the beginning breakpoint,
|
||||
* the backdrop will be hidden. We also
|
||||
* know that at the maxBreakpoint, the backdrop
|
||||
* must be fully visible.
|
||||
* must be fully visible. maxBreakpoint should
|
||||
* always be 1 even if the maximum value
|
||||
* of the breakpoints array is not 1 since
|
||||
* the animation runs from a progress of 0
|
||||
* to a progress of 1.
|
||||
* m = (y2 - y1) / (x2 - x1)
|
||||
*
|
||||
* This is simplified from:
|
||||
* m = (1 - 0) / (maxBreakpoint - backdropBreakpoint)
|
||||
*/
|
||||
const slope = 1 / (maxBreakpoint - backdropBreakpoint);
|
||||
const slope = 1 / (1 - backdropBreakpoint);
|
||||
|
||||
/**
|
||||
* From here, compute b which is
|
||||
|
Reference in New Issue
Block a user