feat(springySliderFade): add custom transition function for slide+fade
This commit is contained in:
@@ -20,3 +20,5 @@ export {
|
|||||||
} from './helpers';
|
} from './helpers';
|
||||||
|
|
||||||
export { splitArray } from './utils';
|
export { splitArray } from './utils';
|
||||||
|
|
||||||
|
export { springySlideFade } from './transitions';
|
||||||
|
|||||||
1
src/shared/lib/transitions/index.ts
Normal file
1
src/shared/lib/transitions/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { springySlideFade } from './springySlideFade/springySlideFade';
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
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;
|
||||||
|
`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user