import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; import { cubicOut } from "svelte/easing"; import type { TransitionConfig } from "svelte/transition"; import { get } from "svelte/store"; import { map } from "./stores"; import { base } from "$app/paths"; import { browser } from "$app/environment"; import { languages } from "$lib/languages"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } type FlyAndScaleParams = { y?: number; x?: number; start?: number; duration?: number; }; export const flyAndScale = ( node: Element, params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 } ): TransitionConfig => { const style = getComputedStyle(node); const transform = style.transform === "none" ? "" : style.transform; const scaleConversion = ( valueA: number, scaleA: [number, number], scaleB: [number, number] ) => { const [minA, maxA] = scaleA; const [minB, maxB] = scaleB; const percentage = (valueA - minA) / (maxA - minA); const valueB = percentage * (maxB - minB) + minB; return valueB; }; const styleToString = ( style: Record ): string => { return Object.keys(style).reduce((str, key) => { if (style[key] === undefined) return str; return str + `${key}:${style[key]};`; }, ""); }; return { duration: params.duration ?? 200, delay: 0, css: (t) => { const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]); const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]); const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]); return styleToString({ transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`, opacity: t }); }, easing: cubicOut }; }; let previousCursors: string[] = []; export function setCursor(cursor: string) { let m = get(map); if (m) { previousCursors.push(m.getCanvas().style.cursor); m.getCanvas().style.cursor = cursor; } } export function resetCursor() { let m = get(map); if (m) { m.getCanvas().style.cursor = previousCursors.pop() ?? ''; } } export function setPointerCursor() { setCursor('pointer'); } export function setGrabbingCursor() { setCursor('grabbing'); } export function setCrosshairCursor() { setCursor('crosshair'); } export function getURLForLanguage(lang: string | null | undefined, path?: string): string { let newPath = path ?? (browser ? window.location.pathname : ''); let languageInPath = newPath.split('/')[1]; if (!languages.hasOwnProperty(languageInPath)) { languageInPath = 'en'; } if (languageInPath === 'en') { if (lang === 'en') { return `${base}${newPath}`; } else { return `${base}/${lang}${newPath}`; } } else { if (lang === 'en') { newPath = newPath.replace(`/${languageInPath}`, ''); return newPath === '' ? `${base}/` : `${base}${newPath}`; } else { newPath = newPath.replace(`/${languageInPath}`, `/${lang}`); return `${base}${newPath}`; } } }