chore(mobile): optimize swipe dialog animation timeline (#9028)

This commit is contained in:
CatsJuice
2024-12-05 06:31:28 +00:00
parent 7dad9fe816
commit 06764bbb83

View File

@@ -29,21 +29,21 @@ const tick = (
overlay: HTMLDivElement, overlay: HTMLDivElement,
dialog: HTMLDivElement, dialog: HTMLDivElement,
prev: HTMLElement | null, prev: HTMLElement | null,
deltaX: number deltaX: number,
fullWidth: number
) => { ) => {
const limitedDeltaX = Math.min(overlay.clientWidth, Math.max(0, deltaX)); const limitedDeltaX = Math.min(fullWidth, Math.max(0, deltaX));
const percent = limitedDeltaX / overlay.clientWidth; const percent = limitedDeltaX / fullWidth;
const opacity = const opacity =
overlayOpacityRange[1] - overlayOpacityRange[1] -
(overlayOpacityRange[1] - overlayOpacityRange[0]) * percent; (overlayOpacityRange[1] - overlayOpacityRange[0]) * percent;
overlay.style.background = `rgba(0, 0, 0, ${opacity})`; overlay.style.background = `rgba(0, 0, 0, ${opacity})`;
dialog.style.transform = `translateX(${limitedDeltaX}px)`; dialog.style.transform = `translate3d(${limitedDeltaX}px, 0, 0)`;
const prevEl = prev ?? document.querySelector('#app'); if (prev) {
if (prevEl) {
const range = [-80, 0]; const range = [-80, 0];
const offset = range[0] + (range[1] - range[0]) * percent; const offset = range[0] + (range[1] - range[0]) * percent;
prevEl.style.transform = `translateX(${offset}px)`; prev.style.transform = `translate3d(${offset}px, 0, 0)`;
} }
}; };
const reset = ( const reset = (
@@ -62,16 +62,17 @@ const reset = (
const getAnimeProxy = ( const getAnimeProxy = (
overlay: HTMLDivElement, overlay: HTMLDivElement,
dialog: HTMLDivElement, dialog: HTMLDivElement,
prev: HTMLElement | null, maybePrev: HTMLElement | null,
init: number init: number
) => { ) => {
const prev = maybePrev ?? document.querySelector('#app');
return new Proxy( return new Proxy(
{ deltaX: init }, { deltaX: init },
{ {
set(target, key, value) { set(target, key, value) {
if (key === 'deltaX') { if (key === 'deltaX') {
target.deltaX = value; target.deltaX = value;
tick(overlay, dialog, prev, value); tick(overlay, dialog, prev, value, overlay.clientWidth);
return true; return true;
} }
return false; return false;
@@ -95,8 +96,8 @@ const cancel = (
Math.min(overlay.clientWidth, Math.max(0, deltaX)) Math.min(overlay.clientWidth, Math.max(0, deltaX))
), ),
deltaX: 0, deltaX: 0,
easing: 'easeInOutSine', easing: 'cubicBezier(.25,.36,.24,.97)',
duration: 230, duration: 320,
complete: () => { complete: () => {
complete?.(); complete?.();
setTimeout(() => { setTimeout(() => {
@@ -121,8 +122,8 @@ const close = (
Math.min(overlay.clientWidth, Math.max(0, deltaX)) Math.min(overlay.clientWidth, Math.max(0, deltaX))
), ),
deltaX: overlay.clientWidth, deltaX: overlay.clientWidth,
easing: 'easeInOutSine', easing: 'cubicBezier(.25,.36,.24,.97)',
duration: 230, duration: 320,
complete: () => { complete: () => {
complete?.(); complete?.();
setTimeout(() => { setTimeout(() => {
@@ -178,7 +179,8 @@ export const SwipeDialog = ({
preventScroll: true, preventScroll: true,
onSwipeStart: () => {}, onSwipeStart: () => {},
onSwipe({ deltaX }) { onSwipe({ deltaX }) {
tick(overlay, dialog, prev, deltaX); const prevOrAppRoot = prev ?? document.querySelector('#app');
tick(overlay, dialog, prevOrAppRoot, deltaX, overlay.clientWidth);
}, },
onSwipeEnd: ({ deltaX }) => { onSwipeEnd: ({ deltaX }) => {
const shouldClose = deltaX > overlay.clientWidth * 0.2; const shouldClose = deltaX > overlay.clientWidth * 0.2;