1+ import { type ClassValue , clsx } from "clsx" ;
2+ import { twMerge } from "tailwind-merge" ;
3+ import { cubicOut } from "svelte/easing" ;
4+ import type { TransitionConfig } from "svelte/transition" ;
5+
6+ export function cn ( ...inputs : ClassValue [ ] ) {
7+ return twMerge ( clsx ( inputs ) ) ;
8+ }
9+
10+ type FlyAndScaleParams = {
11+ y ?: number ;
12+ x ?: number ;
13+ start ?: number ;
14+ duration ?: number ;
15+ } ;
16+
17+ export const flyAndScale = (
18+ node : Element ,
19+ params : FlyAndScaleParams = { y : - 8 , x : 0 , start : 0.95 , duration : 150 }
20+ ) : TransitionConfig => {
21+ const style = getComputedStyle ( node ) ;
22+ const transform = style . transform === "none" ? "" : style . transform ;
23+
24+ const scaleConversion = (
25+ valueA : number ,
26+ scaleA : [ number , number ] ,
27+ scaleB : [ number , number ]
28+ ) => {
29+ const [ minA , maxA ] = scaleA ;
30+ const [ minB , maxB ] = scaleB ;
31+
32+ const percentage = ( valueA - minA ) / ( maxA - minA ) ;
33+ const valueB = percentage * ( maxB - minB ) + minB ;
34+
35+ return valueB ;
36+ } ;
37+
38+ const styleToString = (
39+ style : Record < string , number | string | undefined >
40+ ) : string => {
41+ return Object . keys ( style ) . reduce ( ( str , key ) => {
42+ if ( style [ key ] === undefined ) return str ;
43+ return str + `${ key } :${ style [ key ] } ;` ;
44+ } , "" ) ;
45+ } ;
46+
47+ return {
48+ duration : params . duration ?? 200 ,
49+ delay : 0 ,
50+ css : ( t ) => {
51+ const y = scaleConversion ( t , [ 0 , 1 ] , [ params . y ?? 5 , 0 ] ) ;
52+ const x = scaleConversion ( t , [ 0 , 1 ] , [ params . x ?? 0 , 0 ] ) ;
53+ const scale = scaleConversion ( t , [ 0 , 1 ] , [ params . start ?? 0.95 , 1 ] ) ;
54+
55+ return styleToString ( {
56+ transform : `${ transform } translate3d(${ x } px, ${ y } px, 0) scale(${ scale } )` ,
57+ opacity : t
58+ } ) ;
59+ } ,
60+ easing : cubicOut
61+ } ;
62+ } ;
0 commit comments