import type { SlideParams, TransitionConfig, } from 'svelte/transition'; function elasticOut(t: number) { return Math.pow(2, -10 * t) * Math.sin((t - 0.075) * (2 * Math.PI) / 0.3) + 1; } function gentleSpring(t: number) { return 1 - Math.pow(1 - t, 3) * Math.cos(t * Math.PI * 2); } /** * Svelte slide transition function for custom slide+fade * @param node - The element to apply the transition to * @param params - Transition parameters * @returns Transition configuration */ export function springySlideFade( node: HTMLElement, params: SlideParams = {}, ): TransitionConfig { const { duration = 400 } = params; const height = node.scrollHeight; // Check if the browser is Firefox to work around specific rendering issues const isFirefox = navigator.userAgent.toLowerCase().includes('firefox'); return { duration, // We use 'tick' for the most precise control over the // coordination with the elements below. css: t => { // Use elastic easing const eased = gentleSpring(t); return ` height: ${eased * height}px; opacity: ${t}; transform: translateY(${(1 - t) * -10}px); transform-origin: top; overflow: hidden; contain: size layout style; will-change: max-height, opacity, transform; backface-visibility: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; ${ isFirefox ? ` perspective: 1000px; isolation: isolate; ` : '' } `; }, }; }